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); 29*ac4995b9SSebastian Ott zpci_attr(vfn, "0x%04x\n", vfn); 30*ac4995b9SSebastian Ott zpci_attr(pft, "0x%02x\n", pft); 31*ac4995b9SSebastian Ott zpci_attr(uid, "0x%x\n", uid); 32*ac4995b9SSebastian Ott zpci_attr(segment0, "0x%02x\n", pfip[0]); 33*ac4995b9SSebastian Ott zpci_attr(segment1, "0x%02x\n", pfip[1]); 34*ac4995b9SSebastian Ott zpci_attr(segment2, "0x%02x\n", pfip[2]); 35*ac4995b9SSebastian Ott zpci_attr(segment3, "0x%02x\n", pfip[3]); 361e8da956SJan Glauber 37b346953dSSebastian Ott static ssize_t recover_store(struct device *dev, struct device_attribute *attr, 380b60f9eaSTejun Heo const char *buf, size_t count) 390ff70ec8SSebastian Ott { 400ff70ec8SSebastian Ott struct pci_dev *pdev = to_pci_dev(dev); 410ff70ec8SSebastian Ott struct zpci_dev *zdev = get_zdev(pdev); 420ff70ec8SSebastian Ott int ret; 430ff70ec8SSebastian Ott 440b60f9eaSTejun Heo if (!device_remove_file_self(dev, attr)) 450b60f9eaSTejun Heo return count; 460b60f9eaSTejun Heo 470ff70ec8SSebastian Ott pci_stop_and_remove_bus_device(pdev); 480ff70ec8SSebastian Ott ret = zpci_disable_device(zdev); 490ff70ec8SSebastian Ott if (ret) 500b60f9eaSTejun Heo return ret; 510ff70ec8SSebastian Ott 520ff70ec8SSebastian Ott ret = zpci_enable_device(zdev); 530ff70ec8SSebastian Ott if (ret) 540b60f9eaSTejun Heo return ret; 550ff70ec8SSebastian Ott 560ff70ec8SSebastian Ott pci_rescan_bus(zdev->bus); 570b60f9eaSTejun Heo return count; 580ff70ec8SSebastian Ott } 59b346953dSSebastian Ott static DEVICE_ATTR_WO(recover); 600ff70ec8SSebastian Ott 61*ac4995b9SSebastian Ott static ssize_t util_string_read(struct file *filp, struct kobject *kobj, 62*ac4995b9SSebastian Ott struct bin_attribute *attr, char *buf, 63*ac4995b9SSebastian Ott loff_t off, size_t count) 64*ac4995b9SSebastian Ott { 65*ac4995b9SSebastian Ott struct device *dev = kobj_to_dev(kobj); 66*ac4995b9SSebastian Ott struct pci_dev *pdev = to_pci_dev(dev); 67*ac4995b9SSebastian Ott struct zpci_dev *zdev = get_zdev(pdev); 68*ac4995b9SSebastian Ott 69*ac4995b9SSebastian Ott return memory_read_from_buffer(buf, count, &off, zdev->util_str, 70*ac4995b9SSebastian Ott sizeof(zdev->util_str)); 71*ac4995b9SSebastian Ott } 72*ac4995b9SSebastian Ott static BIN_ATTR_RO(util_string, CLP_UTIL_STR_LEN); 73*ac4995b9SSebastian Ott static struct bin_attribute *zpci_bin_attrs[] = { 74*ac4995b9SSebastian Ott &bin_attr_util_string, 75*ac4995b9SSebastian Ott NULL, 76*ac4995b9SSebastian Ott }; 77*ac4995b9SSebastian Ott 7893065d04SSebastian Ott static struct attribute *zpci_dev_attrs[] = { 7993065d04SSebastian Ott &dev_attr_function_id.attr, 8093065d04SSebastian Ott &dev_attr_function_handle.attr, 8193065d04SSebastian Ott &dev_attr_pchid.attr, 8293065d04SSebastian Ott &dev_attr_pfgid.attr, 83*ac4995b9SSebastian Ott &dev_attr_pft.attr, 84*ac4995b9SSebastian Ott &dev_attr_vfn.attr, 85*ac4995b9SSebastian Ott &dev_attr_uid.attr, 8693065d04SSebastian Ott &dev_attr_recover.attr, 871e8da956SJan Glauber NULL, 881e8da956SJan Glauber }; 8993065d04SSebastian Ott static struct attribute_group zpci_attr_group = { 9093065d04SSebastian Ott .attrs = zpci_dev_attrs, 91*ac4995b9SSebastian Ott .bin_attrs = zpci_bin_attrs, 9293065d04SSebastian Ott }; 93*ac4995b9SSebastian Ott 94*ac4995b9SSebastian Ott static struct attribute *pfip_attrs[] = { 95*ac4995b9SSebastian Ott &dev_attr_segment0.attr, 96*ac4995b9SSebastian Ott &dev_attr_segment1.attr, 97*ac4995b9SSebastian Ott &dev_attr_segment2.attr, 98*ac4995b9SSebastian Ott &dev_attr_segment3.attr, 99*ac4995b9SSebastian Ott NULL, 100*ac4995b9SSebastian Ott }; 101*ac4995b9SSebastian Ott static struct attribute_group pfip_attr_group = { 102*ac4995b9SSebastian Ott .name = "pfip", 103*ac4995b9SSebastian Ott .attrs = pfip_attrs, 104*ac4995b9SSebastian Ott }; 105*ac4995b9SSebastian Ott 10693065d04SSebastian Ott const struct attribute_group *zpci_attr_groups[] = { 10793065d04SSebastian Ott &zpci_attr_group, 108*ac4995b9SSebastian Ott &pfip_attr_group, 10993065d04SSebastian Ott NULL, 11093065d04SSebastian Ott }; 111