static ssize_t recover_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct pci_dev *pdev = to_pci_dev(dev); struct zpci_dev *zdev = to_zpci(pdev); int ret; if (!device_remove_file_self(dev, attr)) return count; pci_lock_rescan_remove(); pci_stop_and_remove_bus_device(pdev); ret = zpci_disable_device(zdev); if (ret) goto error; ret = zpci_enable_device(zdev); if (ret) goto error; pci_rescan_bus(zdev->bus); pci_unlock_rescan_remove(); return count; error: pci_unlock_rescan_remove(); return ret; }
static ssize_t ccwgroup_ungroup_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct ccwgroup_device *gdev = to_ccwgroupdev(dev); int rc; /* Prevent concurrent online/offline processing and ungrouping. */ if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0) return -EAGAIN; if (gdev->state != CCWGROUP_OFFLINE) { rc = -EINVAL; goto out; } if (device_remove_file_self(dev, attr)) ccwgroup_ungroup(gdev); out: if (rc) { if (rc != -EAGAIN) /* Release onoff "lock" when ungrouping failed. */ atomic_set(&gdev->onoff, 0); return rc; } return count; }