1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Interface for Dynamic Logical Partitioning of I/O Slots on 4 * RPA-compliant PPC64 platform. 5 * 6 * John Rose <johnrose@austin.ibm.com> 7 * October 2003 8 * 9 * Copyright (C) 2003 IBM. 10 */ 11 #include <linux/kobject.h> 12 #include <linux/string.h> 13 #include <linux/pci.h> 14 #include <linux/pci_hotplug.h> 15 #include "rpaphp.h" 16 #include "rpadlpar.h" 17 #include "../pci.h" 18 19 #define DLPAR_KOBJ_NAME "control" 20 21 /* Those two have no quotes because they are passed to __ATTR() which 22 * stringifies the argument (yuck !) 23 */ 24 #define ADD_SLOT_ATTR_NAME add_slot 25 #define REMOVE_SLOT_ATTR_NAME remove_slot 26 27 static ssize_t add_slot_store(struct kobject *kobj, struct kobj_attribute *attr, 28 const char *buf, size_t nbytes) 29 { 30 char drc_name[MAX_DRC_NAME_LEN]; 31 char *end; 32 int rc; 33 34 if (nbytes >= MAX_DRC_NAME_LEN) 35 return 0; 36 37 memcpy(drc_name, buf, nbytes); 38 39 end = strchr(drc_name, '\n'); 40 if (!end) 41 end = &drc_name[nbytes]; 42 *end = '\0'; 43 44 rc = dlpar_add_slot(drc_name); 45 if (rc) 46 return rc; 47 48 return nbytes; 49 } 50 51 static ssize_t add_slot_show(struct kobject *kobj, 52 struct kobj_attribute *attr, char *buf) 53 { 54 return sprintf(buf, "0\n"); 55 } 56 57 static ssize_t remove_slot_store(struct kobject *kobj, 58 struct kobj_attribute *attr, 59 const char *buf, size_t nbytes) 60 { 61 char drc_name[MAX_DRC_NAME_LEN]; 62 int rc; 63 char *end; 64 65 if (nbytes >= MAX_DRC_NAME_LEN) 66 return 0; 67 68 memcpy(drc_name, buf, nbytes); 69 70 end = strchr(drc_name, '\n'); 71 if (!end) 72 end = &drc_name[nbytes]; 73 *end = '\0'; 74 75 rc = dlpar_remove_slot(drc_name); 76 if (rc) 77 return rc; 78 79 return nbytes; 80 } 81 82 static ssize_t remove_slot_show(struct kobject *kobj, 83 struct kobj_attribute *attr, char *buf) 84 { 85 return sprintf(buf, "0\n"); 86 } 87 88 static struct kobj_attribute add_slot_attr = 89 __ATTR(ADD_SLOT_ATTR_NAME, 0644, add_slot_show, add_slot_store); 90 91 static struct kobj_attribute remove_slot_attr = 92 __ATTR(REMOVE_SLOT_ATTR_NAME, 0644, remove_slot_show, remove_slot_store); 93 94 static struct attribute *default_attrs[] = { 95 &add_slot_attr.attr, 96 &remove_slot_attr.attr, 97 NULL, 98 }; 99 100 static const struct attribute_group dlpar_attr_group = { 101 .attrs = default_attrs, 102 }; 103 104 static struct kobject *dlpar_kobj; 105 106 int dlpar_sysfs_init(void) 107 { 108 int error; 109 110 dlpar_kobj = kobject_create_and_add(DLPAR_KOBJ_NAME, 111 &pci_slots_kset->kobj); 112 if (!dlpar_kobj) 113 return -EINVAL; 114 115 error = sysfs_create_group(dlpar_kobj, &dlpar_attr_group); 116 if (error) 117 kobject_put(dlpar_kobj); 118 return error; 119 } 120 121 void dlpar_sysfs_exit(void) 122 { 123 sysfs_remove_group(dlpar_kobj, &dlpar_attr_group); 124 kobject_put(dlpar_kobj); 125 } 126