blob: cf8a12ff733b3883c6b8f32d626e14a47a173f92 [file] [log] [blame]
Jan Glauber1e8da952012-11-29 14:36:55 +01001/*
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
15static ssize_t show_fid(struct device *dev, struct device_attribute *attr,
16 char *buf)
17{
Sebastian Ott92948962013-05-17 16:33:40 +020018 struct zpci_dev *zdev = get_zdev(to_pci_dev(dev));
Jan Glauber1e8da952012-11-29 14:36:55 +010019
Sebastian Ott80b054b2013-06-05 16:08:07 +020020 return sprintf(buf, "0x%08x\n", zdev->fid);
Jan Glauber1e8da952012-11-29 14:36:55 +010021}
22static DEVICE_ATTR(function_id, S_IRUGO, show_fid, NULL);
23
24static ssize_t show_fh(struct device *dev, struct device_attribute *attr,
25 char *buf)
26{
Sebastian Ott92948962013-05-17 16:33:40 +020027 struct zpci_dev *zdev = get_zdev(to_pci_dev(dev));
Jan Glauber1e8da952012-11-29 14:36:55 +010028
Sebastian Ott80b054b2013-06-05 16:08:07 +020029 return sprintf(buf, "0x%08x\n", zdev->fh);
Jan Glauber1e8da952012-11-29 14:36:55 +010030}
31static DEVICE_ATTR(function_handle, S_IRUGO, show_fh, NULL);
32
33static ssize_t show_pchid(struct device *dev, struct device_attribute *attr,
34 char *buf)
35{
Sebastian Ott92948962013-05-17 16:33:40 +020036 struct zpci_dev *zdev = get_zdev(to_pci_dev(dev));
Jan Glauber1e8da952012-11-29 14:36:55 +010037
Sebastian Ott80b054b2013-06-05 16:08:07 +020038 return sprintf(buf, "0x%04x\n", zdev->pchid);
Jan Glauber1e8da952012-11-29 14:36:55 +010039}
40static DEVICE_ATTR(pchid, S_IRUGO, show_pchid, NULL);
41
42static ssize_t show_pfgid(struct device *dev, struct device_attribute *attr,
43 char *buf)
44{
Sebastian Ott92948962013-05-17 16:33:40 +020045 struct zpci_dev *zdev = get_zdev(to_pci_dev(dev));
Jan Glauber1e8da952012-11-29 14:36:55 +010046
Sebastian Ott80b054b2013-06-05 16:08:07 +020047 return sprintf(buf, "0x%02x\n", zdev->pfgid);
Jan Glauber1e8da952012-11-29 14:36:55 +010048}
49static DEVICE_ATTR(pfgid, S_IRUGO, show_pfgid, NULL);
50
Sebastian Ott0ff70ec2013-08-29 19:35:19 +020051static 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
69static 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}
75static DEVICE_ATTR(recover, S_IWUSR, NULL, store_recover);
76
Jan Glauber1e8da952012-11-29 14:36:55 +010077static struct device_attribute *zpci_dev_attrs[] = {
78 &dev_attr_function_id,
79 &dev_attr_function_handle,
80 &dev_attr_pchid,
81 &dev_attr_pfgid,
Sebastian Ott0ff70ec2013-08-29 19:35:19 +020082 &dev_attr_recover,
Jan Glauber1e8da952012-11-29 14:36:55 +010083 NULL,
84};
85
86int 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
97error:
98 while (--i >= 0)
99 device_remove_file(dev, zpci_dev_attrs[i]);
100 return rc;
101}
102
103void 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}