1 /* 2 * drivers/pci/slot.c 3 * Copyright (C) 2006 Matthew Wilcox <matthew@wil.cx> 4 * Copyright (C) 2006-2008 Hewlett-Packard Development Company, L.P. 5 * Alex Chiang <achiang@hp.com> 6 */ 7 8 #include <linux/kobject.h> 9 #include <linux/pci.h> 10 #include <linux/err.h> 11 #include "pci.h" 12 13 struct kset *pci_slots_kset; 14 EXPORT_SYMBOL_GPL(pci_slots_kset); 15 16 static ssize_t pci_slot_attr_show(struct kobject *kobj, 17 struct attribute *attr, char *buf) 18 { 19 struct pci_slot *slot = to_pci_slot(kobj); 20 struct pci_slot_attribute *attribute = to_pci_slot_attr(attr); 21 return attribute->show ? attribute->show(slot, buf) : -EIO; 22 } 23 24 static ssize_t pci_slot_attr_store(struct kobject *kobj, 25 struct attribute *attr, const char *buf, size_t len) 26 { 27 struct pci_slot *slot = to_pci_slot(kobj); 28 struct pci_slot_attribute *attribute = to_pci_slot_attr(attr); 29 return attribute->store ? attribute->store(slot, buf, len) : -EIO; 30 } 31 32 static struct sysfs_ops pci_slot_sysfs_ops = { 33 .show = pci_slot_attr_show, 34 .store = pci_slot_attr_store, 35 }; 36 37 static ssize_t address_read_file(struct pci_slot *slot, char *buf) 38 { 39 if (slot->number == 0xff) 40 return sprintf(buf, "%04x:%02x\n", 41 pci_domain_nr(slot->bus), 42 slot->bus->number); 43 else 44 return sprintf(buf, "%04x:%02x:%02x\n", 45 pci_domain_nr(slot->bus), 46 slot->bus->number, 47 slot->number); 48 } 49 50 static void pci_slot_release(struct kobject *kobj) 51 { 52 struct pci_dev *dev; 53 struct pci_slot *slot = to_pci_slot(kobj); 54 55 pr_debug("%s: releasing pci_slot on %x:%d\n", __func__, 56 slot->bus->number, slot->number); 57 58 list_for_each_entry(dev, &slot->bus->devices, bus_list) 59 if (PCI_SLOT(dev->devfn) == slot->number) 60 dev->slot = NULL; 61 62 list_del(&slot->list); 63 64 kfree(slot); 65 } 66 67 static struct pci_slot_attribute pci_slot_attr_address = 68 __ATTR(address, (S_IFREG | S_IRUGO), address_read_file, NULL); 69 70 static struct attribute *pci_slot_default_attrs[] = { 71 &pci_slot_attr_address.attr, 72 NULL, 73 }; 74 75 static struct kobj_type pci_slot_ktype = { 76 .sysfs_ops = &pci_slot_sysfs_ops, 77 .release = &pci_slot_release, 78 .default_attrs = pci_slot_default_attrs, 79 }; 80 81 static char *make_slot_name(const char *name) 82 { 83 char *new_name; 84 int len, max, dup; 85 86 new_name = kstrdup(name, GFP_KERNEL); 87 if (!new_name) 88 return NULL; 89 90 /* 91 * Make sure we hit the realloc case the first time through the 92 * loop. 'len' will be strlen(name) + 3 at that point which is 93 * enough space for "name-X" and the trailing NUL. 94 */ 95 len = strlen(name) + 2; 96 max = 1; 97 dup = 1; 98 99 for (;;) { 100 struct kobject *dup_slot; 101 dup_slot = kset_find_obj(pci_slots_kset, new_name); 102 if (!dup_slot) 103 break; 104 kobject_put(dup_slot); 105 if (dup == max) { 106 len++; 107 max *= 10; 108 kfree(new_name); 109 new_name = kmalloc(len, GFP_KERNEL); 110 if (!new_name) 111 break; 112 } 113 sprintf(new_name, "%s-%d", name, dup++); 114 } 115 116 return new_name; 117 } 118 119 static int rename_slot(struct pci_slot *slot, const char *name) 120 { 121 int result = 0; 122 char *slot_name; 123 124 if (strcmp(pci_slot_name(slot), name) == 0) 125 return result; 126 127 slot_name = make_slot_name(name); 128 if (!slot_name) 129 return -ENOMEM; 130 131 result = kobject_rename(&slot->kobj, slot_name); 132 kfree(slot_name); 133 134 return result; 135 } 136 137 static struct pci_slot *get_slot(struct pci_bus *parent, int slot_nr) 138 { 139 struct pci_slot *slot; 140 /* 141 * We already hold pci_bus_sem so don't worry 142 */ 143 list_for_each_entry(slot, &parent->slots, list) 144 if (slot->number == slot_nr) { 145 kobject_get(&slot->kobj); 146 return slot; 147 } 148 149 return NULL; 150 } 151 152 /** 153 * pci_create_slot - create or increment refcount for physical PCI slot 154 * @parent: struct pci_bus of parent bridge 155 * @slot_nr: PCI_SLOT(pci_dev->devfn) or -1 for placeholder 156 * @name: user visible string presented in /sys/bus/pci/slots/<name> 157 * @hotplug: set if caller is hotplug driver, NULL otherwise 158 * 159 * PCI slots have first class attributes such as address, speed, width, 160 * and a &struct pci_slot is used to manage them. This interface will 161 * either return a new &struct pci_slot to the caller, or if the pci_slot 162 * already exists, its refcount will be incremented. 163 * 164 * Slots are uniquely identified by a @pci_bus, @slot_nr tuple. 165 * 166 * There are known platforms with broken firmware that assign the same 167 * name to multiple slots. Workaround these broken platforms by renaming 168 * the slots on behalf of the caller. If firmware assigns name N to 169 * multiple slots: 170 * 171 * The first slot is assigned N 172 * The second slot is assigned N-1 173 * The third slot is assigned N-2 174 * etc. 175 * 176 * Placeholder slots: 177 * In most cases, @pci_bus, @slot_nr will be sufficient to uniquely identify 178 * a slot. There is one notable exception - pSeries (rpaphp), where the 179 * @slot_nr cannot be determined until a device is actually inserted into 180 * the slot. In this scenario, the caller may pass -1 for @slot_nr. 181 * 182 * The following semantics are imposed when the caller passes @slot_nr == 183 * -1. First, we no longer check for an existing %struct pci_slot, as there 184 * may be many slots with @slot_nr of -1. The other change in semantics is 185 * user-visible, which is the 'address' parameter presented in sysfs will 186 * consist solely of a dddd:bb tuple, where dddd is the PCI domain of the 187 * %struct pci_bus and bb is the bus number. In other words, the devfn of 188 * the 'placeholder' slot will not be displayed. 189 */ 190 struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr, 191 const char *name, 192 struct hotplug_slot *hotplug) 193 { 194 struct pci_dev *dev; 195 struct pci_slot *slot; 196 int err = 0; 197 char *slot_name = NULL; 198 199 down_write(&pci_bus_sem); 200 201 if (slot_nr == -1) 202 goto placeholder; 203 204 /* 205 * Hotplug drivers are allowed to rename an existing slot, 206 * but only if not already claimed. 207 */ 208 slot = get_slot(parent, slot_nr); 209 if (slot) { 210 if (hotplug) { 211 if ((err = slot->hotplug ? -EBUSY : 0) 212 || (err = rename_slot(slot, name))) { 213 kobject_put(&slot->kobj); 214 slot = NULL; 215 goto err; 216 } 217 } 218 goto out; 219 } 220 221 placeholder: 222 slot = kzalloc(sizeof(*slot), GFP_KERNEL); 223 if (!slot) { 224 err = -ENOMEM; 225 goto err; 226 } 227 228 slot->bus = parent; 229 slot->number = slot_nr; 230 231 slot->kobj.kset = pci_slots_kset; 232 233 slot_name = make_slot_name(name); 234 if (!slot_name) { 235 err = -ENOMEM; 236 goto err; 237 } 238 239 err = kobject_init_and_add(&slot->kobj, &pci_slot_ktype, NULL, 240 "%s", slot_name); 241 if (err) 242 goto err; 243 244 INIT_LIST_HEAD(&slot->list); 245 list_add(&slot->list, &parent->slots); 246 247 list_for_each_entry(dev, &parent->devices, bus_list) 248 if (PCI_SLOT(dev->devfn) == slot_nr) 249 dev->slot = slot; 250 251 /* Don't care if debug printk has a -1 for slot_nr */ 252 pr_debug("%s: created pci_slot on %04x:%02x:%02x\n", 253 __func__, pci_domain_nr(parent), parent->number, slot_nr); 254 255 out: 256 up_write(&pci_bus_sem); 257 return slot; 258 err: 259 kfree(slot); 260 slot = ERR_PTR(err); 261 goto out; 262 } 263 EXPORT_SYMBOL_GPL(pci_create_slot); 264 265 /** 266 * pci_renumber_slot - update %struct pci_slot -> number 267 * @slot - %struct pci_slot to update 268 * @slot_nr - new number for slot 269 * 270 * The primary purpose of this interface is to allow callers who earlier 271 * created a placeholder slot in pci_create_slot() by passing a -1 as 272 * slot_nr, to update their %struct pci_slot with the correct @slot_nr. 273 */ 274 void pci_renumber_slot(struct pci_slot *slot, int slot_nr) 275 { 276 struct pci_slot *tmp; 277 278 down_write(&pci_bus_sem); 279 280 list_for_each_entry(tmp, &slot->bus->slots, list) { 281 WARN_ON(tmp->number == slot_nr); 282 goto out; 283 } 284 285 slot->number = slot_nr; 286 out: 287 up_write(&pci_bus_sem); 288 } 289 EXPORT_SYMBOL_GPL(pci_renumber_slot); 290 291 /** 292 * pci_destroy_slot - decrement refcount for physical PCI slot 293 * @slot: struct pci_slot to decrement 294 * 295 * %struct pci_slot is refcounted, so destroying them is really easy; we 296 * just call kobject_put on its kobj and let our release methods do the 297 * rest. 298 */ 299 void pci_destroy_slot(struct pci_slot *slot) 300 { 301 pr_debug("%s: dec refcount to %d on %04x:%02x:%02x\n", __func__, 302 atomic_read(&slot->kobj.kref.refcount) - 1, 303 pci_domain_nr(slot->bus), slot->bus->number, slot->number); 304 305 down_write(&pci_bus_sem); 306 kobject_put(&slot->kobj); 307 up_write(&pci_bus_sem); 308 } 309 EXPORT_SYMBOL_GPL(pci_destroy_slot); 310 311 static int pci_slot_init(void) 312 { 313 struct kset *pci_bus_kset; 314 315 pci_bus_kset = bus_get_kset(&pci_bus_type); 316 pci_slots_kset = kset_create_and_add("slots", NULL, 317 &pci_bus_kset->kobj); 318 if (!pci_slots_kset) { 319 printk(KERN_ERR "PCI: Slot initialization failure\n"); 320 return -ENOMEM; 321 } 322 return 0; 323 } 324 325 subsys_initcall(pci_slot_init); 326