xref: /linux/arch/s390/pci/pci_sysfs.c (revision 93065d045a99391c60fa9ab8aca6b503f51b2e95)
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