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