PCI: prevent duplicate slot names
commit8b0629bccb7da1da8a4597f44333650c2b6a657c
authorAlex Chiang <achiang@hp.com>
Mon, 1 Dec 2008 20:09:29 +0000 (1 13:09 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 5 Dec 2008 18:55:16 +0000 (5 10:55 -0800)
tree03c0d8550958ed405bf6e10940753501a93d8280
parent2dbfebcde1a29b906e4c922ddbf472a84c36cbb4
PCI: prevent duplicate slot names

commit 5fe6cc60680d29740b85278e17a002fa27b7e642 upstream.

Prevent callers of pci_create_slot() from registering slots with
duplicate names. This condition occurs most often when PCI hotplug
drivers are loaded on platforms with broken firmware that assigns
identical names to multiple slots.

We now rename these duplicate slots on behalf of the user.

If firmware assigns the name N to multiple slots, then:

The first registered slot is assigned N
The second registered slot is assigned N-1
The third registered slot is assigned N-2
etc.

This is the permanent fix mentioned in earlier commits d6a9e9b4 and
167e782e (shpchp/pciehp: Rename duplicate slot name...).

We take advantage of the new 'hotplug' parameter in pci_create_slot()
to prevent a slot create/rename race between hotplug drivers and
detection drivers.

Scenario A:
hotplug driver                  detection driver
--------------                  ----------------
pci_create_slot(hotplug=set)
pci_create_slot(hotplug=NULL)

The hotplug driver creates the slot with its desired name, and then
releases the semaphore. Now, the detection driver tries to create
the same slot, but it already exists. We don't care about renaming,
so return the existing slot.

Scenario B:
hotplug driver                  detection driver
--------------                  ----------------
pci_create_slot(hotplug=NULL)
pci_create_slot(hotplug=set)

The detection driver creates the slot with name "X". Then the hotplug
driver tries to create the same slot, but wants the name "Y" instead.
We detect that we're trying to create the same slot and that we also
want a rename, so rename the slot to "Y" and return.

Scenario C:
hotplug driver                  hotplug driver
--------------                  ----------------
pci_create_slot(hotplug=set)
pci_create_slot(hotplug=set)

Two separate hotplug drivers are attempting to claim the slot and
are passing valid hotplug_slot args to pci_create_slot(). We detect
that the slot already has a ->hotplug callback, prevent a rename,
and return -EBUSY.

Cc: jbarnes@virtuousgeek.org
Cc: kristen.c.accardi@intel.com
Cc: matthew@wil.cx
Acked-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Signed-off-by: Alex Chiang <achiang@hp.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/pci/hotplug/pci_hotplug_core.c
drivers/pci/hotplug/pciehp_core.c
drivers/pci/hotplug/shpchp_core.c
drivers/pci/slot.c