^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright IBM Corp. 2012
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Author(s):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Jan Glauber <jang@linux.vnet.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #define KMSG_COMPONENT "zpci"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "../../../drivers/pci/pci.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <asm/sclp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define zpci_attr(name, fmt, member) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) static ssize_t name##_show(struct device *dev, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct device_attribute *attr, char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct zpci_dev *zdev = to_zpci(to_pci_dev(dev)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) return sprintf(buf, fmt, zdev->member); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static DEVICE_ATTR_RO(name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) zpci_attr(function_id, "0x%08x\n", fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) zpci_attr(function_handle, "0x%08x\n", fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) zpci_attr(pchid, "0x%04x\n", pchid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) zpci_attr(pfgid, "0x%02x\n", pfgid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) zpci_attr(vfn, "0x%04x\n", vfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) zpci_attr(pft, "0x%02x\n", pft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) zpci_attr(port, "%d\n", port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) zpci_attr(uid, "0x%x\n", uid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) zpci_attr(segment0, "0x%02x\n", pfip[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) zpci_attr(segment1, "0x%02x\n", pfip[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) zpci_attr(segment2, "0x%02x\n", pfip[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) zpci_attr(segment3, "0x%02x\n", pfip[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static ssize_t mio_enabled_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct zpci_dev *zdev = to_zpci(to_pci_dev(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) return sprintf(buf, zpci_use_mio(zdev) ? "1\n" : "0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static DEVICE_ATTR_RO(mio_enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static ssize_t recover_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct kernfs_node *kn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct zpci_dev *zdev = to_zpci(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /* Can't use device_remove_self() here as that would lead us to lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * the pci_rescan_remove_lock while holding the device' kernfs lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * This would create a possible deadlock with disable_slot() which is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * not directly protected by the device' kernfs lock but takes it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * during the device removal which happens under
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * pci_rescan_remove_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * This is analogous to sdev_store_delete() in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * drivers/scsi/scsi_sysfs.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) kn = sysfs_break_active_protection(&dev->kobj, &attr->attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) WARN_ON_ONCE(!kn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* device_remove_file() serializes concurrent calls ignoring all but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) device_remove_file(dev, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* A concurrent call to recover_store() may slip between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * sysfs_break_active_protection() and the sysfs file removal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * Once it unblocks from pci_lock_rescan_remove() the original pdev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * will already be removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) pci_lock_rescan_remove();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (pci_dev_is_added(pdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) pci_stop_and_remove_bus_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) ret = zpci_disable_device(zdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) ret = zpci_enable_device(zdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) pci_rescan_bus(zdev->zbus->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) pci_unlock_rescan_remove();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (kn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) sysfs_unbreak_active_protection(kn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return ret ? ret : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static DEVICE_ATTR_WO(recover);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static ssize_t util_string_read(struct file *filp, struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct bin_attribute *attr, char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) loff_t off, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct device *dev = kobj_to_dev(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct zpci_dev *zdev = to_zpci(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return memory_read_from_buffer(buf, count, &off, zdev->util_str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) sizeof(zdev->util_str));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static BIN_ATTR_RO(util_string, CLP_UTIL_STR_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static ssize_t report_error_write(struct file *filp, struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct bin_attribute *attr, char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) loff_t off, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct zpci_report_error_header *report = (void *) buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct device *dev = kobj_to_dev(kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct pci_dev *pdev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct zpci_dev *zdev = to_zpci(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (off || (count < sizeof(*report)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) ret = sclp_pci_report(report, zdev->fh, zdev->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return ret ? ret : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static BIN_ATTR(report_error, S_IWUSR, NULL, report_error_write, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static struct bin_attribute *zpci_bin_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) &bin_attr_util_string,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) &bin_attr_report_error,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static struct attribute *zpci_dev_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) &dev_attr_function_id.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) &dev_attr_function_handle.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) &dev_attr_pchid.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) &dev_attr_pfgid.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) &dev_attr_pft.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) &dev_attr_port.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) &dev_attr_vfn.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) &dev_attr_uid.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) &dev_attr_recover.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) &dev_attr_mio_enabled.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static struct attribute_group zpci_attr_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) .attrs = zpci_dev_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) .bin_attrs = zpci_bin_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static struct attribute *pfip_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) &dev_attr_segment0.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) &dev_attr_segment1.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) &dev_attr_segment2.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) &dev_attr_segment3.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static struct attribute_group pfip_attr_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) .name = "pfip",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) .attrs = pfip_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) const struct attribute_group *zpci_attr_groups[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) &zpci_attr_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) &pfip_attr_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) };