xref: /openbmc/linux/arch/s390/pci/pci_sysfs.c (revision f677b30b487ca3763c3de3f1b4d8c976c2961cd1)
1 /*
2  * Copyright IBM Corp. 2012
3  *
4  * Author(s):
5  *   Jan Glauber <jang@linux.vnet.ibm.com>
6  */
7 
8 #define COMPONENT "zPCI"
9 #define pr_fmt(fmt) COMPONENT ": " fmt
10 
11 #include <linux/kernel.h>
12 #include <linux/stat.h>
13 #include <linux/pci.h>
14 
15 static ssize_t show_fid(struct device *dev, struct device_attribute *attr,
16 			char *buf)
17 {
18 	struct zpci_dev *zdev = get_zdev(to_pci_dev(dev));
19 
20 	return sprintf(buf, "0x%08x\n", zdev->fid);
21 }
22 static DEVICE_ATTR(function_id, S_IRUGO, show_fid, NULL);
23 
24 static ssize_t show_fh(struct device *dev, struct device_attribute *attr,
25 		       char *buf)
26 {
27 	struct zpci_dev *zdev = get_zdev(to_pci_dev(dev));
28 
29 	return sprintf(buf, "0x%08x\n", zdev->fh);
30 }
31 static DEVICE_ATTR(function_handle, S_IRUGO, show_fh, NULL);
32 
33 static ssize_t show_pchid(struct device *dev, struct device_attribute *attr,
34 			  char *buf)
35 {
36 	struct zpci_dev *zdev = get_zdev(to_pci_dev(dev));
37 
38 	return sprintf(buf, "0x%04x\n", zdev->pchid);
39 }
40 static DEVICE_ATTR(pchid, S_IRUGO, show_pchid, NULL);
41 
42 static ssize_t show_pfgid(struct device *dev, struct device_attribute *attr,
43 			  char *buf)
44 {
45 	struct zpci_dev *zdev = get_zdev(to_pci_dev(dev));
46 
47 	return sprintf(buf, "0x%02x\n", zdev->pfgid);
48 }
49 static DEVICE_ATTR(pfgid, S_IRUGO, show_pfgid, NULL);
50 
51 static void recover_callback(struct device *dev)
52 {
53 	struct pci_dev *pdev = to_pci_dev(dev);
54 	struct zpci_dev *zdev = get_zdev(pdev);
55 	int ret;
56 
57 	pci_stop_and_remove_bus_device(pdev);
58 	ret = zpci_disable_device(zdev);
59 	if (ret)
60 		return;
61 
62 	ret = zpci_enable_device(zdev);
63 	if (ret)
64 		return;
65 
66 	pci_rescan_bus(zdev->bus);
67 }
68 
69 static ssize_t store_recover(struct device *dev, struct device_attribute *attr,
70 			     const char *buf, size_t count)
71 {
72 	int rc = device_schedule_callback(dev, recover_callback);
73 	return rc ? rc : count;
74 }
75 static DEVICE_ATTR(recover, S_IWUSR, NULL, store_recover);
76 
77 static struct device_attribute *zpci_dev_attrs[] = {
78 	&dev_attr_function_id,
79 	&dev_attr_function_handle,
80 	&dev_attr_pchid,
81 	&dev_attr_pfgid,
82 	&dev_attr_recover,
83 	NULL,
84 };
85 
86 int zpci_sysfs_add_device(struct device *dev)
87 {
88 	int i, rc = 0;
89 
90 	for (i = 0; zpci_dev_attrs[i]; i++) {
91 		rc = device_create_file(dev, zpci_dev_attrs[i]);
92 		if (rc)
93 			goto error;
94 	}
95 	return 0;
96 
97 error:
98 	while (--i >= 0)
99 		device_remove_file(dev, zpci_dev_attrs[i]);
100 	return rc;
101 }
102 
103 void zpci_sysfs_remove_device(struct device *dev)
104 {
105 	int i;
106 
107 	for (i = 0; zpci_dev_attrs[i]; i++)
108 		device_remove_file(dev, zpci_dev_attrs[i]);
109 }
110