1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * PCI Hot Plug Controller Driver for System z 4 * 5 * Copyright 2012 IBM Corp. 6 * 7 * Author(s): 8 * Jan Glauber <jang@linux.vnet.ibm.com> 9 */ 10 11 #define KMSG_COMPONENT "zpci" 12 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 13 14 #include <linux/kernel.h> 15 #include <linux/slab.h> 16 #include <linux/pci.h> 17 #include <linux/pci_hotplug.h> 18 #include <asm/pci_debug.h> 19 #include <asm/sclp.h> 20 21 #define SLOT_NAME_SIZE 10 22 23 static int enable_slot(struct hotplug_slot *hotplug_slot) 24 { 25 struct zpci_dev *zdev = container_of(hotplug_slot, struct zpci_dev, 26 hotplug_slot); 27 int rc; 28 29 mutex_lock(&zdev->state_lock); 30 if (zdev->state != ZPCI_FN_STATE_STANDBY) { 31 rc = -EIO; 32 goto out; 33 } 34 35 rc = sclp_pci_configure(zdev->fid); 36 zpci_dbg(3, "conf fid:%x, rc:%d\n", zdev->fid, rc); 37 if (rc) 38 goto out; 39 zdev->state = ZPCI_FN_STATE_CONFIGURED; 40 41 rc = zpci_scan_configured_device(zdev, zdev->fh); 42 out: 43 mutex_unlock(&zdev->state_lock); 44 return rc; 45 } 46 47 static int disable_slot(struct hotplug_slot *hotplug_slot) 48 { 49 struct zpci_dev *zdev = container_of(hotplug_slot, struct zpci_dev, 50 hotplug_slot); 51 struct pci_dev *pdev = NULL; 52 int rc; 53 54 mutex_lock(&zdev->state_lock); 55 if (zdev->state != ZPCI_FN_STATE_CONFIGURED) { 56 rc = -EIO; 57 goto out; 58 } 59 60 pdev = pci_get_slot(zdev->zbus->bus, zdev->devfn); 61 if (pdev && pci_num_vf(pdev)) { 62 pci_dev_put(pdev); 63 rc = -EBUSY; 64 goto out; 65 } 66 67 rc = zpci_deconfigure_device(zdev); 68 out: 69 mutex_unlock(&zdev->state_lock); 70 if (pdev) 71 pci_dev_put(pdev); 72 return rc; 73 } 74 75 static int reset_slot(struct hotplug_slot *hotplug_slot, bool probe) 76 { 77 struct zpci_dev *zdev = container_of(hotplug_slot, struct zpci_dev, 78 hotplug_slot); 79 int rc = -EIO; 80 81 /* 82 * If we can't get the zdev->state_lock the device state is 83 * currently undergoing a transition and we bail out - just 84 * the same as if the device's state is not configured at all. 85 */ 86 if (!mutex_trylock(&zdev->state_lock)) 87 return rc; 88 89 /* We can reset only if the function is configured */ 90 if (zdev->state != ZPCI_FN_STATE_CONFIGURED) 91 goto out; 92 93 if (probe) { 94 rc = 0; 95 goto out; 96 } 97 98 rc = zpci_hot_reset_device(zdev); 99 out: 100 mutex_unlock(&zdev->state_lock); 101 return rc; 102 } 103 104 static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) 105 { 106 struct zpci_dev *zdev = container_of(hotplug_slot, struct zpci_dev, 107 hotplug_slot); 108 109 *value = zpci_is_device_configured(zdev) ? 1 : 0; 110 return 0; 111 } 112 113 static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) 114 { 115 /* if the slot exits it always contains a function */ 116 *value = 1; 117 return 0; 118 } 119 120 static const struct hotplug_slot_ops s390_hotplug_slot_ops = { 121 .enable_slot = enable_slot, 122 .disable_slot = disable_slot, 123 .reset_slot = reset_slot, 124 .get_power_status = get_power_status, 125 .get_adapter_status = get_adapter_status, 126 }; 127 128 int zpci_init_slot(struct zpci_dev *zdev) 129 { 130 char name[SLOT_NAME_SIZE]; 131 struct zpci_bus *zbus = zdev->zbus; 132 133 zdev->hotplug_slot.ops = &s390_hotplug_slot_ops; 134 135 snprintf(name, SLOT_NAME_SIZE, "%08x", zdev->fid); 136 return pci_hp_register(&zdev->hotplug_slot, zbus->bus, 137 zdev->devfn, name); 138 } 139 140 void zpci_exit_slot(struct zpci_dev *zdev) 141 { 142 pci_hp_deregister(&zdev->hotplug_slot); 143 } 144