From patchwork Sun Aug 19 14:29:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Wunner X-Patchwork-Id: 959417 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41tlXJ3vG9z9s4s for ; Mon, 20 Aug 2018 04:17:20 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=wunner.de Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 41tlXJ2LpZzF2F4 for ; Mon, 20 Aug 2018 04:17:20 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=wunner.de X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=none (mailfrom) smtp.mailfrom=wunner.de (client-ip=176.9.242.54; helo=mailout3.hostsharing.net; envelope-from=lukas@wunner.de; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=wunner.de Received: from mailout3.hostsharing.net (mailout3.hostsharing.net [176.9.242.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 41tlV32jYJzF15Q for ; Mon, 20 Aug 2018 04:15:23 +1000 (AEST) Received: from h08.hostsharing.net (h08.hostsharing.net [83.223.95.28]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "*.hostsharing.net", Issuer "COMODO RSA Domain Validation Secure Server CA" (not verified)) by mailout3.hostsharing.net (Postfix) with ESMTPS id 43919101E6A89; Sun, 19 Aug 2018 16:36:05 +0200 (CEST) Received: from localhost (unknown [89.246.108.87]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by h08.hostsharing.net (Postfix) with ESMTPSA id BBCE7609B163; Sun, 19 Aug 2018 16:36:04 +0200 (CEST) X-Mailbox-Line: From 40b17d029c4fbf099535f989b1d6dd013f708a73 Mon Sep 17 00:00:00 2001 Message-Id: <40b17d029c4fbf099535f989b1d6dd013f708a73.1534686485.git.lukas@wunner.de> In-Reply-To: References: From: Lukas Wunner Date: Sun, 19 Aug 2018 16:29:00 +0200 Subject: [PATCH 6/9] PCI: hotplug: Constify hotplug_slot_ops To: Bjorn Helgaas , linux-pci@vger.kernel.org, Sinan Kaya , Mika Westerberg X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Scott Murray , linux-s390@vger.kernel.org, Greg Kroah-Hartman , acpi4asus-user@lists.sourceforge.net, "Rafael J. Wysocki" , Gavin Shan , platform-driver-x86@vger.kernel.org, linux-acpi@vger.kernel.org, Paul Mackerras , Sebastian Ott , Corentin Chary , Darren Hart , linuxppc-dev@lists.ozlabs.org, Andy Shevchenko , Gerald Schaefer , Len Brown Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" Hotplug drivers cannot declare their hotplug_slot_ops const, making them attractive targets for attackers, because upon registration of a hotplug slot, __pci_hp_initialize() writes to the "owner" and "mod_name" members in that struct. Fix by moving these members to struct hotplug_slot and constify every driver's hotplug_slot_ops except for pciehp. pciehp constructs its hotplug_slot_ops at runtime based on the PCIe port's capabilities, hence cannot declare them const. It can be converted to __write_rarely once that's mainlined: http://www.openwall.com/lists/kernel-hardening/2016/11/16/3 Signed-off-by: Lukas Wunner Cc: Rafael J. Wysocki Cc: Len Brown Cc: Scott Murray Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Michael Ellerman Cc: Gavin Shan Cc: Sebastian Ott Cc: Gerald Schaefer Cc: Corentin Chary Cc: Darren Hart Cc: Andy Shevchenko Reviewed-by: Rafael J. Wysocki Acked-by: Tyrel Datwyler --- drivers/pci/hotplug/acpiphp_core.c | 2 +- drivers/pci/hotplug/cpci_hotplug_core.c | 2 +- drivers/pci/hotplug/cpqphp_core.c | 2 +- drivers/pci/hotplug/ibmphp.h | 2 +- drivers/pci/hotplug/ibmphp_core.c | 2 +- drivers/pci/hotplug/pci_hotplug_core.c | 27 +++++++++++++------------ drivers/pci/hotplug/pnv_php.c | 2 +- drivers/pci/hotplug/rpaphp.h | 2 +- drivers/pci/hotplug/rpaphp_core.c | 2 +- drivers/pci/hotplug/s390_pci_hpc.c | 2 +- drivers/pci/hotplug/sgi_hotplug.c | 2 +- drivers/pci/hotplug/shpchp_core.c | 2 +- drivers/pci/pci.c | 4 ++-- drivers/pci/slot.c | 2 +- drivers/platform/x86/asus-wmi.c | 3 +-- drivers/platform/x86/eeepc-laptop.c | 3 +-- include/linux/pci_hotplug.h | 10 ++++----- 17 files changed, 35 insertions(+), 36 deletions(-) diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index ad32ffbc4b91..e883cef0f3bc 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c @@ -57,7 +57,7 @@ static int get_attention_status(struct hotplug_slot *slot, u8 *value); static int get_latch_status(struct hotplug_slot *slot, u8 *value); static int get_adapter_status(struct hotplug_slot *slot, u8 *value); -static struct hotplug_slot_ops acpi_hotplug_slot_ops = { +static const struct hotplug_slot_ops acpi_hotplug_slot_ops = { .enable_slot = enable_slot, .disable_slot = disable_slot, .set_attention_status = set_attention_status, diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c index 52a339baf06c..97c32e4c74c8 100644 --- a/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/drivers/pci/hotplug/cpci_hotplug_core.c @@ -57,7 +57,7 @@ static int get_attention_status(struct hotplug_slot *slot, u8 *value); static int get_adapter_status(struct hotplug_slot *slot, u8 *value); static int get_latch_status(struct hotplug_slot *slot, u8 *value); -static struct hotplug_slot_ops cpci_hotplug_slot_ops = { +static const struct hotplug_slot_ops cpci_hotplug_slot_ops = { .enable_slot = enable_slot, .disable_slot = disable_slot, .set_attention_status = set_attention_status, diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index 5a06636e910a..3409b62fceac 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c @@ -560,7 +560,7 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) return 0; } -static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = { +static const struct hotplug_slot_ops cpqphp_hotplug_slot_ops = { .set_attention_status = set_attention_status, .enable_slot = process_SI, .disable_slot = process_SS, diff --git a/drivers/pci/hotplug/ibmphp.h b/drivers/pci/hotplug/ibmphp.h index fddb78606c74..db387e10581e 100644 --- a/drivers/pci/hotplug/ibmphp.h +++ b/drivers/pci/hotplug/ibmphp.h @@ -740,7 +740,7 @@ int ibmphp_do_disable_slot(struct slot *slot_cur); int ibmphp_update_slot_info(struct slot *); /* This function is called from HPC, so we need it to not be be static */ int ibmphp_configure_card(struct pci_func *, u8); int ibmphp_unconfigure_card(struct slot **, int); -extern struct hotplug_slot_ops ibmphp_hotplug_slot_ops; +extern const struct hotplug_slot_ops ibmphp_hotplug_slot_ops; #endif //__IBMPHP_H diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index 4ea57e9019f1..b82fdc17040d 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c @@ -1259,7 +1259,7 @@ int ibmphp_do_disable_slot(struct slot *slot_cur) goto exit; } -struct hotplug_slot_ops ibmphp_hotplug_slot_ops = { +const struct hotplug_slot_ops ibmphp_hotplug_slot_ops = { .set_attention_status = set_attention_status, .enable_slot = enable_slot, .disable_slot = ibmphp_disable_slot, diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index 90fde5f106d8..ede2ed6f4ce0 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c @@ -49,15 +49,15 @@ static DEFINE_MUTEX(pci_hp_mutex); #define GET_STATUS(name, type) \ static int get_##name(struct hotplug_slot *slot, type *value) \ { \ - struct hotplug_slot_ops *ops = slot->ops; \ + const struct hotplug_slot_ops *ops = slot->ops; \ int retval = 0; \ - if (!try_module_get(ops->owner)) \ + if (!try_module_get(slot->owner)) \ return -ENODEV; \ if (ops->get_##name) \ retval = ops->get_##name(slot, value); \ else \ *value = slot->info->name; \ - module_put(ops->owner); \ + module_put(slot->owner); \ return retval; \ } @@ -90,7 +90,7 @@ static ssize_t power_write_file(struct pci_slot *pci_slot, const char *buf, power = (u8)(lpower & 0xff); dbg("power = %d\n", power); - if (!try_module_get(slot->ops->owner)) { + if (!try_module_get(slot->owner)) { retval = -ENODEV; goto exit; } @@ -109,7 +109,7 @@ static ssize_t power_write_file(struct pci_slot *pci_slot, const char *buf, err("Illegal value specified for power\n"); retval = -EINVAL; } - module_put(slot->ops->owner); + module_put(slot->owner); exit: if (retval) @@ -138,7 +138,8 @@ static ssize_t attention_read_file(struct pci_slot *pci_slot, char *buf) static ssize_t attention_write_file(struct pci_slot *pci_slot, const char *buf, size_t count) { - struct hotplug_slot_ops *ops = pci_slot->hotplug->ops; + struct hotplug_slot *slot = pci_slot->hotplug; + const struct hotplug_slot_ops *ops = slot->ops; unsigned long lattention; u8 attention; int retval = 0; @@ -147,13 +148,13 @@ static ssize_t attention_write_file(struct pci_slot *pci_slot, const char *buf, attention = (u8)(lattention & 0xff); dbg(" - attention = %d\n", attention); - if (!try_module_get(ops->owner)) { + if (!try_module_get(slot->owner)) { retval = -ENODEV; goto exit; } if (ops->set_attention_status) - retval = ops->set_attention_status(pci_slot->hotplug, attention); - module_put(ops->owner); + retval = ops->set_attention_status(slot, attention); + module_put(slot->owner); exit: if (retval) @@ -213,13 +214,13 @@ static ssize_t test_write_file(struct pci_slot *pci_slot, const char *buf, test = (u32)(ltest & 0xffffffff); dbg("test = %d\n", test); - if (!try_module_get(slot->ops->owner)) { + if (!try_module_get(slot->owner)) { retval = -ENODEV; goto exit; } if (slot->ops->hardware_test) retval = slot->ops->hardware_test(slot, test); - module_put(slot->ops->owner); + module_put(slot->owner); exit: if (retval) @@ -447,8 +448,8 @@ int __pci_hp_initialize(struct hotplug_slot *slot, struct pci_bus *bus, if ((slot->info == NULL) || (slot->ops == NULL)) return -EINVAL; - slot->ops->owner = owner; - slot->ops->mod_name = mod_name; + slot->owner = owner; + slot->mod_name = mod_name; /* * No problems if we call this interface from both ACPI_PCI_SLOT diff --git a/drivers/pci/hotplug/pnv_php.c b/drivers/pci/hotplug/pnv_php.c index 3276a5e4c430..12b92a0ff688 100644 --- a/drivers/pci/hotplug/pnv_php.c +++ b/drivers/pci/hotplug/pnv_php.c @@ -530,7 +530,7 @@ static int pnv_php_disable_slot(struct hotplug_slot *slot) return ret; } -static struct hotplug_slot_ops php_slot_ops = { +static const struct hotplug_slot_ops php_slot_ops = { .get_power_status = pnv_php_get_power_state, .get_adapter_status = pnv_php_get_adapter_state, .set_attention_status = pnv_php_set_attention_state, diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index c8311724bd76..f83347819f7b 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -70,7 +70,7 @@ struct slot { struct hotplug_slot *hotplug_slot; }; -extern struct hotplug_slot_ops rpaphp_hotplug_slot_ops; +extern const struct hotplug_slot_ops rpaphp_hotplug_slot_ops; extern struct list_head rpaphp_slot_head; /* function prototypes */ diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index 857c358b727b..8620a3f8c987 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -477,7 +477,7 @@ static int disable_slot(struct hotplug_slot *hotplug_slot) return 0; } -struct hotplug_slot_ops rpaphp_hotplug_slot_ops = { +const struct hotplug_slot_ops rpaphp_hotplug_slot_ops = { .enable_slot = enable_slot, .disable_slot = disable_slot, .set_attention_status = set_attention_status, diff --git a/drivers/pci/hotplug/s390_pci_hpc.c b/drivers/pci/hotplug/s390_pci_hpc.c index 93b5341d282c..5bd45fd4a92a 100644 --- a/drivers/pci/hotplug/s390_pci_hpc.c +++ b/drivers/pci/hotplug/s390_pci_hpc.c @@ -130,7 +130,7 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) return 0; } -static struct hotplug_slot_ops s390_hotplug_slot_ops = { +static const struct hotplug_slot_ops s390_hotplug_slot_ops = { .enable_slot = enable_slot, .disable_slot = disable_slot, .get_power_status = get_power_status, diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index babd23409f61..af4c28c574dd 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c @@ -80,7 +80,7 @@ static int enable_slot(struct hotplug_slot *slot); static int disable_slot(struct hotplug_slot *slot); static inline int get_power_status(struct hotplug_slot *slot, u8 *value); -static struct hotplug_slot_ops sn_hotplug_slot_ops = { +static const struct hotplug_slot_ops sn_hotplug_slot_ops = { .enable_slot = enable_slot, .disable_slot = disable_slot, .get_power_status = get_power_status, diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index 97cee23f3d51..26cbea04237c 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c @@ -51,7 +51,7 @@ static int get_attention_status(struct hotplug_slot *slot, u8 *value); static int get_latch_status(struct hotplug_slot *slot, u8 *value); static int get_adapter_status(struct hotplug_slot *slot, u8 *value); -static struct hotplug_slot_ops shpchp_hotplug_slot_ops = { +static const struct hotplug_slot_ops shpchp_hotplug_slot_ops = { .set_attention_status = set_attention_status, .enable_slot = enable_slot, .disable_slot = disable_slot, diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 29ff9619b5fa..3f00130c7ae9 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -4570,13 +4570,13 @@ static int pci_reset_hotplug_slot(struct hotplug_slot *hotplug, int probe) { int rc = -ENOTTY; - if (!hotplug || !try_module_get(hotplug->ops->owner)) + if (!hotplug || !try_module_get(hotplug->owner)) return rc; if (hotplug->ops->reset_slot) rc = hotplug->ops->reset_slot(hotplug, probe); - module_put(hotplug->ops->owner); + module_put(hotplug->owner); return rc; } diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index e634229ece89..145cd953b518 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c @@ -371,7 +371,7 @@ void pci_hp_create_module_link(struct pci_slot *pci_slot) if (!slot || !slot->ops) return; - kobj = kset_find_obj(module_kset, slot->ops->mod_name); + kobj = kset_find_obj(module_kset, slot->mod_name); if (!kobj) return; ret = sysfs_create_link(&pci_slot->kobj, kobj, "module"); diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index d67f32a29bb4..d05ac442e4ec 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -858,8 +858,7 @@ static int asus_get_adapter_status(struct hotplug_slot *hotplug_slot, return 0; } -static struct hotplug_slot_ops asus_hotplug_slot_ops = { - .owner = THIS_MODULE, +static const struct hotplug_slot_ops asus_hotplug_slot_ops = { .get_adapter_status = asus_get_adapter_status, .get_power_status = asus_get_adapter_status, }; diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index a4bbf6ecd1f0..41a364376e91 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -726,8 +726,7 @@ static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot, return 0; } -static struct hotplug_slot_ops eeepc_hotplug_slot_ops = { - .owner = THIS_MODULE, +static const struct hotplug_slot_ops eeepc_hotplug_slot_ops = { .get_adapter_status = eeepc_get_adapter_status, .get_power_status = eeepc_get_adapter_status, }; diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h index a6d6650a0490..372dbe95c207 100644 --- a/include/linux/pci_hotplug.h +++ b/include/linux/pci_hotplug.h @@ -16,8 +16,6 @@ /** * struct hotplug_slot_ops -the callbacks that the hotplug pci core can use - * @owner: The module owner of this structure - * @mod_name: The module name (KBUILD_MODNAME) of this structure * @enable_slot: Called when the user wants to enable a specific pci slot * @disable_slot: Called when the user wants to disable a specific pci slot * @set_attention_status: Called to set the specific slot's attention LED to @@ -46,8 +44,6 @@ * set an LED, enable / disable power, etc.) */ struct hotplug_slot_ops { - struct module *owner; - const char *mod_name; int (*enable_slot) (struct hotplug_slot *slot); int (*disable_slot) (struct hotplug_slot *slot); int (*set_attention_status) (struct hotplug_slot *slot, u8 value); @@ -82,15 +78,19 @@ struct hotplug_slot_info { * this slot. * @private: used by the hotplug pci controller driver to store whatever it * needs. + * @owner: The module owner of this structure + * @mod_name: The module name (KBUILD_MODNAME) of this structure */ struct hotplug_slot { - struct hotplug_slot_ops *ops; + const struct hotplug_slot_ops *ops; struct hotplug_slot_info *info; void *private; /* Variables below this are for use only by the hotplug pci core. */ struct list_head slot_list; struct pci_slot *pci_slot; + struct module *owner; + const char *mod_name; }; static inline const char *hotplug_slot_name(const struct hotplug_slot *slot) From patchwork Sun Aug 19 14:29:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Wunner X-Patchwork-Id: 959413 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41tlTT5Zpvz9s4V for ; Mon, 20 Aug 2018 04:14:53 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=wunner.de Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 41tlTT4G0hzF1Sc for ; Mon, 20 Aug 2018 04:14:53 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=wunner.de X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=none (mailfrom) smtp.mailfrom=wunner.de (client-ip=83.223.90.233; helo=mailout2.hostsharing.net; envelope-from=lukas@wunner.de; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=wunner.de Received: from mailout2.hostsharing.net (mailout2.hostsharing.net [83.223.90.233]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 41tlRf6WYkzF0vb for ; Mon, 20 Aug 2018 04:13:18 +1000 (AEST) Received: from h08.hostsharing.net (h08.hostsharing.net [83.223.95.28]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "*.hostsharing.net", Issuer "COMODO RSA Domain Validation Secure Server CA" (not verified)) by mailout2.hostsharing.net (Postfix) with ESMTPS id D328910189CEF; Sun, 19 Aug 2018 16:37:00 +0200 (CEST) Received: from localhost (unknown [89.246.108.87]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by h08.hostsharing.net (Postfix) with ESMTPSA id 50BCD609B163; Sun, 19 Aug 2018 16:37:00 +0200 (CEST) X-Mailbox-Line: From a364bcc959e01f2ebab27cefc5b87ff01633275c Mon Sep 17 00:00:00 2001 Message-Id: In-Reply-To: References: From: Lukas Wunner Date: Sun, 19 Aug 2018 16:29:00 +0200 Subject: [PATCH 7/9] PCI: hotplug: Drop hotplug_slot_info To: Bjorn Helgaas , linux-pci@vger.kernel.org, Sinan Kaya , Mika Westerberg X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Scott Murray , linux-s390@vger.kernel.org, Greg Kroah-Hartman , acpi4asus-user@lists.sourceforge.net, "Rafael J. Wysocki" , Gavin Shan , platform-driver-x86@vger.kernel.org, linux-acpi@vger.kernel.org, Paul Mackerras , Sebastian Ott , Corentin Chary , Darren Hart , linuxppc-dev@lists.ozlabs.org, Andy Shevchenko , Gerald Schaefer , Len Brown Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" Ever since the PCI hotplug core was introduced in 2002, drivers had to allocate and register a struct hotplug_slot_info for every slot: https://git.kernel.org/tglx/history/c/a8a2069f432c Apparently the idea was that drivers furnish the hotplug core with an up-to-date card presence status, power status, latch status and attention indicator status as well as notify the hotplug core of changes thereof. However only 4 out of 12 hotplug drivers bother to notify the hotplug core with pci_hp_change_slot_info() and the hotplug core never made any use of the information: There is just a single macro in pci_hotplug_core.c, GET_STATUS(), which uses the hotplug_slot_info if the driver lacks the corresponding callback in hotplug_slot_ops. The macro is called when the user reads the attribute via sysfs. Now, if the callback isn't defined, the attribute isn't exposed in sysfs in the first place (see e.g. has_power_file()). There are only two situations when the hotplug_slot_info would actually be accessed: * If the driver defines ->enable_slot or ->disable_slot but not ->get_power_status. * If the driver defines ->set_attention_status but not ->get_attention_status. There is no driver doing the former and just a single driver doing the latter, namely pnv_php.c. Amend it with a ->get_attention_status callback. With that, the hotplug_slot_info becomes completely unused by the PCI hotplug core. But a few drivers use it internally as a cache: cpcihp uses it to cache the latch_status and adapter_status. cpqhp uses it to cache the adapter_status. pnv_php and rpaphp use it to cache the attention_status. shpchp uses it to cache all four values. Amend these drivers to cache the information in their private slot struct. shpchp's slot struct already contains members to cache the power_status and adapter_status, so additional members are only needed for the other two values. In the case of cpqphp, the cached value is only accessed in a single place, so instead of caching it, read the current value from the hardware. Caution: acpiphp, cpci, cpqhp, shpchp, asus-wmi and eeepc-laptop populate the hotplug_slot_info with initial values on probe. That code is herewith removed. There is a theoretical chance that the code has side effects without which the driver fails to function, e.g. if the ACPI method to read the adapter status needs to be executed at least once on probe. That seems unlikely to me, still maintainers should review the changes carefully for this possibility. Signed-off-by: Lukas Wunner Cc: Rafael J. Wysocki Cc: Len Brown Cc: Scott Murray Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Michael Ellerman Cc: Gavin Shan Cc: Sebastian Ott Cc: Gerald Schaefer Cc: Corentin Chary Cc: Darren Hart Cc: Andy Shevchenko Reviewed-by: Rafael J. Wysocki Acked-by: Tyrel Datwyler Acked-by: Sebastian Ott --- arch/powerpc/include/asm/pnv-pci.h | 2 +- drivers/pci/hotplug/acpiphp.h | 1 - drivers/pci/hotplug/acpiphp_core.c | 6 --- drivers/pci/hotplug/cpci_hotplug.h | 2 + drivers/pci/hotplug/cpci_hotplug_core.c | 72 +++++-------------------- drivers/pci/hotplug/cpqphp_core.c | 22 +------- drivers/pci/hotplug/cpqphp_ctrl.c | 31 +---------- drivers/pci/hotplug/ibmphp_core.c | 27 +--------- drivers/pci/hotplug/ibmphp_ebda.c | 33 ------------ drivers/pci/hotplug/pci_hotplug_core.c | 26 +-------- drivers/pci/hotplug/pciehp_core.c | 8 --- drivers/pci/hotplug/pnv_php.c | 24 ++++++--- drivers/pci/hotplug/rpaphp.h | 1 + drivers/pci/hotplug/rpaphp_core.c | 4 +- drivers/pci/hotplug/rpaphp_pci.c | 11 +--- drivers/pci/hotplug/rpaphp_slot.c | 9 +--- drivers/pci/hotplug/s390_pci_hpc.c | 12 ----- drivers/pci/hotplug/sgi_hotplug.c | 9 ---- drivers/pci/hotplug/shpchp.h | 2 + drivers/pci/hotplug/shpchp_core.c | 31 ++++------- drivers/pci/hotplug/shpchp_ctrl.c | 21 ++------ drivers/platform/x86/asus-wmi.c | 10 ---- drivers/platform/x86/eeepc-laptop.c | 10 ---- include/linux/pci_hotplug.h | 30 ----------- 24 files changed, 64 insertions(+), 340 deletions(-) diff --git a/arch/powerpc/include/asm/pnv-pci.h b/arch/powerpc/include/asm/pnv-pci.h index 7f627e3f4da4..630eb8b1b7ed 100644 --- a/arch/powerpc/include/asm/pnv-pci.h +++ b/arch/powerpc/include/asm/pnv-pci.h @@ -54,7 +54,6 @@ void pnv_cxl_release_hwirq_ranges(struct cxl_irq_ranges *irqs, struct pnv_php_slot { struct hotplug_slot slot; - struct hotplug_slot_info slot_info; uint64_t id; char *name; int slot_no; @@ -72,6 +71,7 @@ struct pnv_php_slot { struct pci_dev *pdev; struct pci_bus *bus; bool power_state_check; + u8 attention_state; void *fdt; void *dt; struct of_changeset ocs; diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index e438a2d734f2..8377e736ea69 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h @@ -35,7 +35,6 @@ struct acpiphp_slot; struct slot { struct hotplug_slot *hotplug_slot; struct acpiphp_slot *acpi_slot; - struct hotplug_slot_info info; unsigned int sun; /* ACPI _SUN (Slot User Number) value */ }; diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index e883cef0f3bc..abd4f8d7e16a 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c @@ -270,16 +270,10 @@ int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot, if (!slot->hotplug_slot) goto error_slot; - slot->hotplug_slot->info = &slot->info; - slot->hotplug_slot->private = slot; slot->hotplug_slot->ops = &acpi_hotplug_slot_ops; slot->acpi_slot = acpiphp_slot; - slot->hotplug_slot->info->power_status = acpiphp_get_power_status(slot->acpi_slot); - slot->hotplug_slot->info->attention_status = 0; - slot->hotplug_slot->info->latch_status = acpiphp_get_latch_status(slot->acpi_slot); - slot->hotplug_slot->info->adapter_status = acpiphp_get_adapter_status(slot->acpi_slot); acpiphp_slot->slot = slot; slot->sun = sun; diff --git a/drivers/pci/hotplug/cpci_hotplug.h b/drivers/pci/hotplug/cpci_hotplug.h index 4658557be01a..146b06fd12c0 100644 --- a/drivers/pci/hotplug/cpci_hotplug.h +++ b/drivers/pci/hotplug/cpci_hotplug.h @@ -32,6 +32,8 @@ struct slot { unsigned int devfn; struct pci_bus *bus; struct pci_dev *dev; + bool latch_status; + bool adapter_status; unsigned int extracting; struct hotplug_slot *hotplug_slot; struct list_head slot_list; diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c index 97c32e4c74c8..a17fb24c28cd 100644 --- a/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/drivers/pci/hotplug/cpci_hotplug_core.c @@ -67,26 +67,6 @@ static const struct hotplug_slot_ops cpci_hotplug_slot_ops = { .get_latch_status = get_latch_status, }; -static int -update_latch_status(struct hotplug_slot *hotplug_slot, u8 value) -{ - struct hotplug_slot_info info; - - memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info)); - info.latch_status = value; - return pci_hp_change_slot_info(hotplug_slot, &info); -} - -static int -update_adapter_status(struct hotplug_slot *hotplug_slot, u8 value) -{ - struct hotplug_slot_info info; - - memcpy(&info, hotplug_slot->info, sizeof(struct hotplug_slot_info)); - info.adapter_status = value; - return pci_hp_change_slot_info(hotplug_slot, &info); -} - static int enable_slot(struct hotplug_slot *hotplug_slot) { @@ -135,8 +115,7 @@ disable_slot(struct hotplug_slot *hotplug_slot) goto disable_error; } - if (update_adapter_status(slot->hotplug_slot, 0)) - warn("failure to update adapter file"); + slot->adapter_status = 0; if (slot->extracting) { slot->extracting = 0; @@ -184,20 +163,23 @@ set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) { - *value = hotplug_slot->info->adapter_status; + struct slot *slot = hotplug_slot->private; + + *value = slot->adapter_status; return 0; } static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) { - *value = hotplug_slot->info->latch_status; + struct slot *slot = hotplug_slot->private; + + *value = slot->latch_status; return 0; } static void release_slot(struct slot *slot) { - kfree(slot->hotplug_slot->info); kfree(slot->hotplug_slot); pci_dev_put(slot->dev); kfree(slot); @@ -210,7 +192,6 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last) { struct slot *slot; struct hotplug_slot *hotplug_slot; - struct hotplug_slot_info *info; char name[SLOT_NAME_SIZE]; int status; int i; @@ -237,13 +218,6 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last) } slot->hotplug_slot = hotplug_slot; - info = kzalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL); - if (!info) { - status = -ENOMEM; - goto error_hpslot; - } - hotplug_slot->info = info; - slot->bus = bus; slot->number = i; slot->devfn = PCI_DEVFN(i, 0); @@ -253,19 +227,11 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last) hotplug_slot->private = slot; hotplug_slot->ops = &cpci_hotplug_slot_ops; - /* - * Initialize the slot info structure with some known - * good values. - */ - dbg("initializing slot %s", name); - info->power_status = cpci_get_power_status(slot); - info->attention_status = cpci_get_attention_status(slot); - dbg("registering slot %s", name); status = pci_hp_register(slot->hotplug_slot, bus, i, name); if (status) { err("pci_hp_register failed with error %d", status); - goto error_info; + goto error_hpslot; } dbg("slot registered with name: %s", slot_name(slot)); @@ -276,8 +242,6 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last) up_write(&list_rwsem); } return 0; -error_info: - kfree(info); error_hpslot: kfree(hotplug_slot); error_slot: @@ -359,10 +323,8 @@ init_slots(int clear_ins) __func__, slot_name(slot)); dev = pci_get_slot(slot->bus, PCI_DEVFN(slot->number, 0)); if (dev) { - if (update_adapter_status(slot->hotplug_slot, 1)) - warn("failure to update adapter file"); - if (update_latch_status(slot->hotplug_slot, 1)) - warn("failure to update latch file"); + slot->adapter_status = 1; + slot->latch_status = 1; slot->dev = dev; } } @@ -424,11 +386,8 @@ check_slots(void) dbg("%s - slot %s HS_CSR (2) = %04x", __func__, slot_name(slot), hs_csr); - if (update_latch_status(slot->hotplug_slot, 1)) - warn("failure to update latch file"); - - if (update_adapter_status(slot->hotplug_slot, 1)) - warn("failure to update adapter file"); + slot->latch_status = 1; + slot->adapter_status = 1; cpci_led_off(slot); @@ -449,9 +408,7 @@ check_slots(void) __func__, slot_name(slot), hs_csr); if (!slot->extracting) { - if (update_latch_status(slot->hotplug_slot, 0)) - warn("failure to update latch file"); - + slot->latch_status = 0; slot->extracting = 1; atomic_inc(&extracting); } @@ -465,8 +422,7 @@ check_slots(void) */ err("card in slot %s was improperly removed", slot_name(slot)); - if (update_adapter_status(slot->hotplug_slot, 0)) - warn("failure to update adapter file"); + slot->adapter_status = 0; slot->extracting = 0; atomic_dec(&extracting); } diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index 3409b62fceac..bb354a7fc112 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c @@ -276,7 +276,6 @@ static int ctrl_slot_cleanup(struct controller *ctrl) while (old_slot) { next_slot = old_slot->next; pci_hp_deregister(old_slot->hotplug_slot); - kfree(old_slot->hotplug_slot->info); kfree(old_slot->hotplug_slot); kfree(old_slot); old_slot = next_slot; @@ -579,7 +578,6 @@ static int ctrl_slot_setup(struct controller *ctrl, { struct slot *slot; struct hotplug_slot *hotplug_slot; - struct hotplug_slot_info *hotplug_slot_info; struct pci_bus *bus = ctrl->pci_bus; u8 number_of_slots; u8 slot_device; @@ -613,14 +611,6 @@ static int ctrl_slot_setup(struct controller *ctrl, } hotplug_slot = slot->hotplug_slot; - hotplug_slot->info = kzalloc(sizeof(*(hotplug_slot->info)), - GFP_KERNEL); - if (!hotplug_slot->info) { - result = -ENOMEM; - goto error_hpslot; - } - hotplug_slot_info = hotplug_slot->info; - slot->ctrl = ctrl; slot->bus = ctrl->bus; slot->device = slot_device; @@ -673,14 +663,6 @@ static int ctrl_slot_setup(struct controller *ctrl, snprintf(name, SLOT_NAME_SIZE, "%u", slot->number); hotplug_slot->ops = &cpqphp_hotplug_slot_ops; - hotplug_slot_info->power_status = get_slot_enabled(ctrl, slot); - hotplug_slot_info->attention_status = - cpq_get_attention_status(ctrl, slot); - hotplug_slot_info->latch_status = - cpq_get_latch_status(ctrl, slot); - hotplug_slot_info->adapter_status = - get_presence_status(ctrl, slot); - dbg("registering bus %d, dev %d, number %d, ctrl->slot_device_offset %d, slot %d\n", slot->bus, slot->device, slot->number, ctrl->slot_device_offset, @@ -691,7 +673,7 @@ static int ctrl_slot_setup(struct controller *ctrl, name); if (result) { err("pci_hp_register failed with error %d\n", result); - goto error_info; + goto error_hpslot; } slot->next = ctrl->slot; @@ -703,8 +685,6 @@ static int ctrl_slot_setup(struct controller *ctrl, } return 0; -error_info: - kfree(hotplug_slot_info); error_hpslot: kfree(hotplug_slot); error_slot: diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c index 616df442520b..9c4826ac6a4f 100644 --- a/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/drivers/pci/hotplug/cpqphp_ctrl.c @@ -1130,9 +1130,9 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ for (slot = ctrl->slot; slot; slot = slot->next) { if (slot->device == (hp_slot + ctrl->slot_device_offset)) continue; - if (!slot->hotplug_slot || !slot->hotplug_slot->info) + if (!slot->hotplug_slot) continue; - if (slot->hotplug_slot->info->adapter_status == 0) + if (get_presence_status(ctrl, slot) == 0) continue; /* If another adapter is running on the same segment but at a * lower speed/mode, we allow the new adapter to function at @@ -1767,24 +1767,6 @@ void cpqhp_event_stop_thread(void) } -static int update_slot_info(struct controller *ctrl, struct slot *slot) -{ - struct hotplug_slot_info *info; - int result; - - info = kmalloc(sizeof(*info), GFP_KERNEL); - if (!info) - return -ENOMEM; - - info->power_status = get_slot_enabled(ctrl, slot); - info->attention_status = cpq_get_attention_status(ctrl, slot); - info->latch_status = cpq_get_latch_status(ctrl, slot); - info->adapter_status = get_presence_status(ctrl, slot); - result = pci_hp_change_slot_info(slot->hotplug_slot, info); - kfree(info); - return result; -} - static void interrupt_event_handler(struct controller *ctrl) { int loop = 0; @@ -1884,9 +1866,6 @@ static void interrupt_event_handler(struct controller *ctrl) /***********POWER FAULT */ else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) { dbg("power fault\n"); - } else { - /* refresh notification */ - update_slot_info(ctrl, p_slot); } ctrl->event_queue[loop].event_type = 0; @@ -2057,9 +2036,6 @@ int cpqhp_process_SI(struct controller *ctrl, struct pci_func *func) if (rc) dbg("%s: rc = %d\n", __func__, rc); - if (p_slot) - update_slot_info(ctrl, p_slot); - return rc; } @@ -2125,9 +2101,6 @@ int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func) rc = 1; } - if (p_slot) - update_slot_info(ctrl, p_slot); - return rc; } diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index b82fdc17040d..96e5b1f544ac 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c @@ -582,29 +582,10 @@ static int validate(struct slot *slot_cur, int opn) ****************************************************************************/ int ibmphp_update_slot_info(struct slot *slot_cur) { - struct hotplug_slot_info *info; struct pci_bus *bus = slot_cur->hotplug_slot->pci_slot->bus; - int rc; u8 bus_speed; u8 mode; - info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL); - if (!info) - return -ENOMEM; - - info->power_status = SLOT_PWRGD(slot_cur->status); - info->attention_status = SLOT_ATTN(slot_cur->status, - slot_cur->ext_status); - info->latch_status = SLOT_LATCH(slot_cur->status); - if (!SLOT_PRESENT(slot_cur->status)) { - info->adapter_status = 0; -/* info->max_adapter_speed_status = MAX_ADAPTER_NONE; */ - } else { - info->adapter_status = 1; -/* get_max_adapter_speed_1(slot_cur->hotplug_slot, - &info->max_adapter_speed_status, 0); */ - } - bus_speed = slot_cur->bus_on->current_speed; mode = slot_cur->bus_on->current_bus_mode; @@ -630,9 +611,7 @@ int ibmphp_update_slot_info(struct slot *slot_cur) bus->cur_bus_speed = bus_speed; // To do: bus_names - rc = pci_hp_change_slot_info(slot_cur->hotplug_slot, info); - kfree(info); - return rc; + return 0; } @@ -684,7 +663,6 @@ static void free_slots(void) ibmphp_unconfigure_card(&slot_cur, -1); pci_hp_destroy(slot_cur->hotplug_slot); - kfree(slot_cur->hotplug_slot->info); kfree(slot_cur->hotplug_slot); kfree(slot_cur); } @@ -1095,8 +1073,7 @@ static int enable_slot(struct hotplug_slot *hs) slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL); if (!slot_cur->func) { - /* We cannot do update_slot_info here, since no memory for - * kmalloc n.e.ways, and update_slot_info allocates some */ + /* do update_slot_info here? */ rc = -ENOMEM; goto error_power; } diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c index 6f8e90e3ec08..c05d066ab0d5 100644 --- a/drivers/pci/hotplug/ibmphp_ebda.c +++ b/drivers/pci/hotplug/ibmphp_ebda.c @@ -671,31 +671,6 @@ static int fillslotinfo(struct hotplug_slot *hotplug_slot) slot = hotplug_slot->private; rc = ibmphp_hpc_readslot(slot, READ_ALLSTAT, NULL); - if (rc) - return rc; - - // power - enabled:1 not:0 - hotplug_slot->info->power_status = SLOT_POWER(slot->status); - - // attention - off:0, on:1, blinking:2 - hotplug_slot->info->attention_status = SLOT_ATTN(slot->status, slot->ext_status); - - // latch - open:1 closed:0 - hotplug_slot->info->latch_status = SLOT_LATCH(slot->status); - - // pci board - present:1 not:0 - if (SLOT_PRESENT(slot->status)) - hotplug_slot->info->adapter_status = 1; - else - hotplug_slot->info->adapter_status = 0; -/* - if (slot->bus_on->supported_bus_mode - && (slot->bus_on->supported_speed == BUS_SPEED_66)) - hotplug_slot->info->max_bus_speed_status = BUS_SPEED_66PCIX; - else - hotplug_slot->info->max_bus_speed_status = slot->bus_on->supported_speed; -*/ - return rc; } @@ -877,12 +852,6 @@ static int __init ebda_rsrc_controller(void) goto error_no_hp_slot; } - hp_slot_ptr->info = kzalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL); - if (!hp_slot_ptr->info) { - rc = -ENOMEM; - goto error_no_hp_info; - } - tmp_slot = kzalloc(sizeof(*tmp_slot), GFP_KERNEL); if (!tmp_slot) { rc = -ENOMEM; @@ -955,8 +924,6 @@ static int __init ebda_rsrc_controller(void) error: kfree(hp_slot_ptr->private); error_no_slot: - kfree(hp_slot_ptr->info); -error_no_hp_info: kfree(hp_slot_ptr); error_no_hp_slot: free_ebda_hpc(hpc_ptr); diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index ede2ed6f4ce0..5ac31f683b85 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c @@ -55,8 +55,6 @@ static int get_##name(struct hotplug_slot *slot, type *value) \ return -ENODEV; \ if (ops->get_##name) \ retval = ops->get_##name(slot, value); \ - else \ - *value = slot->info->name; \ module_put(slot->owner); \ return retval; \ } @@ -445,7 +443,7 @@ int __pci_hp_initialize(struct hotplug_slot *slot, struct pci_bus *bus, if (slot == NULL) return -ENODEV; - if ((slot->info == NULL) || (slot->ops == NULL)) + if (slot->ops == NULL) return -EINVAL; slot->owner = owner; @@ -560,28 +558,6 @@ void pci_hp_destroy(struct hotplug_slot *slot) } EXPORT_SYMBOL_GPL(pci_hp_destroy); -/** - * pci_hp_change_slot_info - changes the slot's information structure in the core - * @slot: pointer to the slot whose info has changed - * @info: pointer to the info copy into the slot's info structure - * - * @slot must have been registered with the pci - * hotplug subsystem previously with a call to pci_hp_register(). - * - * Returns 0 if successful, anything else for an error. - */ -int pci_hp_change_slot_info(struct hotplug_slot *slot, - struct hotplug_slot_info *info) -{ - if (!slot || !info) - return -ENODEV; - - memcpy(slot->info, info, sizeof(struct hotplug_slot_info)); - - return 0; -} -EXPORT_SYMBOL_GPL(pci_hp_change_slot_info); - static int __init pci_hotplug_init(void) { int result; diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 2c9fa5263634..dda90030005d 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -52,7 +52,6 @@ static int get_adapter_status(struct hotplug_slot *slot, u8 *value); static int init_slot(struct controller *ctrl) { struct hotplug_slot *hotplug = NULL; - struct hotplug_slot_info *info = NULL; struct hotplug_slot_ops *ops = NULL; char name[SLOT_NAME_SIZE]; int retval = -ENOMEM; @@ -61,10 +60,6 @@ static int init_slot(struct controller *ctrl) if (!hotplug) goto out; - info = kzalloc(sizeof(*info), GFP_KERNEL); - if (!info) - goto out; - /* Setup hotplug slot ops */ ops = kzalloc(sizeof(*ops), GFP_KERNEL); if (!ops) @@ -86,7 +81,6 @@ static int init_slot(struct controller *ctrl) } /* register this slot with the hotplug pci core */ - hotplug->info = info; hotplug->private = ctrl; hotplug->ops = ops; ctrl->hotplug_slot = hotplug; @@ -99,7 +93,6 @@ static int init_slot(struct controller *ctrl) out: if (retval) { kfree(ops); - kfree(info); kfree(hotplug); } return retval; @@ -111,7 +104,6 @@ static void cleanup_slot(struct controller *ctrl) pci_hp_destroy(hotplug_slot); kfree(hotplug_slot->ops); - kfree(hotplug_slot->info); kfree(hotplug_slot); } diff --git a/drivers/pci/hotplug/pnv_php.c b/drivers/pci/hotplug/pnv_php.c index 12b92a0ff688..5bb63430262e 100644 --- a/drivers/pci/hotplug/pnv_php.c +++ b/drivers/pci/hotplug/pnv_php.c @@ -328,6 +328,11 @@ static int pnv_php_add_devtree(struct pnv_php_slot *php_slot) return ret; } +static inline struct pnv_php_slot *to_pnv_php_slot(struct hotplug_slot *slot) +{ + return container_of(slot, struct pnv_php_slot, slot); +} + int pnv_php_set_slot_power_state(struct hotplug_slot *slot, uint8_t state) { @@ -378,7 +383,6 @@ static int pnv_php_get_power_state(struct hotplug_slot *slot, u8 *state) ret); } else { *state = power_state; - slot->info->power_status = power_state; } return 0; @@ -397,7 +401,6 @@ static int pnv_php_get_adapter_state(struct hotplug_slot *slot, u8 *state) ret = pnv_pci_get_presence_state(php_slot->id, &presence); if (ret >= 0) { *state = presence; - slot->info->adapter_status = presence; ret = 0; } else { pci_warn(php_slot->pdev, "Error %d getting presence\n", ret); @@ -406,10 +409,20 @@ static int pnv_php_get_adapter_state(struct hotplug_slot *slot, u8 *state) return ret; } +static int pnv_php_get_attention_state(struct hotplug_slot *slot, u8 *state) +{ + struct pnv_php_slot *php_slot = to_pnv_php_slot(slot); + + *state = php_slot->attention_state; + return 0; +} + static int pnv_php_set_attention_state(struct hotplug_slot *slot, u8 state) { + struct pnv_php_slot *php_slot = to_pnv_php_slot(slot); + /* FIXME: Make it real once firmware supports it */ - slot->info->attention_status = state; + php_slot->attention_state = state; return 0; } @@ -501,8 +514,7 @@ static int pnv_php_enable(struct pnv_php_slot *php_slot, bool rescan) static int pnv_php_enable_slot(struct hotplug_slot *slot) { - struct pnv_php_slot *php_slot = container_of(slot, - struct pnv_php_slot, slot); + struct pnv_php_slot *php_slot = to_pnv_php_slot(slot); return pnv_php_enable(php_slot, true); } @@ -533,6 +545,7 @@ static int pnv_php_disable_slot(struct hotplug_slot *slot) static const struct hotplug_slot_ops php_slot_ops = { .get_power_status = pnv_php_get_power_state, .get_adapter_status = pnv_php_get_adapter_state, + .get_attention_status = pnv_php_get_attention_state, .set_attention_status = pnv_php_set_attention_state, .enable_slot = pnv_php_enable_slot, .disable_slot = pnv_php_disable_slot, @@ -594,7 +607,6 @@ static struct pnv_php_slot *pnv_php_alloc_slot(struct device_node *dn) php_slot->id = id; php_slot->power_state_check = false; php_slot->slot.ops = &php_slot_ops; - php_slot->slot.info = &php_slot->slot_info; php_slot->slot.private = php_slot; INIT_LIST_HEAD(&php_slot->children); diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index f83347819f7b..26a3dd731b5e 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -63,6 +63,7 @@ struct slot { u32 index; u32 type; u32 power_domain; + u8 attention_status; char *name; struct device_node *dn; struct pci_bus *bus; diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index 8620a3f8c987..898e78dcd311 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -66,7 +66,7 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value) rc = rtas_set_indicator(DR_INDICATOR, slot->index, value); if (!rc) - hotplug_slot->info->attention_status = value; + slot->attention_status = value; return rc; } @@ -95,7 +95,7 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) { struct slot *slot = (struct slot *)hotplug_slot->private; - *value = slot->hotplug_slot->info->attention_status; + *value = slot->attention_status; return 0; } diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index 0aac33e15dab..beca61badeea 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -54,25 +54,21 @@ int rpaphp_get_sensor_state(struct slot *slot, int *state) * rpaphp_enable_slot - record slot state, config pci device * @slot: target &slot * - * Initialize values in the slot, and the hotplug_slot info - * structures to indicate if there is a pci card plugged into - * the slot. If the slot is not empty, run the pcibios routine + * Initialize values in the slot structure to indicate if there is a pci card + * plugged into the slot. If the slot is not empty, run the pcibios routine * to get pcibios stuff correctly set up. */ int rpaphp_enable_slot(struct slot *slot) { int rc, level, state; struct pci_bus *bus; - struct hotplug_slot_info *info = slot->hotplug_slot->info; - info->adapter_status = NOT_VALID; slot->state = EMPTY; /* Find out if the power is turned on for the slot */ rc = rtas_get_power_level(slot->power_domain, &level); if (rc) return rc; - info->power_status = level; /* Figure out if there is an adapter in the slot */ rc = rpaphp_get_sensor_state(slot, &state); @@ -85,13 +81,11 @@ int rpaphp_enable_slot(struct slot *slot) return -EINVAL; } - info->adapter_status = EMPTY; slot->bus = bus; slot->pci_devs = &bus->devices; /* if there's an adapter in the slot, go add the pci devices */ if (state == PRESENT) { - info->adapter_status = NOT_CONFIGURED; slot->state = NOT_CONFIGURED; /* non-empty slot has to have child */ @@ -105,7 +99,6 @@ int rpaphp_enable_slot(struct slot *slot) pci_hp_add_devices(bus); if (!list_empty(&bus->devices)) { - info->adapter_status = CONFIGURED; slot->state = CONFIGURED; } diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c index b916c8e4372d..6e2658ce300b 100644 --- a/drivers/pci/hotplug/rpaphp_slot.c +++ b/drivers/pci/hotplug/rpaphp_slot.c @@ -21,7 +21,6 @@ /* free up the memory used by a slot */ void dealloc_slot_struct(struct slot *slot) { - kfree(slot->hotplug_slot->info); kfree(slot->name); kfree(slot->hotplug_slot); kfree(slot); @@ -38,13 +37,9 @@ struct slot *alloc_slot_struct(struct device_node *dn, slot->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL); if (!slot->hotplug_slot) goto error_slot; - slot->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info), - GFP_KERNEL); - if (!slot->hotplug_slot->info) - goto error_hpslot; slot->name = kstrdup(drc_name, GFP_KERNEL); if (!slot->name) - goto error_info; + goto error_hpslot; slot->dn = dn; slot->index = drc_index; slot->power_domain = power_domain; @@ -53,8 +48,6 @@ struct slot *alloc_slot_struct(struct device_node *dn, return (slot); -error_info: - kfree(slot->hotplug_slot->info); error_hpslot: kfree(slot->hotplug_slot); error_slot: diff --git a/drivers/pci/hotplug/s390_pci_hpc.c b/drivers/pci/hotplug/s390_pci_hpc.c index 5bd45fd4a92a..d04634b0defe 100644 --- a/drivers/pci/hotplug/s390_pci_hpc.c +++ b/drivers/pci/hotplug/s390_pci_hpc.c @@ -140,7 +140,6 @@ static const struct hotplug_slot_ops s390_hotplug_slot_ops = { int zpci_init_slot(struct zpci_dev *zdev) { struct hotplug_slot *hotplug_slot; - struct hotplug_slot_info *info; char name[SLOT_NAME_SIZE]; struct slot *slot; int rc; @@ -160,16 +159,8 @@ int zpci_init_slot(struct zpci_dev *zdev) slot->hotplug_slot = hotplug_slot; slot->zdev = zdev; - info = kzalloc(sizeof(*info), GFP_KERNEL); - if (!info) - goto error_info; - hotplug_slot->info = info; - hotplug_slot->ops = &s390_hotplug_slot_ops; - get_power_status(hotplug_slot, &info->power_status); - get_adapter_status(hotplug_slot, &info->adapter_status); - snprintf(name, SLOT_NAME_SIZE, "%08x", zdev->fid); rc = pci_hp_register(slot->hotplug_slot, zdev->bus, ZPCI_DEVFN, name); @@ -180,8 +171,6 @@ int zpci_init_slot(struct zpci_dev *zdev) return 0; error_reg: - kfree(info); -error_info: kfree(hotplug_slot); error_hp: kfree(slot); @@ -199,7 +188,6 @@ void zpci_exit_slot(struct zpci_dev *zdev) continue; list_del(&slot->slot_list); pci_hp_deregister(slot->hotplug_slot); - kfree(slot->hotplug_slot->info); kfree(slot->hotplug_slot); kfree(slot); } diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index af4c28c574dd..e103826c83e3 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c @@ -585,7 +585,6 @@ static inline int get_power_status(struct hotplug_slot *bss_hotplug_slot, static void sn_release_slot(struct hotplug_slot *bss_hotplug_slot) { - kfree(bss_hotplug_slot->info); kfree(bss_hotplug_slot->private); kfree(bss_hotplug_slot); } @@ -614,14 +613,6 @@ static int sn_hotplug_slot_register(struct pci_bus *pci_bus) goto alloc_err; } - bss_hotplug_slot->info = - kzalloc(sizeof(struct hotplug_slot_info), - GFP_KERNEL); - if (!bss_hotplug_slot->info) { - rc = -ENOMEM; - goto alloc_err; - } - if (sn_hp_slot_private_alloc(bss_hotplug_slot, pci_bus, device, name)) { rc = -ENOMEM; diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index 516e4835019c..a7bb816e6f25 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h @@ -67,7 +67,9 @@ struct slot { u32 number; u8 is_a_board; u8 state; + u8 attention_save; u8 presence_save; + u8 latch_save; u8 pwr_save; struct controller *ctrl; const struct hpc_ops *hpc_ops; diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index 26cbea04237c..b7181b7e7b98 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c @@ -65,7 +65,6 @@ static int init_slots(struct controller *ctrl) { struct slot *slot; struct hotplug_slot *hotplug_slot; - struct hotplug_slot_info *info; char name[SLOT_NAME_SIZE]; int retval; int i; @@ -84,13 +83,6 @@ static int init_slots(struct controller *ctrl) } slot->hotplug_slot = hotplug_slot; - info = kzalloc(sizeof(*info), GFP_KERNEL); - if (!info) { - retval = -ENOMEM; - goto error_hpslot; - } - hotplug_slot->info = info; - slot->hp_slot = i; slot->ctrl = ctrl; slot->bus = ctrl->pci_dev->subordinate->number; @@ -101,7 +93,7 @@ static int init_slots(struct controller *ctrl) slot->wq = alloc_workqueue("shpchp-%d", 0, 0, slot->number); if (!slot->wq) { retval = -ENOMEM; - goto error_info; + goto error_hpslot; } mutex_init(&slot->lock); @@ -124,10 +116,10 @@ static int init_slots(struct controller *ctrl) goto error_slotwq; } - get_power_status(hotplug_slot, &info->power_status); - get_attention_status(hotplug_slot, &info->attention_status); - get_latch_status(hotplug_slot, &info->latch_status); - get_adapter_status(hotplug_slot, &info->adapter_status); + get_power_status(hotplug_slot, &slot->pwr_save); + get_attention_status(hotplug_slot, &slot->attention_save); + get_latch_status(hotplug_slot, &slot->latch_save); + get_adapter_status(hotplug_slot, &slot->presence_save); list_add(&slot->slot_list, &ctrl->slot_list); } @@ -135,8 +127,6 @@ static int init_slots(struct controller *ctrl) return 0; error_slotwq: destroy_workqueue(slot->wq); -error_info: - kfree(info); error_hpslot: kfree(hotplug_slot); error_slot: @@ -154,7 +144,6 @@ void cleanup_slots(struct controller *ctrl) cancel_delayed_work(&slot->work); destroy_workqueue(slot->wq); pci_hp_deregister(slot->hotplug_slot); - kfree(slot->hotplug_slot->info); kfree(slot->hotplug_slot); kfree(slot); } @@ -170,7 +159,7 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", __func__, slot_name(slot)); - hotplug_slot->info->attention_status = status; + slot->attention_save = status; slot->hpc_ops->set_attention_status(slot, status); return 0; @@ -206,7 +195,7 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) retval = slot->hpc_ops->get_power_status(slot, value); if (retval < 0) - *value = hotplug_slot->info->power_status; + *value = slot->pwr_save; return 0; } @@ -221,7 +210,7 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) retval = slot->hpc_ops->get_attention_status(slot, value); if (retval < 0) - *value = hotplug_slot->info->attention_status; + *value = slot->attention_save; return 0; } @@ -236,7 +225,7 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) retval = slot->hpc_ops->get_latch_status(slot, value); if (retval < 0) - *value = hotplug_slot->info->latch_status; + *value = slot->latch_save; return 0; } @@ -251,7 +240,7 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) retval = slot->hpc_ops->get_adapter_status(slot, value); if (retval < 0) - *value = hotplug_slot->info->adapter_status; + *value = slot->presence_save; return 0; } diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index 1267dcc5a531..078003dcde5b 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c @@ -446,23 +446,12 @@ void shpchp_queue_pushbutton_work(struct work_struct *work) mutex_unlock(&p_slot->lock); } -static int update_slot_info (struct slot *slot) +static void update_slot_info(struct slot *slot) { - struct hotplug_slot_info *info; - int result; - - info = kmalloc(sizeof(*info), GFP_KERNEL); - if (!info) - return -ENOMEM; - - slot->hpc_ops->get_power_status(slot, &(info->power_status)); - slot->hpc_ops->get_attention_status(slot, &(info->attention_status)); - slot->hpc_ops->get_latch_status(slot, &(info->latch_status)); - slot->hpc_ops->get_adapter_status(slot, &(info->adapter_status)); - - result = pci_hp_change_slot_info(slot->hotplug_slot, info); - kfree (info); - return result; + slot->hpc_ops->get_power_status(slot, &slot->pwr_save); + slot->hpc_ops->get_attention_status(slot, &slot->attention_save); + slot->hpc_ops->get_latch_status(slot, &slot->latch_save); + slot->hpc_ops->get_adapter_status(slot, &slot->presence_save); } /* diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index d05ac442e4ec..a2130dd2db3c 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -892,15 +892,8 @@ static int asus_setup_pci_hotplug(struct asus_wmi *asus) if (!asus->hotplug_slot) goto error_slot; - asus->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info), - GFP_KERNEL); - if (!asus->hotplug_slot->info) - goto error_info; - asus->hotplug_slot->private = asus; asus->hotplug_slot->ops = &asus_hotplug_slot_ops; - asus_get_adapter_status(asus->hotplug_slot, - &asus->hotplug_slot->info->adapter_status); ret = pci_hp_register(asus->hotplug_slot, bus, 0, "asus-wifi"); if (ret) { @@ -911,8 +904,6 @@ static int asus_setup_pci_hotplug(struct asus_wmi *asus) return 0; error_register: - kfree(asus->hotplug_slot->info); -error_info: kfree(asus->hotplug_slot); asus->hotplug_slot = NULL; error_slot: @@ -1045,7 +1036,6 @@ static void asus_wmi_rfkill_exit(struct asus_wmi *asus) asus_rfkill_hotplug(asus); if (asus->hotplug_slot) { pci_hp_deregister(asus->hotplug_slot); - kfree(asus->hotplug_slot->info); kfree(asus->hotplug_slot); } if (asus->hotplug_workqueue) diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 41a364376e91..028b20f82962 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -745,15 +745,8 @@ static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc) if (!eeepc->hotplug_slot) goto error_slot; - eeepc->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info), - GFP_KERNEL); - if (!eeepc->hotplug_slot->info) - goto error_info; - eeepc->hotplug_slot->private = eeepc; eeepc->hotplug_slot->ops = &eeepc_hotplug_slot_ops; - eeepc_get_adapter_status(eeepc->hotplug_slot, - &eeepc->hotplug_slot->info->adapter_status); ret = pci_hp_register(eeepc->hotplug_slot, bus, 0, "eeepc-wifi"); if (ret) { @@ -764,8 +757,6 @@ static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc) return 0; error_register: - kfree(eeepc->hotplug_slot->info); -error_info: kfree(eeepc->hotplug_slot); eeepc->hotplug_slot = NULL; error_slot: @@ -831,7 +822,6 @@ static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc) if (eeepc->hotplug_slot) { pci_hp_deregister(eeepc->hotplug_slot); - kfree(eeepc->hotplug_slot->info); kfree(eeepc->hotplug_slot); } diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h index 372dbe95c207..6f07a4e1de8d 100644 --- a/include/linux/pci_hotplug.h +++ b/include/linux/pci_hotplug.h @@ -23,17 +23,9 @@ * @hardware_test: Called to run a specified hardware test on the specified * slot. * @get_power_status: Called to get the current power status of a slot. - * If this field is NULL, the value passed in the struct hotplug_slot_info - * will be used when this value is requested by a user. * @get_attention_status: Called to get the current attention status of a slot. - * If this field is NULL, the value passed in the struct hotplug_slot_info - * will be used when this value is requested by a user. * @get_latch_status: Called to get the current latch status of a slot. - * If this field is NULL, the value passed in the struct hotplug_slot_info - * will be used when this value is requested by a user. * @get_adapter_status: Called to get see if an adapter is present in the slot or not. - * If this field is NULL, the value passed in the struct hotplug_slot_info - * will be used when this value is requested by a user. * @reset_slot: Optional interface to allow override of a bus reset for the * slot for cases where a secondary bus reset can result in spurious * hotplug events or where a slot can be reset independent of the bus. @@ -55,27 +47,9 @@ struct hotplug_slot_ops { int (*reset_slot) (struct hotplug_slot *slot, int probe); }; -/** - * struct hotplug_slot_info - used to notify the hotplug pci core of the state of the slot - * @power_status: if power is enabled or not (1/0) - * @attention_status: if the attention light is enabled or not (1/0) - * @latch_status: if the latch (if any) is open or closed (1/0) - * @adapter_status: if there is a pci board present in the slot or not (1/0) - * - * Used to notify the hotplug pci core of the status of a specific slot. - */ -struct hotplug_slot_info { - u8 power_status; - u8 attention_status; - u8 latch_status; - u8 adapter_status; -}; - /** * struct hotplug_slot - used to register a physical slot with the hotplug pci core * @ops: pointer to the &struct hotplug_slot_ops to be used for this slot - * @info: pointer to the &struct hotplug_slot_info for the initial values for - * this slot. * @private: used by the hotplug pci controller driver to store whatever it * needs. * @owner: The module owner of this structure @@ -83,7 +57,6 @@ struct hotplug_slot_info { */ struct hotplug_slot { const struct hotplug_slot_ops *ops; - struct hotplug_slot_info *info; void *private; /* Variables below this are for use only by the hotplug pci core. */ @@ -110,9 +83,6 @@ void pci_hp_del(struct hotplug_slot *slot); void pci_hp_destroy(struct hotplug_slot *slot); void pci_hp_deregister(struct hotplug_slot *slot); -int __must_check pci_hp_change_slot_info(struct hotplug_slot *slot, - struct hotplug_slot_info *info); - /* use a define to avoid include chaining to get THIS_MODULE & friends */ #define pci_hp_register(slot, pbus, devnr, name) \ __pci_hp_register(slot, pbus, devnr, name, THIS_MODULE, KBUILD_MODNAME) From patchwork Sun Aug 19 14:29:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Wunner X-Patchwork-Id: 959419 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41tlhp0MBnz9s4s for ; Mon, 20 Aug 2018 04:24:42 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=wunner.de Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 41tlhn6GChzF256 for ; Mon, 20 Aug 2018 04:24:41 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=wunner.de X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=none (mailfrom) smtp.mailfrom=wunner.de (client-ip=83.223.90.233; helo=mailout2.hostsharing.net; envelope-from=lukas@wunner.de; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=wunner.de Received: from mailout2.hostsharing.net (mailout2.hostsharing.net [83.223.90.233]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 41tlgC10YfzF1Rh for ; Mon, 20 Aug 2018 04:23:19 +1000 (AEST) Received: from h08.hostsharing.net (h08.hostsharing.net [83.223.95.28]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "*.hostsharing.net", Issuer "COMODO RSA Domain Validation Secure Server CA" (not verified)) by mailout2.hostsharing.net (Postfix) with ESMTPS id D5A7710189D19; Sun, 19 Aug 2018 16:46:07 +0200 (CEST) Received: from localhost (unknown [89.246.108.87]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by h08.hostsharing.net (Postfix) with ESMTPSA id 4776A609B163; Sun, 19 Aug 2018 16:46:07 +0200 (CEST) X-Mailbox-Line: From 9918fbca94bcfc03d1560b191d138d3e6664cc86 Mon Sep 17 00:00:00 2001 Message-Id: <9918fbca94bcfc03d1560b191d138d3e6664cc86.1534686485.git.lukas@wunner.de> In-Reply-To: References: From: Lukas Wunner Date: Sun, 19 Aug 2018 16:29:00 +0200 Subject: [PATCH 8/9] PCI: hotplug: Embed hotplug_slot To: Bjorn Helgaas , linux-pci@vger.kernel.org, Sinan Kaya , Mika Westerberg X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Scott Murray , linux-s390@vger.kernel.org, Greg Kroah-Hartman , acpi4asus-user@lists.sourceforge.net, "Rafael J. Wysocki" , Gavin Shan , platform-driver-x86@vger.kernel.org, linux-acpi@vger.kernel.org, Paul Mackerras , Sebastian Ott , Corentin Chary , Darren Hart , linuxppc-dev@lists.ozlabs.org, Andy Shevchenko , Gerald Schaefer , Len Brown Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" When the PCI hotplug core and its first user, cpqphp, were introduced in February 2002 with historic commit a8a2069f432c, cpqphp allocated a slot struct for its internal use plus a hotplug_slot struct to be registered with the hotplug core and linked the two with pointers: https://git.kernel.org/tglx/history/c/a8a2069f432c Nowadays, the predominant pattern in the tree is to embed ("subclass") such structures in one another and cast to the containing struct with container_of(). But it wasn't until July 2002 that container_of() was introduced with historic commit ec4f214232cf: https://git.kernel.org/tglx/history/c/ec4f214232cf pnv_php, introduced in 2016, did the right thing and embedded struct hotplug_slot in its internal struct pnv_php_slot, but all other drivers cargo-culted cpqphp's design and linked separate structs with pointers. Embedding structs is preferrable to linking them with pointers because it requires fewer allocations, thereby reducing overhead and simplifying error paths. Casting an embedded struct to the containing struct becomes a cheap subtraction rather than a dereference. And having fewer pointers reduces the risk of them pointing nowhere either accidentally or due to an attack. Convert all drivers to embed struct hotplug_slot in their internal slot struct. The "private" pointer in struct hotplug_slot thereby becomes unused, so drop it. Signed-off-by: Lukas Wunner Cc: Rafael J. Wysocki Cc: Len Brown Cc: Scott Murray Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Michael Ellerman Cc: Gavin Shan Cc: Sebastian Ott Cc: Gerald Schaefer Cc: Corentin Chary Cc: Darren Hart Cc: Andy Shevchenko Reviewed-by: Rafael J. Wysocki Acked-by: Tyrel Datwyler Acked-by: Sebastian Ott --- drivers/pci/hotplug/acpiphp.h | 9 ++- drivers/pci/hotplug/acpiphp_core.c | 28 +++----- drivers/pci/hotplug/acpiphp_ibm.c | 2 +- drivers/pci/hotplug/cpci_hotplug.h | 9 ++- drivers/pci/hotplug/cpci_hotplug_core.c | 37 ++++------ drivers/pci/hotplug/cpci_hotplug_pci.c | 6 +- drivers/pci/hotplug/cpqphp.h | 9 ++- drivers/pci/hotplug/cpqphp_core.c | 37 ++++------ drivers/pci/hotplug/cpqphp_ctrl.c | 2 - drivers/pci/hotplug/ibmphp.h | 7 +- drivers/pci/hotplug/ibmphp_core.c | 92 +++++++++++-------------- drivers/pci/hotplug/ibmphp_ebda.c | 37 +++------- drivers/pci/hotplug/pciehp.h | 11 ++- drivers/pci/hotplug/pciehp_core.c | 37 ++++------ drivers/pci/hotplug/pciehp_ctrl.c | 4 +- drivers/pci/hotplug/pciehp_hpc.c | 8 +-- drivers/pci/hotplug/pnv_php.c | 9 ++- drivers/pci/hotplug/rpaphp.h | 7 +- drivers/pci/hotplug/rpaphp_core.c | 14 ++-- drivers/pci/hotplug/rpaphp_slot.c | 15 ++-- drivers/pci/hotplug/s390_pci_hpc.c | 30 ++++---- drivers/pci/hotplug/sgi_hotplug.c | 52 ++++++-------- drivers/pci/hotplug/shpchp.h | 6 +- drivers/pci/hotplug/shpchp_core.c | 17 ++--- drivers/platform/x86/asus-wmi.c | 26 +++---- drivers/platform/x86/eeepc-laptop.c | 30 ++++---- include/linux/pci_hotplug.h | 3 - 27 files changed, 223 insertions(+), 321 deletions(-) diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index 8377e736ea69..cf3058404f41 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h @@ -33,14 +33,19 @@ struct acpiphp_slot; * struct slot - slot information for each *physical* slot */ struct slot { - struct hotplug_slot *hotplug_slot; + struct hotplug_slot hotplug_slot; struct acpiphp_slot *acpi_slot; unsigned int sun; /* ACPI _SUN (Slot User Number) value */ }; static inline const char *slot_name(struct slot *slot) { - return hotplug_slot_name(slot->hotplug_slot); + return hotplug_slot_name(&slot->hotplug_slot); +} + +static inline struct slot *to_slot(struct hotplug_slot *hotplug_slot) +{ + return container_of(hotplug_slot, struct slot, hotplug_slot); } /* diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index abd4f8d7e16a..c9e2bd40c038 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c @@ -118,7 +118,7 @@ EXPORT_SYMBOL_GPL(acpiphp_unregister_attention); */ static int enable_slot(struct hotplug_slot *hotplug_slot) { - struct slot *slot = hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot)); @@ -135,7 +135,7 @@ static int enable_slot(struct hotplug_slot *hotplug_slot) */ static int disable_slot(struct hotplug_slot *hotplug_slot) { - struct slot *slot = hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot)); @@ -179,7 +179,7 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) */ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) { - struct slot *slot = hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot)); @@ -225,7 +225,7 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) */ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) { - struct slot *slot = hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot)); @@ -245,7 +245,7 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) */ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) { - struct slot *slot = hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot)); @@ -266,12 +266,7 @@ int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot, if (!slot) goto error; - slot->hotplug_slot = kzalloc(sizeof(*slot->hotplug_slot), GFP_KERNEL); - if (!slot->hotplug_slot) - goto error_slot; - - slot->hotplug_slot->private = slot; - slot->hotplug_slot->ops = &acpi_hotplug_slot_ops; + slot->hotplug_slot.ops = &acpi_hotplug_slot_ops; slot->acpi_slot = acpiphp_slot; @@ -279,20 +274,18 @@ int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot, slot->sun = sun; snprintf(name, SLOT_NAME_SIZE, "%u", sun); - retval = pci_hp_register(slot->hotplug_slot, acpiphp_slot->bus, + retval = pci_hp_register(&slot->hotplug_slot, acpiphp_slot->bus, acpiphp_slot->device, name); if (retval == -EBUSY) - goto error_hpslot; + goto error_slot; if (retval) { pr_err("pci_hp_register failed with error %d\n", retval); - goto error_hpslot; + goto error_slot; } pr_info("Slot [%s] registered\n", slot_name(slot)); return 0; -error_hpslot: - kfree(slot->hotplug_slot); error_slot: kfree(slot); error: @@ -306,8 +299,7 @@ void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *acpiphp_slot) pr_info("Slot [%s] unregistered\n", slot_name(slot)); - pci_hp_deregister(slot->hotplug_slot); - kfree(slot->hotplug_slot); + pci_hp_deregister(&slot->hotplug_slot); kfree(slot); } diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index 41713f16ff97..df48b3b03ab4 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c @@ -41,7 +41,7 @@ MODULE_VERSION(DRIVER_VERSION); #define IBM_HARDWARE_ID1 "IBM37D0" #define IBM_HARDWARE_ID2 "IBM37D4" -#define hpslot_to_sun(A) (((struct slot *)((A)->private))->sun) +#define hpslot_to_sun(A) (to_slot(A)->sun) /* union apci_descriptor - allows access to the * various device descriptors that are embedded in the diff --git a/drivers/pci/hotplug/cpci_hotplug.h b/drivers/pci/hotplug/cpci_hotplug.h index 146b06fd12c0..817c84e0b2fe 100644 --- a/drivers/pci/hotplug/cpci_hotplug.h +++ b/drivers/pci/hotplug/cpci_hotplug.h @@ -35,7 +35,7 @@ struct slot { bool latch_status; bool adapter_status; unsigned int extracting; - struct hotplug_slot *hotplug_slot; + struct hotplug_slot hotplug_slot; struct list_head slot_list; }; @@ -60,7 +60,12 @@ struct cpci_hp_controller { static inline const char *slot_name(struct slot *slot) { - return hotplug_slot_name(slot->hotplug_slot); + return hotplug_slot_name(&slot->hotplug_slot); +} + +static inline struct slot *to_slot(struct hotplug_slot *hotplug_slot) +{ + return container_of(hotplug_slot, struct slot, hotplug_slot); } int cpci_hp_register_controller(struct cpci_hp_controller *controller); diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c index a17fb24c28cd..603eadf3d965 100644 --- a/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/drivers/pci/hotplug/cpci_hotplug_core.c @@ -70,7 +70,7 @@ static const struct hotplug_slot_ops cpci_hotplug_slot_ops = { static int enable_slot(struct hotplug_slot *hotplug_slot) { - struct slot *slot = hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); int retval = 0; dbg("%s - physical_slot = %s", __func__, slot_name(slot)); @@ -83,7 +83,7 @@ enable_slot(struct hotplug_slot *hotplug_slot) static int disable_slot(struct hotplug_slot *hotplug_slot) { - struct slot *slot = hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); int retval = 0; dbg("%s - physical_slot = %s", __func__, slot_name(slot)); @@ -139,7 +139,7 @@ cpci_get_power_status(struct slot *slot) static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) { - struct slot *slot = hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); *value = cpci_get_power_status(slot); return 0; @@ -148,7 +148,7 @@ get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) { - struct slot *slot = hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); *value = cpci_get_attention_status(slot); return 0; @@ -157,13 +157,13 @@ get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) { - return cpci_set_attention_status(hotplug_slot->private, status); + return cpci_set_attention_status(to_slot(hotplug_slot), status); } static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) { - struct slot *slot = hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); *value = slot->adapter_status; return 0; @@ -172,7 +172,7 @@ get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) { - struct slot *slot = hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); *value = slot->latch_status; return 0; @@ -180,7 +180,6 @@ get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) static void release_slot(struct slot *slot) { - kfree(slot->hotplug_slot); pci_dev_put(slot->dev); kfree(slot); } @@ -191,7 +190,6 @@ int cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last) { struct slot *slot; - struct hotplug_slot *hotplug_slot; char name[SLOT_NAME_SIZE]; int status; int i; @@ -210,28 +208,19 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last) goto error; } - hotplug_slot = - kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL); - if (!hotplug_slot) { - status = -ENOMEM; - goto error_slot; - } - slot->hotplug_slot = hotplug_slot; - slot->bus = bus; slot->number = i; slot->devfn = PCI_DEVFN(i, 0); snprintf(name, SLOT_NAME_SIZE, "%02x:%02x", bus->number, i); - hotplug_slot->private = slot; - hotplug_slot->ops = &cpci_hotplug_slot_ops; + slot->hotplug_slot.ops = &cpci_hotplug_slot_ops; dbg("registering slot %s", name); - status = pci_hp_register(slot->hotplug_slot, bus, i, name); + status = pci_hp_register(&slot->hotplug_slot, bus, i, name); if (status) { err("pci_hp_register failed with error %d", status); - goto error_hpslot; + goto error_slot; } dbg("slot registered with name: %s", slot_name(slot)); @@ -242,8 +231,6 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last) up_write(&list_rwsem); } return 0; -error_hpslot: - kfree(hotplug_slot); error_slot: kfree(slot); error: @@ -269,7 +256,7 @@ cpci_hp_unregister_bus(struct pci_bus *bus) slots--; dbg("deregistering slot %s", slot_name(slot)); - pci_hp_deregister(slot->hotplug_slot); + pci_hp_deregister(&slot->hotplug_slot); release_slot(slot); } } @@ -571,7 +558,7 @@ cleanup_slots(void) goto cleanup_null; list_for_each_entry_safe(slot, tmp, &slot_list, slot_list) { list_del(&slot->slot_list); - pci_hp_deregister(slot->hotplug_slot); + pci_hp_deregister(&slot->hotplug_slot); release_slot(slot); } cleanup_null: diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index 389b8fb50cd9..2c16adb7f4ec 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c @@ -194,8 +194,7 @@ int cpci_led_on(struct slot *slot) slot->devfn, hs_cap + 2, hs_csr)) { - err("Could not set LOO for slot %s", - hotplug_slot_name(slot->hotplug_slot)); + err("Could not set LOO for slot %s", slot_name(slot)); return -ENODEV; } } @@ -223,8 +222,7 @@ int cpci_led_off(struct slot *slot) slot->devfn, hs_cap + 2, hs_csr)) { - err("Could not clear LOO for slot %s", - hotplug_slot_name(slot->hotplug_slot)); + err("Could not clear LOO for slot %s", slot_name(slot)); return -ENODEV; } } diff --git a/drivers/pci/hotplug/cpqphp.h b/drivers/pci/hotplug/cpqphp.h index db78b394a075..77e4e0142fbc 100644 --- a/drivers/pci/hotplug/cpqphp.h +++ b/drivers/pci/hotplug/cpqphp.h @@ -260,7 +260,7 @@ struct slot { u8 hp_slot; struct controller *ctrl; void __iomem *p_sm_slot; - struct hotplug_slot *hotplug_slot; + struct hotplug_slot hotplug_slot; }; struct pci_resource { @@ -445,7 +445,12 @@ extern u8 cpqhp_disk_irq; static inline const char *slot_name(struct slot *slot) { - return hotplug_slot_name(slot->hotplug_slot); + return hotplug_slot_name(&slot->hotplug_slot); +} + +static inline struct slot *to_slot(struct hotplug_slot *hotplug_slot) +{ + return container_of(hotplug_slot, struct slot, hotplug_slot); } /* diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index bb354a7fc112..95b7d60cf119 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c @@ -275,8 +275,7 @@ static int ctrl_slot_cleanup(struct controller *ctrl) while (old_slot) { next_slot = old_slot->next; - pci_hp_deregister(old_slot->hotplug_slot); - kfree(old_slot->hotplug_slot); + pci_hp_deregister(&old_slot->hotplug_slot); kfree(old_slot); old_slot = next_slot; } @@ -418,7 +417,7 @@ cpqhp_set_attention_status(struct controller *ctrl, struct pci_func *func, static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) { struct pci_func *slot_func; - struct slot *slot = hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); struct controller *ctrl = slot->ctrl; u8 bus; u8 devfn; @@ -445,7 +444,7 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) static int process_SI(struct hotplug_slot *hotplug_slot) { struct pci_func *slot_func; - struct slot *slot = hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); struct controller *ctrl = slot->ctrl; u8 bus; u8 devfn; @@ -477,7 +476,7 @@ static int process_SI(struct hotplug_slot *hotplug_slot) static int process_SS(struct hotplug_slot *hotplug_slot) { struct pci_func *slot_func; - struct slot *slot = hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); struct controller *ctrl = slot->ctrl; u8 bus; u8 devfn; @@ -504,7 +503,7 @@ static int process_SS(struct hotplug_slot *hotplug_slot) static int hardware_test(struct hotplug_slot *hotplug_slot, u32 value) { - struct slot *slot = hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); struct controller *ctrl = slot->ctrl; dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); @@ -515,7 +514,7 @@ static int hardware_test(struct hotplug_slot *hotplug_slot, u32 value) static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) { - struct slot *slot = hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); struct controller *ctrl = slot->ctrl; dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); @@ -526,7 +525,7 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) { - struct slot *slot = hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); struct controller *ctrl = slot->ctrl; dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); @@ -537,7 +536,7 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) { - struct slot *slot = hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); struct controller *ctrl = slot->ctrl; dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); @@ -549,7 +548,7 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) { - struct slot *slot = hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); struct controller *ctrl = slot->ctrl; dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); @@ -577,7 +576,6 @@ static int ctrl_slot_setup(struct controller *ctrl, void __iomem *smbios_table) { struct slot *slot; - struct hotplug_slot *hotplug_slot; struct pci_bus *bus = ctrl->pci_bus; u8 number_of_slots; u8 slot_device; @@ -603,14 +601,6 @@ static int ctrl_slot_setup(struct controller *ctrl, goto error; } - slot->hotplug_slot = kzalloc(sizeof(*(slot->hotplug_slot)), - GFP_KERNEL); - if (!slot->hotplug_slot) { - result = -ENOMEM; - goto error_slot; - } - hotplug_slot = slot->hotplug_slot; - slot->ctrl = ctrl; slot->bus = ctrl->bus; slot->device = slot_device; @@ -659,21 +649,20 @@ static int ctrl_slot_setup(struct controller *ctrl, ((read_slot_enable(ctrl) << 2) >> ctrl_slot) & 0x04; /* register this slot with the hotplug pci core */ - hotplug_slot->private = slot; snprintf(name, SLOT_NAME_SIZE, "%u", slot->number); - hotplug_slot->ops = &cpqphp_hotplug_slot_ops; + slot->hotplug_slot.ops = &cpqphp_hotplug_slot_ops; dbg("registering bus %d, dev %d, number %d, ctrl->slot_device_offset %d, slot %d\n", slot->bus, slot->device, slot->number, ctrl->slot_device_offset, slot_number); - result = pci_hp_register(hotplug_slot, + result = pci_hp_register(&slot->hotplug_slot, ctrl->pci_dev->bus, slot->device, name); if (result) { err("pci_hp_register failed with error %d\n", result); - goto error_hpslot; + goto error_slot; } slot->next = ctrl->slot; @@ -685,8 +674,6 @@ static int ctrl_slot_setup(struct controller *ctrl, } return 0; -error_hpslot: - kfree(hotplug_slot); error_slot: kfree(slot); error: diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c index 9c4826ac6a4f..b7f4e1f099d9 100644 --- a/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/drivers/pci/hotplug/cpqphp_ctrl.c @@ -1130,8 +1130,6 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ for (slot = ctrl->slot; slot; slot = slot->next) { if (slot->device == (hp_slot + ctrl->slot_device_offset)) continue; - if (!slot->hotplug_slot) - continue; if (get_presence_status(ctrl, slot) == 0) continue; /* If another adapter is running on the same segment but at a diff --git a/drivers/pci/hotplug/ibmphp.h b/drivers/pci/hotplug/ibmphp.h index db387e10581e..b89f850c3a4e 100644 --- a/drivers/pci/hotplug/ibmphp.h +++ b/drivers/pci/hotplug/ibmphp.h @@ -698,7 +698,7 @@ struct slot { u8 supported_bus_mode; u8 flag; /* this is for disable slot and polling */ u8 ctlr_index; - struct hotplug_slot *hotplug_slot; + struct hotplug_slot hotplug_slot; struct controller *ctrl; struct pci_func *func; u8 irq[4]; @@ -742,5 +742,10 @@ int ibmphp_configure_card(struct pci_func *, u8); int ibmphp_unconfigure_card(struct slot **, int); extern const struct hotplug_slot_ops ibmphp_hotplug_slot_ops; +static inline struct slot *to_slot(struct hotplug_slot *hotplug_slot) +{ + return container_of(hotplug_slot, struct slot, hotplug_slot); +} + #endif //__IBMPHP_H diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index 96e5b1f544ac..08a58e911fc2 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c @@ -247,11 +247,8 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value) break; } if (rc == 0) { - pslot = hotplug_slot->private; - if (pslot) - rc = ibmphp_hpc_writeslot(pslot, cmd); - else - rc = -ENODEV; + pslot = to_slot(hotplug_slot); + rc = ibmphp_hpc_writeslot(pslot, cmd); } } else rc = -ENODEV; @@ -273,19 +270,15 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) ibmphp_lock_operations(); if (hotplug_slot) { - pslot = hotplug_slot->private; - if (pslot) { - memcpy(&myslot, pslot, sizeof(struct slot)); - rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS, - &(myslot.status)); - if (!rc) - rc = ibmphp_hpc_readslot(pslot, - READ_EXTSLOTSTATUS, - &(myslot.ext_status)); - if (!rc) - *value = SLOT_ATTN(myslot.status, - myslot.ext_status); - } + pslot = to_slot(hotplug_slot); + memcpy(&myslot, pslot, sizeof(struct slot)); + rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS, + &myslot.status); + if (!rc) + rc = ibmphp_hpc_readslot(pslot, READ_EXTSLOTSTATUS, + &myslot.ext_status); + if (!rc) + *value = SLOT_ATTN(myslot.status, myslot.ext_status); } ibmphp_unlock_operations(); @@ -303,14 +296,12 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) (ulong) hotplug_slot, (ulong) value); ibmphp_lock_operations(); if (hotplug_slot) { - pslot = hotplug_slot->private; - if (pslot) { - memcpy(&myslot, pslot, sizeof(struct slot)); - rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS, - &(myslot.status)); - if (!rc) - *value = SLOT_LATCH(myslot.status); - } + pslot = to_slot(hotplug_slot); + memcpy(&myslot, pslot, sizeof(struct slot)); + rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS, + &myslot.status); + if (!rc) + *value = SLOT_LATCH(myslot.status); } ibmphp_unlock_operations(); @@ -330,14 +321,12 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) (ulong) hotplug_slot, (ulong) value); ibmphp_lock_operations(); if (hotplug_slot) { - pslot = hotplug_slot->private; - if (pslot) { - memcpy(&myslot, pslot, sizeof(struct slot)); - rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS, - &(myslot.status)); - if (!rc) - *value = SLOT_PWRGD(myslot.status); - } + pslot = to_slot(hotplug_slot); + memcpy(&myslot, pslot, sizeof(struct slot)); + rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS, + &myslot.status); + if (!rc) + *value = SLOT_PWRGD(myslot.status); } ibmphp_unlock_operations(); @@ -357,18 +346,16 @@ static int get_adapter_present(struct hotplug_slot *hotplug_slot, u8 *value) (ulong) hotplug_slot, (ulong) value); ibmphp_lock_operations(); if (hotplug_slot) { - pslot = hotplug_slot->private; - if (pslot) { - memcpy(&myslot, pslot, sizeof(struct slot)); - rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS, - &(myslot.status)); - if (!rc) { - present = SLOT_PRESENT(myslot.status); - if (present == HPC_SLOT_EMPTY) - *value = 0; - else - *value = 1; - } + pslot = to_slot(hotplug_slot); + memcpy(&myslot, pslot, sizeof(struct slot)); + rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS, + &myslot.status); + if (!rc) { + present = SLOT_PRESENT(myslot.status); + if (present == HPC_SLOT_EMPTY) + *value = 0; + else + *value = 1; } } @@ -382,7 +369,7 @@ static int get_max_bus_speed(struct slot *slot) int rc = 0; u8 mode = 0; enum pci_bus_speed speed; - struct pci_bus *bus = slot->hotplug_slot->pci_slot->bus; + struct pci_bus *bus = slot->hotplug_slot.pci_slot->bus; debug("%s - Entry slot[%p]\n", __func__, slot); @@ -582,7 +569,7 @@ static int validate(struct slot *slot_cur, int opn) ****************************************************************************/ int ibmphp_update_slot_info(struct slot *slot_cur) { - struct pci_bus *bus = slot_cur->hotplug_slot->pci_slot->bus; + struct pci_bus *bus = slot_cur->hotplug_slot.pci_slot->bus; u8 bus_speed; u8 mode; @@ -652,7 +639,7 @@ static void free_slots(void) list_for_each_entry_safe(slot_cur, next, &ibmphp_slot_head, ibm_slot_list) { - pci_hp_del(slot_cur->hotplug_slot); + pci_hp_del(&slot_cur->hotplug_slot); slot_cur->ctrl = NULL; slot_cur->bus_on = NULL; @@ -662,8 +649,7 @@ static void free_slots(void) */ ibmphp_unconfigure_card(&slot_cur, -1); - pci_hp_destroy(slot_cur->hotplug_slot); - kfree(slot_cur->hotplug_slot); + pci_hp_destroy(&slot_cur->hotplug_slot); kfree(slot_cur); } debug("%s -- exit\n", __func__); @@ -985,7 +971,7 @@ static int enable_slot(struct hotplug_slot *hs) ibmphp_lock_operations(); debug("ENABLING SLOT........\n"); - slot_cur = hs->private; + slot_cur = to_slot(hs); rc = validate(slot_cur, ENABLE); if (rc) { @@ -1146,7 +1132,7 @@ static int enable_slot(struct hotplug_slot *hs) **************************************************************/ static int ibmphp_disable_slot(struct hotplug_slot *hotplug_slot) { - struct slot *slot = hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); int rc; ibmphp_lock_operations(); diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c index c05d066ab0d5..11a2661dc062 100644 --- a/drivers/pci/hotplug/ibmphp_ebda.c +++ b/drivers/pci/hotplug/ibmphp_ebda.c @@ -666,10 +666,7 @@ static int fillslotinfo(struct hotplug_slot *hotplug_slot) struct slot *slot; int rc = 0; - if (!hotplug_slot || !hotplug_slot->private) - return -EINVAL; - - slot = hotplug_slot->private; + slot = to_slot(hotplug_slot); rc = ibmphp_hpc_readslot(slot, READ_ALLSTAT, NULL); return rc; } @@ -687,7 +684,6 @@ static int __init ebda_rsrc_controller(void) u8 ctlr_id, temp, bus_index; u16 ctlr, slot, bus; u16 slot_num, bus_num, index; - struct hotplug_slot *hp_slot_ptr; struct controller *hpc_ptr; struct ebda_hpc_bus *bus_ptr; struct ebda_hpc_slot *slot_ptr; @@ -746,7 +742,7 @@ static int __init ebda_rsrc_controller(void) bus_info_ptr1 = kzalloc(sizeof(struct bus_info), GFP_KERNEL); if (!bus_info_ptr1) { rc = -ENOMEM; - goto error_no_hp_slot; + goto error_no_slot; } bus_info_ptr1->slot_min = slot_ptr->slot_num; bus_info_ptr1->slot_max = slot_ptr->slot_num; @@ -817,7 +813,7 @@ static int __init ebda_rsrc_controller(void) (hpc_ptr->u.isa_ctlr.io_end - hpc_ptr->u.isa_ctlr.io_start + 1), "ibmphp")) { rc = -ENODEV; - goto error_no_hp_slot; + goto error_no_slot; } hpc_ptr->irq = readb(io_mem + addr + 4); addr += 5; @@ -832,7 +828,7 @@ static int __init ebda_rsrc_controller(void) break; default: rc = -ENODEV; - goto error_no_hp_slot; + goto error_no_slot; } //reorganize chassis' linked list @@ -845,13 +841,6 @@ static int __init ebda_rsrc_controller(void) // register slots with hpc core as well as create linked list of ibm slot for (index = 0; index < hpc_ptr->slot_count; index++) { - - hp_slot_ptr = kzalloc(sizeof(*hp_slot_ptr), GFP_KERNEL); - if (!hp_slot_ptr) { - rc = -ENOMEM; - goto error_no_hp_slot; - } - tmp_slot = kzalloc(sizeof(*tmp_slot), GFP_KERNEL); if (!tmp_slot) { rc = -ENOMEM; @@ -878,7 +867,6 @@ static int __init ebda_rsrc_controller(void) bus_info_ptr1 = ibmphp_find_same_bus_num(hpc_ptr->slots[index].slot_bus_num); if (!bus_info_ptr1) { - kfree(tmp_slot); rc = -ENODEV; goto error; } @@ -888,22 +876,19 @@ static int __init ebda_rsrc_controller(void) tmp_slot->ctlr_index = hpc_ptr->slots[index].ctl_index; tmp_slot->number = hpc_ptr->slots[index].slot_num; - tmp_slot->hotplug_slot = hp_slot_ptr; - - hp_slot_ptr->private = tmp_slot; - rc = fillslotinfo(hp_slot_ptr); + rc = fillslotinfo(&tmp_slot->hotplug_slot); if (rc) goto error; - rc = ibmphp_init_devno((struct slot **) &hp_slot_ptr->private); + rc = ibmphp_init_devno(&tmp_slot); if (rc) goto error; - hp_slot_ptr->ops = &ibmphp_hotplug_slot_ops; + tmp_slot->hotplug_slot.ops = &ibmphp_hotplug_slot_ops; // end of registering ibm slot with hotplug core - list_add(&((struct slot *)(hp_slot_ptr->private))->ibm_slot_list, &ibmphp_slot_head); + list_add(&tmp_slot->ibm_slot_list, &ibmphp_slot_head); } print_bus_info(); @@ -913,7 +898,7 @@ static int __init ebda_rsrc_controller(void) list_for_each_entry(tmp_slot, &ibmphp_slot_head, ibm_slot_list) { snprintf(name, SLOT_NAME_SIZE, "%s", create_file_name(tmp_slot)); - pci_hp_register(tmp_slot->hotplug_slot, + pci_hp_register(&tmp_slot->hotplug_slot, pci_find_bus(0, tmp_slot->bus), tmp_slot->device, name); } @@ -922,10 +907,8 @@ static int __init ebda_rsrc_controller(void) return 0; error: - kfree(hp_slot_ptr->private); + kfree(tmp_slot); error_no_slot: - kfree(hp_slot_ptr); -error_no_hp_slot: free_ebda_hpc(hpc_ptr); error_no_hpc: iounmap(io_mem); diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index f3c0a376ffd5..b1179d445945 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -88,7 +88,7 @@ do { \ * protects scheduling, execution and cancellation of @button_work * @button_work: work item to turn the slot on or off after 5 seconds * in response to an Attention Button press - * @hotplug_slot: pointer to the structure registered with the PCI hotplug core + * @hotplug_slot: structure registered with the PCI hotplug core * @reset_lock: prevents access to the Data Link Layer Link Active bit in the * Link Status register and to the Presence Detect State bit in the Slot * Status register during a slot reset which may cause them to flap @@ -120,7 +120,7 @@ struct controller { struct mutex state_lock; struct delayed_work button_work; - struct hotplug_slot *hotplug_slot; /* hotplug core interface */ + struct hotplug_slot hotplug_slot; /* hotplug core interface */ struct rw_semaphore reset_lock; int request_result; wait_queue_head_t requester; @@ -206,7 +206,12 @@ int pciehp_get_raw_indicator_status(struct hotplug_slot *h_slot, u8 *status); static inline const char *slot_name(struct controller *ctrl) { - return hotplug_slot_name(ctrl->hotplug_slot); + return hotplug_slot_name(&ctrl->hotplug_slot); +} + +static inline struct controller *to_ctrl(struct hotplug_slot *hotplug_slot) +{ + return container_of(hotplug_slot, struct controller, hotplug_slot); } #endif /* _PCIEHP_H */ diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index dda90030005d..6292ddc0876b 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -51,19 +51,14 @@ static int get_adapter_status(struct hotplug_slot *slot, u8 *value); static int init_slot(struct controller *ctrl) { - struct hotplug_slot *hotplug = NULL; - struct hotplug_slot_ops *ops = NULL; + struct hotplug_slot_ops *ops; char name[SLOT_NAME_SIZE]; - int retval = -ENOMEM; - - hotplug = kzalloc(sizeof(*hotplug), GFP_KERNEL); - if (!hotplug) - goto out; + int retval; /* Setup hotplug slot ops */ ops = kzalloc(sizeof(*ops), GFP_KERNEL); if (!ops) - goto out; + return -ENOMEM; ops->enable_slot = pciehp_sysfs_enable_slot; ops->disable_slot = pciehp_sysfs_disable_slot; @@ -81,30 +76,24 @@ static int init_slot(struct controller *ctrl) } /* register this slot with the hotplug pci core */ - hotplug->private = ctrl; - hotplug->ops = ops; - ctrl->hotplug_slot = hotplug; + ctrl->hotplug_slot.ops = ops; snprintf(name, SLOT_NAME_SIZE, "%u", PSN(ctrl)); - retval = pci_hp_initialize(hotplug, + retval = pci_hp_initialize(&ctrl->hotplug_slot, ctrl->pcie->port->subordinate, 0, name); - if (retval) - ctrl_err(ctrl, "pci_hp_initialize failed: error %d\n", retval); -out: if (retval) { + ctrl_err(ctrl, "pci_hp_initialize failed: error %d\n", retval); kfree(ops); - kfree(hotplug); } return retval; } static void cleanup_slot(struct controller *ctrl) { - struct hotplug_slot *hotplug_slot = ctrl->hotplug_slot; + struct hotplug_slot *hotplug_slot = &ctrl->hotplug_slot; pci_hp_destroy(hotplug_slot); kfree(hotplug_slot->ops); - kfree(hotplug_slot); } /* @@ -112,7 +101,7 @@ static void cleanup_slot(struct controller *ctrl) */ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) { - struct controller *ctrl = hotplug_slot->private; + struct controller *ctrl = to_ctrl(hotplug_slot); struct pci_dev *pdev = ctrl->pcie->port; pci_config_pm_runtime_get(pdev); @@ -123,7 +112,7 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) { - struct controller *ctrl = hotplug_slot->private; + struct controller *ctrl = to_ctrl(hotplug_slot); struct pci_dev *pdev = ctrl->pcie->port; pci_config_pm_runtime_get(pdev); @@ -134,7 +123,7 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) { - struct controller *ctrl = hotplug_slot->private; + struct controller *ctrl = to_ctrl(hotplug_slot); struct pci_dev *pdev = ctrl->pcie->port; pci_config_pm_runtime_get(pdev); @@ -145,7 +134,7 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) { - struct controller *ctrl = hotplug_slot->private; + struct controller *ctrl = to_ctrl(hotplug_slot); struct pci_dev *pdev = ctrl->pcie->port; pci_config_pm_runtime_get(pdev); @@ -223,7 +212,7 @@ static int pciehp_probe(struct pcie_device *dev) } /* Publish to user space */ - rc = pci_hp_add(ctrl->hotplug_slot); + rc = pci_hp_add(&ctrl->hotplug_slot); if (rc) { ctrl_err(ctrl, "Publication to user space failed (%d)\n", rc); goto err_out_shutdown_notification; @@ -246,7 +235,7 @@ static void pciehp_remove(struct pcie_device *dev) { struct controller *ctrl = get_service_data(dev); - pci_hp_del(ctrl->hotplug_slot); + pci_hp_del(&ctrl->hotplug_slot); pcie_shutdown_notification(ctrl); cleanup_slot(ctrl); pciehp_release_ctrl(ctrl); diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 005d88ccbcaa..ba0ae8dae7dc 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c @@ -354,7 +354,7 @@ static int pciehp_disable_slot(struct controller *ctrl, bool safe_removal) int pciehp_sysfs_enable_slot(struct hotplug_slot *hotplug_slot) { - struct controller *ctrl = hotplug_slot->private; + struct controller *ctrl = to_ctrl(hotplug_slot); mutex_lock(&ctrl->state_lock); switch (ctrl->state) { @@ -392,7 +392,7 @@ int pciehp_sysfs_enable_slot(struct hotplug_slot *hotplug_slot) int pciehp_sysfs_disable_slot(struct hotplug_slot *hotplug_slot) { - struct controller *ctrl = hotplug_slot->private; + struct controller *ctrl = to_ctrl(hotplug_slot); mutex_lock(&ctrl->state_lock); switch (ctrl->state) { diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 71ae78732145..6b0b0ed7c565 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -315,7 +315,7 @@ static int pciehp_link_enable(struct controller *ctrl) int pciehp_get_raw_indicator_status(struct hotplug_slot *hotplug_slot, u8 *status) { - struct controller *ctrl = hotplug_slot->private; + struct controller *ctrl = to_ctrl(hotplug_slot); struct pci_dev *pdev = ctrl_dev(ctrl); u16 slot_ctrl; @@ -328,7 +328,7 @@ int pciehp_get_raw_indicator_status(struct hotplug_slot *hotplug_slot, int pciehp_get_attention_status(struct hotplug_slot *hotplug_slot, u8 *status) { - struct controller *ctrl = hotplug_slot->private; + struct controller *ctrl = to_ctrl(hotplug_slot); struct pci_dev *pdev = ctrl_dev(ctrl); u16 slot_ctrl; @@ -408,7 +408,7 @@ int pciehp_query_power_fault(struct controller *ctrl) int pciehp_set_raw_indicator_status(struct hotplug_slot *hotplug_slot, u8 status) { - struct controller *ctrl = hotplug_slot->private; + struct controller *ctrl = to_ctrl(hotplug_slot); struct pci_dev *pdev = ctrl_dev(ctrl); pci_config_pm_runtime_get(pdev); @@ -744,7 +744,7 @@ void pcie_clear_hotplug_events(struct controller *ctrl) */ int pciehp_reset_slot(struct hotplug_slot *hotplug_slot, int probe) { - struct controller *ctrl = hotplug_slot->private; + struct controller *ctrl = to_ctrl(hotplug_slot); struct pci_dev *pdev = ctrl_dev(ctrl); u16 stat_mask = 0, ctrl_mask = 0; int rc; diff --git a/drivers/pci/hotplug/pnv_php.c b/drivers/pci/hotplug/pnv_php.c index 5bb63430262e..5070620a4f9f 100644 --- a/drivers/pci/hotplug/pnv_php.c +++ b/drivers/pci/hotplug/pnv_php.c @@ -336,7 +336,7 @@ static inline struct pnv_php_slot *to_pnv_php_slot(struct hotplug_slot *slot) int pnv_php_set_slot_power_state(struct hotplug_slot *slot, uint8_t state) { - struct pnv_php_slot *php_slot = slot->private; + struct pnv_php_slot *php_slot = to_pnv_php_slot(slot); struct opal_msg msg; int ret; @@ -368,7 +368,7 @@ EXPORT_SYMBOL_GPL(pnv_php_set_slot_power_state); static int pnv_php_get_power_state(struct hotplug_slot *slot, u8 *state) { - struct pnv_php_slot *php_slot = slot->private; + struct pnv_php_slot *php_slot = to_pnv_php_slot(slot); uint8_t power_state = OPAL_PCI_SLOT_POWER_ON; int ret; @@ -390,7 +390,7 @@ static int pnv_php_get_power_state(struct hotplug_slot *slot, u8 *state) static int pnv_php_get_adapter_state(struct hotplug_slot *slot, u8 *state) { - struct pnv_php_slot *php_slot = slot->private; + struct pnv_php_slot *php_slot = to_pnv_php_slot(slot); uint8_t presence = OPAL_PCI_SLOT_EMPTY; int ret; @@ -521,7 +521,7 @@ static int pnv_php_enable_slot(struct hotplug_slot *slot) static int pnv_php_disable_slot(struct hotplug_slot *slot) { - struct pnv_php_slot *php_slot = slot->private; + struct pnv_php_slot *php_slot = to_pnv_php_slot(slot); int ret; if (php_slot->state != PNV_PHP_STATE_POPULATED) @@ -607,7 +607,6 @@ static struct pnv_php_slot *pnv_php_alloc_slot(struct device_node *dn) php_slot->id = id; php_slot->power_state_check = false; php_slot->slot.ops = &php_slot_ops; - php_slot->slot.private = php_slot; INIT_LIST_HEAD(&php_slot->children); INIT_LIST_HEAD(&php_slot->link); diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index 26a3dd731b5e..bdc954d70869 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -68,12 +68,17 @@ struct slot { struct device_node *dn; struct pci_bus *bus; struct list_head *pci_devs; - struct hotplug_slot *hotplug_slot; + struct hotplug_slot hotplug_slot; }; extern const struct hotplug_slot_ops rpaphp_hotplug_slot_ops; extern struct list_head rpaphp_slot_head; +static inline struct slot *to_slot(struct hotplug_slot *hotplug_slot) +{ + return container_of(hotplug_slot, struct slot, hotplug_slot); +} + /* function prototypes */ /* rpaphp_pci.c */ diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index 898e78dcd311..bcd5d357ca23 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -52,7 +52,7 @@ module_param_named(debug, rpaphp_debug, bool, 0644); static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value) { int rc; - struct slot *slot = (struct slot *)hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); switch (value) { case 0: @@ -79,7 +79,7 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value) static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) { int retval, level; - struct slot *slot = (struct slot *)hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); retval = rtas_get_power_level(slot->power_domain, &level); if (!retval) @@ -94,14 +94,14 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) */ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) { - struct slot *slot = (struct slot *)hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); *value = slot->attention_status; return 0; } static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) { - struct slot *slot = (struct slot *)hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); int rc, state; rc = rpaphp_get_sensor_state(slot, &state); @@ -409,7 +409,7 @@ static void __exit cleanup_slots(void) list_for_each_entry_safe(slot, next, &rpaphp_slot_head, rpaphp_slot_list) { list_del(&slot->rpaphp_slot_list); - pci_hp_deregister(slot->hotplug_slot); + pci_hp_deregister(&slot->hotplug_slot); dealloc_slot_struct(slot); } return; @@ -434,7 +434,7 @@ static void __exit rpaphp_exit(void) static int enable_slot(struct hotplug_slot *hotplug_slot) { - struct slot *slot = (struct slot *)hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); int state; int retval; @@ -464,7 +464,7 @@ static int enable_slot(struct hotplug_slot *hotplug_slot) static int disable_slot(struct hotplug_slot *hotplug_slot) { - struct slot *slot = (struct slot *)hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); if (slot->state == NOT_CONFIGURED) return -EINVAL; diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c index 6e2658ce300b..5282aa3e33c5 100644 --- a/drivers/pci/hotplug/rpaphp_slot.c +++ b/drivers/pci/hotplug/rpaphp_slot.c @@ -22,7 +22,6 @@ void dealloc_slot_struct(struct slot *slot) { kfree(slot->name); - kfree(slot->hotplug_slot); kfree(slot); } @@ -34,22 +33,16 @@ struct slot *alloc_slot_struct(struct device_node *dn, slot = kzalloc(sizeof(struct slot), GFP_KERNEL); if (!slot) goto error_nomem; - slot->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL); - if (!slot->hotplug_slot) - goto error_slot; slot->name = kstrdup(drc_name, GFP_KERNEL); if (!slot->name) - goto error_hpslot; + goto error_slot; slot->dn = dn; slot->index = drc_index; slot->power_domain = power_domain; - slot->hotplug_slot->private = slot; - slot->hotplug_slot->ops = &rpaphp_hotplug_slot_ops; + slot->hotplug_slot.ops = &rpaphp_hotplug_slot_ops; return (slot); -error_hpslot: - kfree(slot->hotplug_slot); error_slot: kfree(slot); error_nomem: @@ -70,7 +63,7 @@ static int is_registered(struct slot *slot) int rpaphp_deregister_slot(struct slot *slot) { int retval = 0; - struct hotplug_slot *php_slot = slot->hotplug_slot; + struct hotplug_slot *php_slot = &slot->hotplug_slot; dbg("%s - Entry: deregistering slot=%s\n", __func__, slot->name); @@ -86,7 +79,7 @@ EXPORT_SYMBOL_GPL(rpaphp_deregister_slot); int rpaphp_register_slot(struct slot *slot) { - struct hotplug_slot *php_slot = slot->hotplug_slot; + struct hotplug_slot *php_slot = &slot->hotplug_slot; struct device_node *child; u32 my_index; int retval; diff --git a/drivers/pci/hotplug/s390_pci_hpc.c b/drivers/pci/hotplug/s390_pci_hpc.c index d04634b0defe..30ee72268790 100644 --- a/drivers/pci/hotplug/s390_pci_hpc.c +++ b/drivers/pci/hotplug/s390_pci_hpc.c @@ -32,10 +32,15 @@ static int zpci_fn_configured(enum zpci_state state) */ struct slot { struct list_head slot_list; - struct hotplug_slot *hotplug_slot; + struct hotplug_slot hotplug_slot; struct zpci_dev *zdev; }; +static inline struct slot *to_slot(struct hotplug_slot *hotplug_slot) +{ + return container_of(hotplug_slot, struct slot, hotplug_slot); +} + static inline int slot_configure(struct slot *slot) { int ret = sclp_pci_configure(slot->zdev->fid); @@ -60,7 +65,7 @@ static inline int slot_deconfigure(struct slot *slot) static int enable_slot(struct hotplug_slot *hotplug_slot) { - struct slot *slot = hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); int rc; if (slot->zdev->state != ZPCI_FN_STATE_STANDBY) @@ -88,7 +93,7 @@ static int enable_slot(struct hotplug_slot *hotplug_slot) static int disable_slot(struct hotplug_slot *hotplug_slot) { - struct slot *slot = hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); struct pci_dev *pdev; int rc; @@ -110,7 +115,7 @@ static int disable_slot(struct hotplug_slot *hotplug_slot) static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) { - struct slot *slot = hotplug_slot->private; + struct slot *slot = to_slot(hotplug_slot); switch (slot->zdev->state) { case ZPCI_FN_STATE_STANDBY: @@ -139,7 +144,6 @@ static const struct hotplug_slot_ops s390_hotplug_slot_ops = { int zpci_init_slot(struct zpci_dev *zdev) { - struct hotplug_slot *hotplug_slot; char name[SLOT_NAME_SIZE]; struct slot *slot; int rc; @@ -151,18 +155,11 @@ int zpci_init_slot(struct zpci_dev *zdev) if (!slot) goto error; - hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL); - if (!hotplug_slot) - goto error_hp; - hotplug_slot->private = slot; - - slot->hotplug_slot = hotplug_slot; slot->zdev = zdev; - - hotplug_slot->ops = &s390_hotplug_slot_ops; + slot->hotplug_slot.ops = &s390_hotplug_slot_ops; snprintf(name, SLOT_NAME_SIZE, "%08x", zdev->fid); - rc = pci_hp_register(slot->hotplug_slot, zdev->bus, + rc = pci_hp_register(&slot->hotplug_slot, zdev->bus, ZPCI_DEVFN, name); if (rc) goto error_reg; @@ -171,8 +168,6 @@ int zpci_init_slot(struct zpci_dev *zdev) return 0; error_reg: - kfree(hotplug_slot); -error_hp: kfree(slot); error: return -ENOMEM; @@ -187,8 +182,7 @@ void zpci_exit_slot(struct zpci_dev *zdev) if (slot->zdev != zdev) continue; list_del(&slot->slot_list); - pci_hp_deregister(slot->hotplug_slot); - kfree(slot->hotplug_slot); + pci_hp_deregister(&slot->hotplug_slot); kfree(slot); } } diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index e103826c83e3..231f5bdd3d2d 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c @@ -56,7 +56,7 @@ struct slot { int device_num; struct pci_bus *pci_bus; /* this struct for glue internal only */ - struct hotplug_slot *hotplug_slot; + struct hotplug_slot hotplug_slot; struct list_head hp_list; char physical_path[SN_SLOT_NAME_SIZE]; }; @@ -88,10 +88,15 @@ static const struct hotplug_slot_ops sn_hotplug_slot_ops = { static DEFINE_MUTEX(sn_hotplug_mutex); +static struct slot *to_slot(struct hotplug_slot *bss_hotplug_slot) +{ + return container_of(bss_hotplug_slot, struct slot, hotplug_slot); +} + static ssize_t path_show(struct pci_slot *pci_slot, char *buf) { int retval = -ENOENT; - struct slot *slot = pci_slot->hotplug->private; + struct slot *slot = to_slot(pci_slot->hotplug); if (!slot) return retval; @@ -156,7 +161,7 @@ static int sn_pci_bus_valid(struct pci_bus *pci_bus) return -EIO; } -static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot, +static int sn_hp_slot_private_alloc(struct hotplug_slot **bss_hotplug_slot, struct pci_bus *pci_bus, int device, char *name) { @@ -168,7 +173,6 @@ static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot, slot = kzalloc(sizeof(*slot), GFP_KERNEL); if (!slot) return -ENOMEM; - bss_hotplug_slot->private = slot; slot->device_num = device; slot->pci_bus = pci_bus; @@ -179,8 +183,8 @@ static int sn_hp_slot_private_alloc(struct hotplug_slot *bss_hotplug_slot, sn_generate_path(pci_bus, slot->physical_path); - slot->hotplug_slot = bss_hotplug_slot; list_add(&slot->hp_list, &sn_hp_list); + *bss_hotplug_slot = &slot->hotplug_slot; return 0; } @@ -192,10 +196,9 @@ static struct hotplug_slot *sn_hp_destroy(void) struct hotplug_slot *bss_hotplug_slot = NULL; list_for_each_entry(slot, &sn_hp_list, hp_list) { - bss_hotplug_slot = slot->hotplug_slot; + bss_hotplug_slot = &slot->hotplug_slot; pci_slot = bss_hotplug_slot->pci_slot; - list_del(&((struct slot *)bss_hotplug_slot->private)-> - hp_list); + list_del(&slot->hp_list); sysfs_remove_file(&pci_slot->kobj, &sn_slot_path_attr.attr); break; @@ -227,7 +230,7 @@ static void sn_bus_free_data(struct pci_dev *dev) static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot, int device_num, char **ssdt) { - struct slot *slot = bss_hotplug_slot->private; + struct slot *slot = to_slot(bss_hotplug_slot); struct pcibus_info *pcibus_info; struct pcibr_slot_enable_resp resp; int rc; @@ -267,7 +270,7 @@ static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot, static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot, int device_num, int action) { - struct slot *slot = bss_hotplug_slot->private; + struct slot *slot = to_slot(bss_hotplug_slot); struct pcibus_info *pcibus_info; struct pcibr_slot_disable_resp resp; int rc; @@ -323,7 +326,7 @@ static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot, */ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) { - struct slot *slot = bss_hotplug_slot->private; + struct slot *slot = to_slot(bss_hotplug_slot); struct pci_bus *new_bus = NULL; struct pci_dev *dev; int num_funcs; @@ -469,7 +472,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) static int disable_slot(struct hotplug_slot *bss_hotplug_slot) { - struct slot *slot = bss_hotplug_slot->private; + struct slot *slot = to_slot(bss_hotplug_slot); struct pci_dev *dev, *temp; int rc; acpi_handle ssdt_hdl = NULL; @@ -571,7 +574,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) static inline int get_power_status(struct hotplug_slot *bss_hotplug_slot, u8 *value) { - struct slot *slot = bss_hotplug_slot->private; + struct slot *slot = to_slot(bss_hotplug_slot); struct pcibus_info *pcibus_info; u32 power; @@ -585,8 +588,7 @@ static inline int get_power_status(struct hotplug_slot *bss_hotplug_slot, static void sn_release_slot(struct hotplug_slot *bss_hotplug_slot) { - kfree(bss_hotplug_slot->private); - kfree(bss_hotplug_slot); + kfree(to_slot(bss_hotplug_slot)); } static int sn_hotplug_slot_register(struct pci_bus *pci_bus) @@ -606,14 +608,7 @@ static int sn_hotplug_slot_register(struct pci_bus *pci_bus) if (sn_pci_slot_valid(pci_bus, device) != 1) continue; - bss_hotplug_slot = kzalloc(sizeof(*bss_hotplug_slot), - GFP_KERNEL); - if (!bss_hotplug_slot) { - rc = -ENOMEM; - goto alloc_err; - } - - if (sn_hp_slot_private_alloc(bss_hotplug_slot, + if (sn_hp_slot_private_alloc(&bss_hotplug_slot, pci_bus, device, name)) { rc = -ENOMEM; goto alloc_err; @@ -628,7 +623,7 @@ static int sn_hotplug_slot_register(struct pci_bus *pci_bus) rc = sysfs_create_file(&pci_slot->kobj, &sn_slot_path_attr.attr); if (rc) - goto register_err; + goto alloc_err; } pci_dbg(pci_bus->self, "Registered bus with hotplug\n"); return rc; @@ -637,14 +632,11 @@ static int sn_hotplug_slot_register(struct pci_bus *pci_bus) pci_dbg(pci_bus->self, "bus failed to register with err = %d\n", rc); -alloc_err: - if (rc == -ENOMEM) - pci_dbg(pci_bus->self, "Memory allocation error\n"); - /* destroy THIS element */ - if (bss_hotplug_slot) - sn_release_slot(bss_hotplug_slot); + sn_hp_destroy(); + sn_release_slot(bss_hotplug_slot); +alloc_err: /* destroy anything else on the list */ while ((bss_hotplug_slot = sn_hp_destroy())) { pci_hp_deregister(bss_hotplug_slot); diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index a7bb816e6f25..f7f13ee5d06e 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h @@ -73,7 +73,7 @@ struct slot { u8 pwr_save; struct controller *ctrl; const struct hpc_ops *hpc_ops; - struct hotplug_slot *hotplug_slot; + struct hotplug_slot hotplug_slot; struct list_head slot_list; struct delayed_work work; /* work for button event */ struct mutex lock; @@ -171,7 +171,7 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev); static inline const char *slot_name(struct slot *slot) { - return hotplug_slot_name(slot->hotplug_slot); + return hotplug_slot_name(&slot->hotplug_slot); } struct ctrl_reg { @@ -209,7 +209,7 @@ enum ctrl_offsets { static inline struct slot *get_slot(struct hotplug_slot *hotplug_slot) { - return hotplug_slot->private; + return container_of(hotplug_slot, struct slot, hotplug_slot); } static inline struct slot *shpchp_find_slot(struct controller *ctrl, u8 device) diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index b7181b7e7b98..81a918d47895 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c @@ -76,12 +76,7 @@ static int init_slots(struct controller *ctrl) goto error; } - hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL); - if (!hotplug_slot) { - retval = -ENOMEM; - goto error_slot; - } - slot->hotplug_slot = hotplug_slot; + hotplug_slot = &slot->hotplug_slot; slot->hp_slot = i; slot->ctrl = ctrl; @@ -93,14 +88,13 @@ static int init_slots(struct controller *ctrl) slot->wq = alloc_workqueue("shpchp-%d", 0, 0, slot->number); if (!slot->wq) { retval = -ENOMEM; - goto error_hpslot; + goto error_slot; } mutex_init(&slot->lock); INIT_DELAYED_WORK(&slot->work, shpchp_queue_pushbutton_work); /* register this slot with the hotplug pci core */ - hotplug_slot->private = slot; snprintf(name, SLOT_NAME_SIZE, "%d", slot->number); hotplug_slot->ops = &shpchp_hotplug_slot_ops; @@ -108,7 +102,7 @@ static int init_slots(struct controller *ctrl) pci_domain_nr(ctrl->pci_dev->subordinate), slot->bus, slot->device, slot->hp_slot, slot->number, ctrl->slot_device_offset); - retval = pci_hp_register(slot->hotplug_slot, + retval = pci_hp_register(hotplug_slot, ctrl->pci_dev->subordinate, slot->device, name); if (retval) { ctrl_err(ctrl, "pci_hp_register failed with error %d\n", @@ -127,8 +121,6 @@ static int init_slots(struct controller *ctrl) return 0; error_slotwq: destroy_workqueue(slot->wq); -error_hpslot: - kfree(hotplug_slot); error_slot: kfree(slot); error: @@ -143,8 +135,7 @@ void cleanup_slots(struct controller *ctrl) list_del(&slot->slot_list); cancel_delayed_work(&slot->work); destroy_workqueue(slot->wq); - pci_hp_deregister(slot->hotplug_slot); - kfree(slot->hotplug_slot); + pci_hp_deregister(&slot->hotplug_slot); kfree(slot); } } diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index a2130dd2db3c..5dac33474aea 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -253,7 +253,7 @@ struct asus_wmi { int asus_hwmon_num_fans; int asus_hwmon_pwm; - struct hotplug_slot *hotplug_slot; + struct hotplug_slot hotplug_slot; struct mutex hotplug_lock; struct mutex wmi_lock; struct workqueue_struct *hotplug_workqueue; @@ -743,7 +743,7 @@ static void asus_rfkill_hotplug(struct asus_wmi *asus) if (asus->wlan.rfkill) rfkill_set_sw_state(asus->wlan.rfkill, blocked); - if (asus->hotplug_slot) { + if (asus->hotplug_slot.ops) { bus = pci_find_bus(0, 1); if (!bus) { pr_warn("Unable to find PCI bus 1?\n"); @@ -848,7 +848,8 @@ static void asus_unregister_rfkill_notifier(struct asus_wmi *asus, char *node) static int asus_get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) { - struct asus_wmi *asus = hotplug_slot->private; + struct asus_wmi *asus = container_of(hotplug_slot, + struct asus_wmi, hotplug_slot); int result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN); if (result < 0) @@ -888,14 +889,9 @@ static int asus_setup_pci_hotplug(struct asus_wmi *asus) INIT_WORK(&asus->hotplug_work, asus_hotplug_work); - asus->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL); - if (!asus->hotplug_slot) - goto error_slot; + asus->hotplug_slot.ops = &asus_hotplug_slot_ops; - asus->hotplug_slot->private = asus; - asus->hotplug_slot->ops = &asus_hotplug_slot_ops; - - ret = pci_hp_register(asus->hotplug_slot, bus, 0, "asus-wifi"); + ret = pci_hp_register(&asus->hotplug_slot, bus, 0, "asus-wifi"); if (ret) { pr_err("Unable to register hotplug slot - %d\n", ret); goto error_register; @@ -904,9 +900,7 @@ static int asus_setup_pci_hotplug(struct asus_wmi *asus) return 0; error_register: - kfree(asus->hotplug_slot); - asus->hotplug_slot = NULL; -error_slot: + asus->hotplug_slot.ops = NULL; destroy_workqueue(asus->hotplug_workqueue); error_workqueue: return ret; @@ -1034,10 +1028,8 @@ static void asus_wmi_rfkill_exit(struct asus_wmi *asus) * asus_unregister_rfkill_notifier() */ asus_rfkill_hotplug(asus); - if (asus->hotplug_slot) { - pci_hp_deregister(asus->hotplug_slot); - kfree(asus->hotplug_slot); - } + if (asus->hotplug_slot.ops) + pci_hp_deregister(&asus->hotplug_slot); if (asus->hotplug_workqueue) destroy_workqueue(asus->hotplug_workqueue); diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 028b20f82962..e6946a9beb5a 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -177,7 +177,7 @@ struct eeepc_laptop { struct rfkill *wwan3g_rfkill; struct rfkill *wimax_rfkill; - struct hotplug_slot *hotplug_slot; + struct hotplug_slot hotplug_slot; struct mutex hotplug_lock; struct led_classdev tpd_led; @@ -582,7 +582,7 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle) mutex_lock(&eeepc->hotplug_lock); pci_lock_rescan_remove(); - if (!eeepc->hotplug_slot) + if (!eeepc->hotplug_slot.ops) goto out_unlock; port = acpi_get_pci_dev(handle); @@ -715,8 +715,11 @@ static void eeepc_unregister_rfkill_notifier(struct eeepc_laptop *eeepc, static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) { - struct eeepc_laptop *eeepc = hotplug_slot->private; - int val = get_acpi(eeepc, CM_ASL_WLAN); + struct eeepc_laptop *eeepc; + int val; + + eeepc = container_of(hotplug_slot, struct eeepc_laptop, hotplug_slot); + val = get_acpi(eeepc, CM_ASL_WLAN); if (val == 1 || val == 0) *value = val; @@ -741,14 +744,9 @@ static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc) return -ENODEV; } - eeepc->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL); - if (!eeepc->hotplug_slot) - goto error_slot; + eeepc->hotplug_slot.ops = &eeepc_hotplug_slot_ops; - eeepc->hotplug_slot->private = eeepc; - eeepc->hotplug_slot->ops = &eeepc_hotplug_slot_ops; - - ret = pci_hp_register(eeepc->hotplug_slot, bus, 0, "eeepc-wifi"); + ret = pci_hp_register(&eeepc->hotplug_slot, bus, 0, "eeepc-wifi"); if (ret) { pr_err("Unable to register hotplug slot - %d\n", ret); goto error_register; @@ -757,9 +755,7 @@ static int eeepc_setup_pci_hotplug(struct eeepc_laptop *eeepc) return 0; error_register: - kfree(eeepc->hotplug_slot); - eeepc->hotplug_slot = NULL; -error_slot: + eeepc->hotplug_slot.ops = NULL; return ret; } @@ -820,10 +816,8 @@ static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc) eeepc->wlan_rfkill = NULL; } - if (eeepc->hotplug_slot) { - pci_hp_deregister(eeepc->hotplug_slot); - kfree(eeepc->hotplug_slot); - } + if (eeepc->hotplug_slot.ops) + pci_hp_deregister(&eeepc->hotplug_slot); if (eeepc->bluetooth_rfkill) { rfkill_unregister(eeepc->bluetooth_rfkill); diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h index 6f07a4e1de8d..7acc9f91e72b 100644 --- a/include/linux/pci_hotplug.h +++ b/include/linux/pci_hotplug.h @@ -50,14 +50,11 @@ struct hotplug_slot_ops { /** * struct hotplug_slot - used to register a physical slot with the hotplug pci core * @ops: pointer to the &struct hotplug_slot_ops to be used for this slot - * @private: used by the hotplug pci controller driver to store whatever it - * needs. * @owner: The module owner of this structure * @mod_name: The module name (KBUILD_MODNAME) of this structure */ struct hotplug_slot { const struct hotplug_slot_ops *ops; - void *private; /* Variables below this are for use only by the hotplug pci core. */ struct list_head slot_list;