s390/pci: embedding hotplug_slot in zdev
authorPierre Morel <pmorel@linux.ibm.com>
Mon, 10 Feb 2020 16:53:25 +0000 (17:53 +0100)
committerVasily Gorbik <gor@linux.ibm.com>
Tue, 10 Mar 2020 14:16:25 +0000 (15:16 +0100)
Embedding the hotplug_slot in zdev structure allows to
greatly simplify the hotplug handling by eliminating
the handling of the slot_list.

Signed-off-by: Pierre Morel <pmorel@linux.ibm.com>
Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
arch/s390/include/asm/pci.h
drivers/pci/hotplug/s390_pci_hpc.c

index b05187c..73b69a7 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/pci.h>
 #include <linux/mutex.h>
 #include <linux/iommu.h>
+#include <linux/pci_hotplug.h>
 #include <asm-generic/pci.h>
 #include <asm/pci_clp.h>
 #include <asm/pci_debug.h>
@@ -96,6 +97,7 @@ struct s390_domain;
 struct zpci_dev {
        struct pci_bus  *bus;
        struct list_head entry;         /* list of all zpci_devices, needed for hotplug, etc. */
+       struct hotplug_slot hotplug_slot;
 
        enum zpci_state state;
        u32             fid;            /* function ID, used by sclp */
index 30ee722..39295d8 100644 (file)
@@ -19,7 +19,6 @@
 #include <asm/sclp.h>
 
 #define SLOT_NAME_SIZE 10
-static LIST_HEAD(s390_hotplug_slot_list);
 
 static int zpci_fn_configured(enum zpci_state state)
 {
@@ -27,97 +26,86 @@ static int zpci_fn_configured(enum zpci_state state)
               state == ZPCI_FN_STATE_ONLINE;
 }
 
-/*
- * struct slot - slot information for each *physical* slot
- */
-struct slot {
-       struct list_head slot_list;
-       struct hotplug_slot hotplug_slot;
-       struct zpci_dev *zdev;
-};
-
-static inline struct slot *to_slot(struct hotplug_slot *hotplug_slot)
+static inline int zdev_configure(struct zpci_dev *zdev)
 {
-       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);
+       int ret = sclp_pci_configure(zdev->fid);
 
-       zpci_dbg(3, "conf fid:%x, rc:%d\n", slot->zdev->fid, ret);
+       zpci_dbg(3, "conf fid:%x, rc:%d\n", zdev->fid, ret);
        if (!ret)
-               slot->zdev->state = ZPCI_FN_STATE_CONFIGURED;
+               zdev->state = ZPCI_FN_STATE_CONFIGURED;
 
        return ret;
 }
 
-static inline int slot_deconfigure(struct slot *slot)
+static inline int zdev_deconfigure(struct zpci_dev *zdev)
 {
-       int ret = sclp_pci_deconfigure(slot->zdev->fid);
+       int ret = sclp_pci_deconfigure(zdev->fid);
 
-       zpci_dbg(3, "deconf fid:%x, rc:%d\n", slot->zdev->fid, ret);
+       zpci_dbg(3, "deconf fid:%x, rc:%d\n", zdev->fid, ret);
        if (!ret)
-               slot->zdev->state = ZPCI_FN_STATE_STANDBY;
+               zdev->state = ZPCI_FN_STATE_STANDBY;
 
        return ret;
 }
 
 static int enable_slot(struct hotplug_slot *hotplug_slot)
 {
-       struct slot *slot = to_slot(hotplug_slot);
+       struct zpci_dev *zdev = container_of(hotplug_slot, struct zpci_dev,
+                                            hotplug_slot);
        int rc;
 
-       if (slot->zdev->state != ZPCI_FN_STATE_STANDBY)
+       if (zdev->state != ZPCI_FN_STATE_STANDBY)
                return -EIO;
 
-       rc = slot_configure(slot);
+       rc = zdev_configure(zdev);
        if (rc)
                return rc;
 
-       rc = zpci_enable_device(slot->zdev);
+       rc = zpci_enable_device(zdev);
        if (rc)
                goto out_deconfigure;
 
-       pci_scan_slot(slot->zdev->bus, ZPCI_DEVFN);
+       pci_scan_slot(zdev->bus, ZPCI_DEVFN);
        pci_lock_rescan_remove();
-       pci_bus_add_devices(slot->zdev->bus);
+       pci_bus_add_devices(zdev->bus);
        pci_unlock_rescan_remove();
 
        return rc;
 
 out_deconfigure:
-       slot_deconfigure(slot);
+       zdev_deconfigure(zdev);
        return rc;
 }
 
 static int disable_slot(struct hotplug_slot *hotplug_slot)
 {
-       struct slot *slot = to_slot(hotplug_slot);
+       struct zpci_dev *zdev = container_of(hotplug_slot, struct zpci_dev,
+                                            hotplug_slot);
        struct pci_dev *pdev;
        int rc;
 
-       if (!zpci_fn_configured(slot->zdev->state))
+       if (!zpci_fn_configured(zdev->state))
                return -EIO;
 
-       pdev = pci_get_slot(slot->zdev->bus, ZPCI_DEVFN);
+       pdev = pci_get_slot(zdev->bus, ZPCI_DEVFN);
        if (pdev) {
                pci_stop_and_remove_bus_device_locked(pdev);
                pci_dev_put(pdev);
        }
 
-       rc = zpci_disable_device(slot->zdev);
+       rc = zpci_disable_device(zdev);
        if (rc)
                return rc;
 
-       return slot_deconfigure(slot);
+       return zdev_deconfigure(zdev);
 }
 
 static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
 {
-       struct slot *slot = to_slot(hotplug_slot);
+       struct zpci_dev *zdev = container_of(hotplug_slot, struct zpci_dev,
+                                            hotplug_slot);
 
-       switch (slot->zdev->state) {
+       switch (zdev->state) {
        case ZPCI_FN_STATE_STANDBY:
                *value = 0;
                break;
@@ -145,44 +133,15 @@ static const struct hotplug_slot_ops s390_hotplug_slot_ops = {
 int zpci_init_slot(struct zpci_dev *zdev)
 {
        char name[SLOT_NAME_SIZE];
-       struct slot *slot;
-       int rc;
 
-       if (!zdev)
-               return 0;
-
-       slot = kzalloc(sizeof(*slot), GFP_KERNEL);
-       if (!slot)
-               goto error;
-
-       slot->zdev = zdev;
-       slot->hotplug_slot.ops = &s390_hotplug_slot_ops;
+       zdev->hotplug_slot.ops = &s390_hotplug_slot_ops;
 
        snprintf(name, SLOT_NAME_SIZE, "%08x", zdev->fid);
-       rc = pci_hp_register(&slot->hotplug_slot, zdev->bus,
-                            ZPCI_DEVFN, name);
-       if (rc)
-               goto error_reg;
-
-       list_add(&slot->slot_list, &s390_hotplug_slot_list);
-       return 0;
-
-error_reg:
-       kfree(slot);
-error:
-       return -ENOMEM;
+       return pci_hp_register(&zdev->hotplug_slot, zdev->bus,
+                              ZPCI_DEVFN, name);
 }
 
 void zpci_exit_slot(struct zpci_dev *zdev)
 {
-       struct slot *slot, *next;
-
-       list_for_each_entry_safe(slot, next, &s390_hotplug_slot_list,
-                                slot_list) {
-               if (slot->zdev != zdev)
-                       continue;
-               list_del(&slot->slot_list);
-               pci_hp_deregister(&slot->hotplug_slot);
-               kfree(slot);
-       }
+       pci_hp_deregister(&zdev->hotplug_slot);
 }