11e8da956SJan Glauber /* 21e8da956SJan Glauber * Copyright IBM Corp. 2012 31e8da956SJan Glauber * 41e8da956SJan Glauber * Author(s): 51e8da956SJan Glauber * Jan Glauber <jang@linux.vnet.ibm.com> 61e8da956SJan Glauber */ 71e8da956SJan Glauber 81e8da956SJan Glauber #define COMPONENT "zPCI" 91e8da956SJan Glauber #define pr_fmt(fmt) COMPONENT ": " fmt 101e8da956SJan Glauber 111e8da956SJan Glauber #include <linux/kernel.h> 121e8da956SJan Glauber #include <linux/stat.h> 131e8da956SJan Glauber #include <linux/pci.h> 141e8da956SJan Glauber 15b346953dSSebastian Ott #define zpci_attr(name, fmt, member) \ 16b346953dSSebastian Ott static ssize_t name##_show(struct device *dev, \ 17b346953dSSebastian Ott struct device_attribute *attr, char *buf) \ 18b346953dSSebastian Ott { \ 19b346953dSSebastian Ott struct zpci_dev *zdev = get_zdev(to_pci_dev(dev)); \ 20b346953dSSebastian Ott \ 21b346953dSSebastian Ott return sprintf(buf, fmt, zdev->member); \ 22b346953dSSebastian Ott } \ 23b346953dSSebastian Ott static DEVICE_ATTR_RO(name) 241e8da956SJan Glauber 25b346953dSSebastian Ott zpci_attr(function_id, "0x%08x\n", fid); 26b346953dSSebastian Ott zpci_attr(function_handle, "0x%08x\n", fh); 27b346953dSSebastian Ott zpci_attr(pchid, "0x%04x\n", pchid); 28b346953dSSebastian Ott zpci_attr(pfgid, "0x%02x\n", pfgid); 291e8da956SJan Glauber 30b346953dSSebastian Ott static ssize_t recover_store(struct device *dev, struct device_attribute *attr, 310b60f9eaSTejun Heo const char *buf, size_t count) 320ff70ec8SSebastian Ott { 330ff70ec8SSebastian Ott struct pci_dev *pdev = to_pci_dev(dev); 340ff70ec8SSebastian Ott struct zpci_dev *zdev = get_zdev(pdev); 350ff70ec8SSebastian Ott int ret; 360ff70ec8SSebastian Ott 370b60f9eaSTejun Heo if (!device_remove_file_self(dev, attr)) 380b60f9eaSTejun Heo return count; 390b60f9eaSTejun Heo 400ff70ec8SSebastian Ott pci_stop_and_remove_bus_device(pdev); 410ff70ec8SSebastian Ott ret = zpci_disable_device(zdev); 420ff70ec8SSebastian Ott if (ret) 430b60f9eaSTejun Heo return ret; 440ff70ec8SSebastian Ott 450ff70ec8SSebastian Ott ret = zpci_enable_device(zdev); 460ff70ec8SSebastian Ott if (ret) 470b60f9eaSTejun Heo return ret; 480ff70ec8SSebastian Ott 490ff70ec8SSebastian Ott pci_rescan_bus(zdev->bus); 500b60f9eaSTejun Heo return count; 510ff70ec8SSebastian Ott } 52b346953dSSebastian Ott static DEVICE_ATTR_WO(recover); 530ff70ec8SSebastian Ott 54*93065d04SSebastian Ott static struct attribute *zpci_dev_attrs[] = { 55*93065d04SSebastian Ott &dev_attr_function_id.attr, 56*93065d04SSebastian Ott &dev_attr_function_handle.attr, 57*93065d04SSebastian Ott &dev_attr_pchid.attr, 58*93065d04SSebastian Ott &dev_attr_pfgid.attr, 59*93065d04SSebastian Ott &dev_attr_recover.attr, 601e8da956SJan Glauber NULL, 611e8da956SJan Glauber }; 62*93065d04SSebastian Ott static struct attribute_group zpci_attr_group = { 63*93065d04SSebastian Ott .attrs = zpci_dev_attrs, 64*93065d04SSebastian Ott }; 65*93065d04SSebastian Ott const struct attribute_group *zpci_attr_groups[] = { 66*93065d04SSebastian Ott &zpci_attr_group, 67*93065d04SSebastian Ott NULL, 68*93065d04SSebastian Ott }; 69