staticchar *make_slot_name(constchar *name)
{ char *new_name; int len, max, dup;
new_name = kstrdup(name, GFP_KERNEL); if (!new_name) return NULL;
/* * Make sure we hit the realloc case the first time through the * loop. 'len' will be strlen(name) + 3 at that point which is * enough space for "name-X" and the trailing NUL.
*/
len = strlen(name) + 2;
max = 1;
dup = 1;
for (;;) { struct kobject *dup_slot;
dup_slot = kset_find_obj(pci_slots_kset, new_name); if (!dup_slot) break;
kobject_put(dup_slot); if (dup == max) {
len++;
max *= 10;
kfree(new_name);
new_name = kmalloc(len, GFP_KERNEL); if (!new_name) break;
}
sprintf(new_name, "%s-%d", name, dup++);
}
return new_name;
}
staticint rename_slot(struct pci_slot *slot, constchar *name)
{ int result = 0; char *slot_name;
if (strcmp(pci_slot_name(slot), name) == 0) return result;
slot_name = make_slot_name(name); if (!slot_name) return -ENOMEM;
result = kobject_rename(&slot->kobj, slot_name);
kfree(slot_name);
/* We already hold pci_slot_mutex */
list_for_each_entry(slot, &parent->slots, list) if (slot->number == slot_nr) {
kobject_get(&slot->kobj); return slot;
}
return NULL;
}
/** * pci_create_slot - create or increment refcount for physical PCI slot * @parent: struct pci_bus of parent bridge * @slot_nr: PCI_SLOT(pci_dev->devfn) or -1 for placeholder * @name: user visible string presented in /sys/bus/pci/slots/<name> * @hotplug: set if caller is hotplug driver, NULL otherwise * * PCI slots have first class attributes such as address, speed, width, * and a &struct pci_slot is used to manage them. This interface will * either return a new &struct pci_slot to the caller, or if the pci_slot * already exists, its refcount will be incremented. * * Slots are uniquely identified by a @pci_bus, @slot_nr tuple. * * There are known platforms with broken firmware that assign the same * name to multiple slots. Workaround these broken platforms by renaming * the slots on behalf of the caller. If firmware assigns name N to * multiple slots: * * The first slot is assigned N * The second slot is assigned N-1 * The third slot is assigned N-2 * etc. * * Placeholder slots: * In most cases, @pci_bus, @slot_nr will be sufficient to uniquely identify * a slot. There is one notable exception - pSeries (rpaphp), where the * @slot_nr cannot be determined until a device is actually inserted into * the slot. In this scenario, the caller may pass -1 for @slot_nr. * * The following semantics are imposed when the caller passes @slot_nr == * -1. First, we no longer check for an existing %struct pci_slot, as there * may be many slots with @slot_nr of -1. The other change in semantics is * user-visible, which is the 'address' parameter presented in sysfs will * consist solely of a dddd:bb tuple, where dddd is the PCI domain of the * %struct pci_bus and bb is the bus number. In other words, the devfn of * the 'placeholder' slot will not be displayed.
*/ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr, constchar *name, struct hotplug_slot *hotplug)
{ struct pci_dev *dev; struct pci_slot *slot; int err = 0; char *slot_name = NULL;
mutex_lock(&pci_slot_mutex);
if (slot_nr == -1) goto placeholder;
/* * Hotplug drivers are allowed to rename an existing slot, * but only if not already claimed.
*/
slot = get_slot(parent, slot_nr); if (slot) { if (hotplug) { if (slot->hotplug) {
err = -EBUSY; goto put_slot;
}
err = rename_slot(slot, name); if (err) goto put_slot;
} goto out;
}
/** * pci_destroy_slot - decrement refcount for physical PCI slot * @slot: struct pci_slot to decrement * * %struct pci_slot is refcounted, so destroying them is really easy; we * just call kobject_put on its kobj and let our release methods do the * rest.
*/ void pci_destroy_slot(struct pci_slot *slot)
{
dev_dbg(&slot->bus->dev, "dev %02x, dec refcount to %d\n",
slot->number, kref_read(&slot->kobj.kref) - 1);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.