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};
79
80static ssize_t bus_speed_read(enum pci_bus_speed speed, char *buf)
81{
82 const char *speed_string;
83
84 if (speed < ARRAY_SIZE(pci_bus_speed_strings))
85 speed_string = pci_bus_speed_strings[speed];
86 else
87 speed_string = "Unknown";
88
89 return sprintf(buf, "%s\n", speed_string);
90}
91
92static ssize_t max_speed_read_file(struct pci_slot *slot, char *buf)
93{
94 return bus_speed_read(slot->bus->max_bus_speed, buf);
95}
96
97static ssize_t cur_speed_read_file(struct pci_slot *slot, char *buf)
98{
99 return bus_speed_read(slot->bus->cur_bus_speed, buf);
100}
101
102static void pci_slot_release(struct kobject *kobj)
103{
104 struct pci_dev *dev;
105 struct pci_slot *slot = to_pci_slot(kobj);
106
107 dev_dbg(&slot->bus->dev, "dev %02x, released physical slot %s\n",
108 slot->number, pci_slot_name(slot));
109
110 down_read(&pci_bus_sem);
111 list_for_each_entry(dev, &slot->bus->devices, bus_list)
112 if (PCI_SLOT(dev->devfn) == slot->number)
113 dev->slot = NULL;
114 up_read(&pci_bus_sem);
115
116 list_del(&slot->list);
117
118 kfree(slot);
119}
120
121static struct pci_slot_attribute pci_slot_attr_address =
122 __ATTR(address, (S_IFREG | S_IRUGO), address_read_file, NULL);
123static struct pci_slot_attribute pci_slot_attr_max_speed =
124 __ATTR(max_bus_speed, (S_IFREG | S_IRUGO), max_speed_read_file, NULL);
125static struct pci_slot_attribute pci_slot_attr_cur_speed =
126 __ATTR(cur_bus_speed, (S_IFREG | S_IRUGO), cur_speed_read_file, NULL);
127
128static struct attribute *pci_slot_default_attrs[] = {
129 &pci_slot_attr_address.attr,
130 &pci_slot_attr_max_speed.attr,
131 &pci_slot_attr_cur_speed.attr,
132 NULL,
133};
134
135static struct kobj_type pci_slot_ktype = {
136 .sysfs_ops = &pci_slot_sysfs_ops,
137 .release = &pci_slot_release,
138 .default_attrs = pci_slot_default_attrs,
139};
140
141static char *make_slot_name(const char *name)
142{
143 char *new_name;
144 int len, max, dup;
145
146 new_name = kstrdup(name, GFP_KERNEL);
147 if (!new_name)
148 return NULL;
149
150
151
152
153
154
155 len = strlen(name) + 2;
156 max = 1;
157 dup = 1;
158
159 for (;;) {
160 struct kobject *dup_slot;
161 dup_slot = kset_find_obj(pci_slots_kset, new_name);
162 if (!dup_slot)
163 break;
164 kobject_put(dup_slot);
165 if (dup == max) {
166 len++;
167 max *= 10;
168 kfree(new_name);
169 new_name = kmalloc(len, GFP_KERNEL);
170 if (!new_name)
171 break;
172 }
173 sprintf(new_name, "%s-%d", name, dup++);
174 }
175
176 return new_name;
177}
178
179static int rename_slot(struct pci_slot *slot, const char *name)
180{
181 int result = 0;
182 char *slot_name;
183
184 if (strcmp(pci_slot_name(slot), name) == 0)
185 return result;
186
187 slot_name = make_slot_name(name);
188 if (!slot_name)
189 return -ENOMEM;
190
191 result = kobject_rename(&slot->kobj, slot_name);
192 kfree(slot_name);
193
194 return result;
195}
196
197void pci_dev_assign_slot(struct pci_dev *dev)
198{
199 struct pci_slot *slot;
200
201 mutex_lock(&pci_slot_mutex);
202 list_for_each_entry(slot, &dev->bus->slots, list)
203 if (PCI_SLOT(dev->devfn) == slot->number)
204 dev->slot = slot;
205 mutex_unlock(&pci_slot_mutex);
206}
207
208static struct pci_slot *get_slot(struct pci_bus *parent, int slot_nr)
209{
210 struct pci_slot *slot;
211
212
213 list_for_each_entry(slot, &parent->slots, list)
214 if (slot->number == slot_nr) {
215 kobject_get(&slot->kobj);
216 return slot;
217 }
218
219 return NULL;
220}
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
260struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr,
261 const char *name,
262 struct hotplug_slot *hotplug)
263{
264 struct pci_dev *dev;
265 struct pci_slot *slot;
266 int err = 0;
267 char *slot_name = NULL;
268
269 mutex_lock(&pci_slot_mutex);
270
271 if (slot_nr == -1)
272 goto placeholder;
273
274
275
276
277
278 slot = get_slot(parent, slot_nr);
279 if (slot) {
280 if (hotplug) {
281 if ((err = slot->hotplug ? -EBUSY : 0)
282 || (err = rename_slot(slot, name))) {
283 kobject_put(&slot->kobj);
284 slot = NULL;
285 goto err;
286 }
287 }
288 goto out;
289 }
290
291placeholder:
292 slot = kzalloc(sizeof(*slot), GFP_KERNEL);
293 if (!slot) {
294 err = -ENOMEM;
295 goto err;
296 }
297
298 slot->bus = parent;
299 slot->number = slot_nr;
300
301 slot->kobj.kset = pci_slots_kset;
302
303 slot_name = make_slot_name(name);
304 if (!slot_name) {
305 err = -ENOMEM;
306 goto err;
307 }
308
309 err = kobject_init_and_add(&slot->kobj, &pci_slot_ktype, NULL,
310 "%s", slot_name);
311 if (err)
312 goto err;
313
314 INIT_LIST_HEAD(&slot->list);
315 list_add(&slot->list, &parent->slots);
316
317 down_read(&pci_bus_sem);
318 list_for_each_entry(dev, &parent->devices, bus_list)
319 if (PCI_SLOT(dev->devfn) == slot_nr)
320 dev->slot = slot;
321 up_read(&pci_bus_sem);
322
323 dev_dbg(&parent->dev, "dev %02x, created physical slot %s\n",
324 slot_nr, pci_slot_name(slot));
325
326out:
327 kfree(slot_name);
328 mutex_unlock(&pci_slot_mutex);
329 return slot;
330err:
331 kfree(slot);
332 slot = ERR_PTR(err);
333 goto out;
334}
335EXPORT_SYMBOL_GPL(pci_create_slot);
336
337
338
339
340
341
342
343
344
345void pci_destroy_slot(struct pci_slot *slot)
346{
347 dev_dbg(&slot->bus->dev, "dev %02x, dec refcount to %d\n",
348 slot->number, kref_read(&slot->kobj.kref) - 1);
349
350 mutex_lock(&pci_slot_mutex);
351 kobject_put(&slot->kobj);
352 mutex_unlock(&pci_slot_mutex);
353}
354EXPORT_SYMBOL_GPL(pci_destroy_slot);
355
356#if defined(CONFIG_HOTPLUG_PCI) || defined(CONFIG_HOTPLUG_PCI_MODULE)
357#include <linux/pci_hotplug.h>
358
359
360
361
362
363
364
365void pci_hp_create_module_link(struct pci_slot *pci_slot)
366{
367 struct hotplug_slot *slot = pci_slot->hotplug;
368 struct kobject *kobj = NULL;
369 int ret;
370
371 if (!slot || !slot->ops)
372 return;
373 kobj = kset_find_obj(module_kset, slot->ops->mod_name);
374 if (!kobj)
375 return;
376 ret = sysfs_create_link(&pci_slot->kobj, kobj, "module");
377 if (ret)
378 dev_err(&pci_slot->bus->dev, "Error creating sysfs link (%d)\n",
379 ret);
380 kobject_put(kobj);
381}
382EXPORT_SYMBOL_GPL(pci_hp_create_module_link);
383
384
385
386
387
388
389
390
391void pci_hp_remove_module_link(struct pci_slot *pci_slot)
392{
393 sysfs_remove_link(&pci_slot->kobj, "module");
394}
395EXPORT_SYMBOL_GPL(pci_hp_remove_module_link);
396#endif
397
398static int pci_slot_init(void)
399{
400 struct kset *pci_bus_kset;
401
402 pci_bus_kset = bus_get_kset(&pci_bus_type);
403 pci_slots_kset = kset_create_and_add("slots", NULL,
404 &pci_bus_kset->kobj);
405 if (!pci_slots_kset) {
406 printk(KERN_ERR "PCI: Slot initialization failure\n");
407 return -ENOMEM;
408 }
409 return 0;
410}
411
412subsys_initcall(pci_slot_init);
413