1
2
3
4
5
6
7
8#include <linux/kobject.h>
9#include <linux/slab.h>
10#include <linux/module.h>
11#include <linux/pci.h>
12#include <linux/err.h>
13#include "pci.h"
14
15struct kset *pci_slots_kset;
16EXPORT_SYMBOL_GPL(pci_slots_kset);
17static DEFINE_MUTEX(pci_slot_mutex);
18
19static ssize_t pci_slot_attr_show(struct kobject *kobj,
20 struct attribute *attr, char *buf)
21{
22 struct pci_slot *slot = to_pci_slot(kobj);
23 struct pci_slot_attribute *attribute = to_pci_slot_attr(attr);
24 return attribute->show ? attribute->show(slot, buf) : -EIO;
25}
26
27static ssize_t pci_slot_attr_store(struct kobject *kobj,
28 struct attribute *attr, const char *buf, size_t len)
29{
30 struct pci_slot *slot = to_pci_slot(kobj);
31 struct pci_slot_attribute *attribute = to_pci_slot_attr(attr);
32 return attribute->store ? attribute->store(slot, buf, len) : -EIO;
33}
34
35static const struct sysfs_ops pci_slot_sysfs_ops = {
36 .show = pci_slot_attr_show,
37 .store = pci_slot_attr_store,
38};
39
40static ssize_t address_read_file(struct pci_slot *slot, char *buf)
41{
42 if (slot->number == 0xff)
43 return sprintf(buf, "%04x:%02x\n",
44 pci_domain_nr(slot->bus),
45 slot->bus->number);
46 else
47 return sprintf(buf, "%04x:%02x:%02x\n",
48 pci_domain_nr(slot->bus),
49 slot->bus->number,
50 slot->number);
51}
52
53
54static const char *pci_bus_speed_strings[] = {
55 "33 MHz PCI",
56 "66 MHz PCI",
57 "66 MHz PCI-X",
58 "100 MHz PCI-X",
59 "133 MHz PCI-X",
60 NULL,
61 NULL,
62 NULL,
63 NULL,
64 "66 MHz PCI-X 266",
65 "100 MHz PCI-X 266",
66 "133 MHz PCI-X 266",
67 "Unknown AGP",
68 "1x AGP",
69 "2x AGP",
70 "4x AGP",
71 "8x AGP",
72 "66 MHz PCI-X 533",
73 "100 MHz PCI-X 533",
74 "133 MHz PCI-X 533",
75 "2.5 GT/s PCIe",
76 "5.0 GT/s PCIe",
77 "8.0 GT/s PCIe",
78 "16.0 GT/s PCIe",
79};
80
81static ssize_t bus_speed_read(enum pci_bus_speed speed, char *buf)
82{
83 const char *speed_string;
84
85 if (speed < ARRAY_SIZE(pci_bus_speed_strings))
86 speed_string = pci_bus_speed_strings[speed];
87 else
88 speed_string = "Unknown";
89
90 return sprintf(buf, "%s\n", speed_string);
91}
92
93static ssize_t max_speed_read_file(struct pci_slot *slot, char *buf)
94{
95 return bus_speed_read(slot->bus->max_bus_speed, buf);
96}
97
98static ssize_t cur_speed_read_file(struct pci_slot *slot, char *buf)
99{
100 return bus_speed_read(slot->bus->cur_bus_speed, buf);
101}
102
103static void pci_slot_release(struct kobject *kobj)
104{
105 struct pci_dev *dev;
106 struct pci_slot *slot = to_pci_slot(kobj);
107
108 dev_dbg(&slot->bus->dev, "dev %02x, released physical slot %s\n",
109 slot->number, pci_slot_name(slot));
110
111 down_read(&pci_bus_sem);
112 list_for_each_entry(dev, &slot->bus->devices, bus_list)
113 if (PCI_SLOT(dev->devfn) == slot->number)
114 dev->slot = NULL;
115 up_read(&pci_bus_sem);
116
117 list_del(&slot->list);
118
119 kfree(slot);
120}
121
122static struct pci_slot_attribute pci_slot_attr_address =
123 __ATTR(address, S_IRUGO, address_read_file, NULL);
124static struct pci_slot_attribute pci_slot_attr_max_speed =
125 __ATTR(max_bus_speed, S_IRUGO, max_speed_read_file, NULL);
126static struct pci_slot_attribute pci_slot_attr_cur_speed =
127 __ATTR(cur_bus_speed, S_IRUGO, cur_speed_read_file, NULL);
128
129static struct attribute *pci_slot_default_attrs[] = {
130 &pci_slot_attr_address.attr,
131 &pci_slot_attr_max_speed.attr,
132 &pci_slot_attr_cur_speed.attr,
133 NULL,
134};
135
136static struct kobj_type pci_slot_ktype = {
137 .sysfs_ops = &pci_slot_sysfs_ops,
138 .release = &pci_slot_release,
139 .default_attrs = pci_slot_default_attrs,
140};
141
142static char *make_slot_name(const char *name)
143{
144 char *new_name;
145 int len, max, dup;
146
147 new_name = kstrdup(name, GFP_KERNEL);
148 if (!new_name)
149 return NULL;
150
151
152
153
154
155
156 len = strlen(name) + 2;
157 max = 1;
158 dup = 1;
159
160 for (;;) {
161 struct kobject *dup_slot;
162 dup_slot = kset_find_obj(pci_slots_kset, new_name);
163 if (!dup_slot)
164 break;
165 kobject_put(dup_slot);
166 if (dup == max) {
167 len++;
168 max *= 10;
169 kfree(new_name);
170 new_name = kmalloc(len, GFP_KERNEL);
171 if (!new_name)
172 break;
173 }
174 sprintf(new_name, "%s-%d", name, dup++);
175 }
176
177 return new_name;
178}
179
180static int rename_slot(struct pci_slot *slot, const char *name)
181{
182 int result = 0;
183 char *slot_name;
184
185 if (strcmp(pci_slot_name(slot), name) == 0)
186 return result;
187
188 slot_name = make_slot_name(name);
189 if (!slot_name)
190 return -ENOMEM;
191
192 result = kobject_rename(&slot->kobj, slot_name);
193 kfree(slot_name);
194
195 return result;
196}
197
198void pci_dev_assign_slot(struct pci_dev *dev)
199{
200 struct pci_slot *slot;
201
202 mutex_lock(&pci_slot_mutex);
203 list_for_each_entry(slot, &dev->bus->slots, list)
204 if (PCI_SLOT(dev->devfn) == slot->number)
205 dev->slot = slot;
206 mutex_unlock(&pci_slot_mutex);
207}
208
209static struct pci_slot *get_slot(struct pci_bus *parent, int slot_nr)
210{
211 struct pci_slot *slot;
212
213
214 list_for_each_entry(slot, &parent->slots, list)
215 if (slot->number == slot_nr) {
216 kobject_get(&slot->kobj);
217 return slot;
218 }
219
220 return NULL;
221}
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr,
262 const char *name,
263 struct hotplug_slot *hotplug)
264{
265 struct pci_dev *dev;
266 struct pci_slot *slot;
267 int err = 0;
268 char *slot_name = NULL;
269
270 mutex_lock(&pci_slot_mutex);
271
272 if (slot_nr == -1)
273 goto placeholder;
274
275
276
277
278
279 slot = get_slot(parent, slot_nr);
280 if (slot) {
281 if (hotplug) {
282 if ((err = slot->hotplug ? -EBUSY : 0)
283 || (err = rename_slot(slot, name))) {
284 kobject_put(&slot->kobj);
285 slot = NULL;
286 goto err;
287 }
288 }
289 goto out;
290 }
291
292placeholder:
293 slot = kzalloc(sizeof(*slot), GFP_KERNEL);
294 if (!slot) {
295 err = -ENOMEM;
296 goto err;
297 }
298
299 slot->bus = parent;
300 slot->number = slot_nr;
301
302 slot->kobj.kset = pci_slots_kset;
303
304 slot_name = make_slot_name(name);
305 if (!slot_name) {
306 err = -ENOMEM;
307 goto err;
308 }
309
310 err = kobject_init_and_add(&slot->kobj, &pci_slot_ktype, NULL,
311 "%s", slot_name);
312 if (err)
313 goto err;
314
315 INIT_LIST_HEAD(&slot->list);
316 list_add(&slot->list, &parent->slots);
317
318 down_read(&pci_bus_sem);
319 list_for_each_entry(dev, &parent->devices, bus_list)
320 if (PCI_SLOT(dev->devfn) == slot_nr)
321 dev->slot = slot;
322 up_read(&pci_bus_sem);
323
324 dev_dbg(&parent->dev, "dev %02x, created physical slot %s\n",
325 slot_nr, pci_slot_name(slot));
326
327out:
328 kfree(slot_name);
329 mutex_unlock(&pci_slot_mutex);
330 return slot;
331err:
332 kfree(slot);
333 slot = ERR_PTR(err);
334 goto out;
335}
336EXPORT_SYMBOL_GPL(pci_create_slot);
337
338
339
340
341
342
343
344
345
346void pci_destroy_slot(struct pci_slot *slot)
347{
348 dev_dbg(&slot->bus->dev, "dev %02x, dec refcount to %d\n",
349 slot->number, kref_read(&slot->kobj.kref) - 1);
350
351 mutex_lock(&pci_slot_mutex);
352 kobject_put(&slot->kobj);
353 mutex_unlock(&pci_slot_mutex);
354}
355EXPORT_SYMBOL_GPL(pci_destroy_slot);
356
357#if defined(CONFIG_HOTPLUG_PCI) || defined(CONFIG_HOTPLUG_PCI_MODULE)
358#include <linux/pci_hotplug.h>
359
360
361
362
363
364
365
366void pci_hp_create_module_link(struct pci_slot *pci_slot)
367{
368 struct hotplug_slot *slot = pci_slot->hotplug;
369 struct kobject *kobj = NULL;
370 int ret;
371
372 if (!slot || !slot->ops)
373 return;
374 kobj = kset_find_obj(module_kset, slot->ops->mod_name);
375 if (!kobj)
376 return;
377 ret = sysfs_create_link(&pci_slot->kobj, kobj, "module");
378 if (ret)
379 dev_err(&pci_slot->bus->dev, "Error creating sysfs link (%d)\n",
380 ret);
381 kobject_put(kobj);
382}
383EXPORT_SYMBOL_GPL(pci_hp_create_module_link);
384
385
386
387
388
389
390
391
392void pci_hp_remove_module_link(struct pci_slot *pci_slot)
393{
394 sysfs_remove_link(&pci_slot->kobj, "module");
395}
396EXPORT_SYMBOL_GPL(pci_hp_remove_module_link);
397#endif
398
399static int pci_slot_init(void)
400{
401 struct kset *pci_bus_kset;
402
403 pci_bus_kset = bus_get_kset(&pci_bus_type);
404 pci_slots_kset = kset_create_and_add("slots", NULL,
405 &pci_bus_kset->kobj);
406 if (!pci_slots_kset) {
407 printk(KERN_ERR "PCI: Slot initialization failure\n");
408 return -ENOMEM;
409 }
410 return 0;
411}
412
413subsys_initcall(pci_slot_init);
414