Skip to content

Commit 20634dc

Browse files
committed
Merge branch 'pci/hotplug'
- Differentiate between pciehp surprise and safe removal (Lukas Wunner) - Remove unnecessary pciehp includes (Lukas Wunner) - Drop pciehp hotplug_slot_ops wrappers (Lukas Wunner) - Tolerate PCIe Slot Presence Detect being hardwired to zero to workaround broken hardware, e.g., the Wilocity switch/wireless device (Lukas Wunner) - Unify pciehp controller & slot structs (Lukas Wunner) - Constify hotplug_slot_ops (Lukas Wunner) - Drop hotplug_slot_info (Lukas Wunner) - Embed hotplug_slot struct into users instead of allocating it separately (Lukas Wunner) - Initialize PCIe port service drivers directly instead of relying on initcall ordering (Keith Busch) - Restore PCI config state after a slot reset (Keith Busch) - Save/restore DPC config state along with other PCI config state (Keith Busch) - Reference count devices during AER handling to avoid race issue with concurrent hot removal (Keith Busch) - If an Upstream Port reports ERR_FATAL, don't try to read the Port's config space because it is probably unreachable (Keith Busch) - During error handling, use slot-specific reset instead of secondary bus reset to avoid link up/down issues on hotplug ports (Keith Busch) - Restore previous AER/DPC handling that does not remove and re-enumerate devices on ERR_FATAL (Keith Busch) - Notify all drivers that may be affected by error recovery resets (Keith Busch) - Always generate error recovery uevents, even if a driver doesn't have error callbacks (Keith Busch) - Make PCIe link active reporting detection generic (Keith Busch) - Support D3cold in PCIe hierarchies during system sleep and runtime, including hotplug and Thunderbolt ports (Mika Westerberg) - Handle hpmemsize/hpiosize kernel parameters uniformly, whether slots are empty or occupied (Jon Derrick) - Remove duplicated include from pci/pcie/err.c and unused variable from cpqphp (YueHaibing) - Remove driver pci_cleanup_aer_uncorrect_error_status() calls (Oza Pawandeep) - Uninline PCI bus accessors for better ftracing (Keith Busch) - Remove unused AER Root Port .error_resume method (Keith Busch) - Use kfifo in AER instead of a local version (Keith Busch) - Use threaded IRQ in AER bottom half (Keith Busch) - Use managed resources in AER core (Keith Busch) - Reuse pcie_port_find_device() for AER injection (Keith Busch) - Abstract AER interrupt handling to disconnect error injection (Keith Busch) - Refactor AER injection callbacks to simplify future improvments (Keith Busch) * pci/hotplug: PCI/AER: Refactor error injection fallbacks PCI/AER: Abstract AER interrupt handling PCI/AER: Reuse existing pcie_port_find_device() interface PCI/AER: Use managed resource allocations PCI/AER: Use threaded IRQ for bottom half PCI/AER: Use kfifo_in_spinlocked() to insert locked elements PCI/AER: Use kfifo for tracking events instead of reimplementing it PCI/AER: Remove error source from AER struct aer_rpc PCI/AER: Remove unused aer_error_resume() PCI: Uninline PCI bus accessors for better ftracing PCI/AER: Remove pci_cleanup_aer_uncorrect_error_status() calls PCI: pnv_php: Use kmemdup() PCI: cpqphp: Remove set but not used variable 'physical_slot' PCI/ERR: Remove duplicated include from err.c PCI: Equalize hotplug memory and io for occupied and empty slots PCI / ACPI: Whitelist D3 for more PCIe hotplug ports ACPI / property: Allow multiple property compatible _DSD entries PCI/PME: Implement runtime PM callbacks PCI: pciehp: Implement runtime PM callbacks PCI/portdrv: Add runtime PM hooks for port service drivers PCI/portdrv: Resume upon exit from system suspend if left runtime suspended PCI: pciehp: Do not handle events if interrupts are masked PCI: pciehp: Disable hotplug interrupt during suspend PCI / ACPI: Enable wake automatically for power managed bridges PCI: Do not skip power-managed bridges in pci_enable_wake() PCI: Make link active reporting detection generic PCI: Unify device inaccessible PCI/ERR: Always report current recovery status for udev PCI/ERR: Simplify broadcast callouts PCI/ERR: Run error recovery callbacks for all affected devices PCI/ERR: Handle fatal error recovery PCI/ERR: Use slot reset if available PCI/AER: Don't read upstream ports below fatal errors PCI/AER: Take reference on error devices PCI/DPC: Save and restore config state PCI: portdrv: Restore PCI config state on slot reset PCI: portdrv: Initialize service drivers directly PCI: hotplug: Document TODOs PCI: hotplug: Embed hotplug_slot PCI: hotplug: Drop hotplug_slot_info PCI: hotplug: Constify hotplug_slot_ops PCI: pciehp: Reshuffle controller struct for clarity PCI: pciehp: Rename controller struct members for clarity PCI: pciehp: Unify controller and slot structs PCI: pciehp: Tolerate Presence Detect hardwired to zero PCI: pciehp: Drop hotplug_slot_ops wrappers PCI: pciehp: Drop unnecessary includes PCI: pciehp: Differentiate between surprise and safe removal PCI: Simplify disconnected marking
2 parents de468b7 + e51cd9c commit 20634dc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+1383
-1747
lines changed

Documentation/PCI/pci-error-recovery.txt

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ The actual steps taken by a platform to recover from a PCI error
110110
event will be platform-dependent, but will follow the general
111111
sequence described below.
112112

113-
STEP 0: Error Event: ERR_NONFATAL
113+
STEP 0: Error Event
114114
-------------------
115115
A PCI bus error is detected by the PCI hardware. On powerpc, the slot
116116
is isolated, in that all I/O is blocked: all reads return 0xffffffff,
@@ -228,7 +228,13 @@ proceeds to either STEP3 (Link Reset) or to STEP 5 (Resume Operations).
228228
If any driver returned PCI_ERS_RESULT_NEED_RESET, then the platform
229229
proceeds to STEP 4 (Slot Reset)
230230

231-
STEP 3: Slot Reset
231+
STEP 3: Link Reset
232+
------------------
233+
The platform resets the link. This is a PCI-Express specific step
234+
and is done whenever a fatal error has been detected that can be
235+
"solved" by resetting the link.
236+
237+
STEP 4: Slot Reset
232238
------------------
233239

234240
In response to a return value of PCI_ERS_RESULT_NEED_RESET, the
@@ -314,7 +320,7 @@ Failure).
314320
>>> However, it probably should.
315321

316322

317-
STEP 4: Resume Operations
323+
STEP 5: Resume Operations
318324
-------------------------
319325
The platform will call the resume() callback on all affected device
320326
drivers if all drivers on the segment have returned
@@ -326,7 +332,7 @@ a result code.
326332
At this point, if a new error happens, the platform will restart
327333
a new error recovery sequence.
328334

329-
STEP 5: Permanent Failure
335+
STEP 6: Permanent Failure
330336
-------------------------
331337
A "permanent failure" has occurred, and the platform cannot recover
332338
the device. The platform will call error_detected() with a
@@ -349,27 +355,6 @@ errors. See the discussion in powerpc/eeh-pci-error-recovery.txt
349355
for additional detail on real-life experience of the causes of
350356
software errors.
351357

352-
STEP 0: Error Event: ERR_FATAL
353-
-------------------
354-
PCI bus error is detected by the PCI hardware. On powerpc, the slot is
355-
isolated, in that all I/O is blocked: all reads return 0xffffffff, all
356-
writes are ignored.
357-
358-
STEP 1: Remove devices
359-
--------------------
360-
Platform removes the devices depending on the error agent, it could be
361-
this port for all subordinates or upstream component (likely downstream
362-
port)
363-
364-
STEP 2: Reset link
365-
--------------------
366-
The platform resets the link. This is a PCI-Express specific step and is
367-
done whenever a fatal error has been detected that can be "solved" by
368-
resetting the link.
369-
370-
STEP 3: Re-enumerate the devices
371-
--------------------
372-
Initiates the re-enumeration.
373358

374359
Conclusion; General Remarks
375360
---------------------------

arch/powerpc/include/asm/pnv-pci.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ void pnv_cxl_release_hwirq_ranges(struct cxl_irq_ranges *irqs,
5454

5555
struct pnv_php_slot {
5656
struct hotplug_slot slot;
57-
struct hotplug_slot_info slot_info;
5857
uint64_t id;
5958
char *name;
6059
int slot_no;
@@ -72,6 +71,7 @@ struct pnv_php_slot {
7271
struct pci_dev *pdev;
7372
struct pci_bus *bus;
7473
bool power_state_check;
74+
u8 attention_state;
7575
void *fdt;
7676
void *dt;
7777
struct of_changeset ocs;

drivers/acpi/property.c

Lines changed: 71 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,15 @@ static int acpi_data_get_property_array(const struct acpi_device_data *data,
2424
acpi_object_type type,
2525
const union acpi_object **obj);
2626

27-
/* ACPI _DSD device properties GUID: daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */
28-
static const guid_t prp_guid =
27+
static const guid_t prp_guids[] = {
28+
/* ACPI _DSD device properties GUID: daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */
2929
GUID_INIT(0xdaffd814, 0x6eba, 0x4d8c,
30-
0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01);
31-
/* ACPI _DSD data subnodes GUID: dbb8e3e6-5886-4ba6-8795-1319f52a966b */
30+
0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01),
31+
/* Hotplug in D3 GUID: 6211e2c0-58a3-4af3-90e1-927a4e0c55a4 */
32+
GUID_INIT(0x6211e2c0, 0x58a3, 0x4af3,
33+
0x90, 0xe1, 0x92, 0x7a, 0x4e, 0x0c, 0x55, 0xa4),
34+
};
35+
3236
static const guid_t ads_guid =
3337
GUID_INIT(0xdbb8e3e6, 0x5886, 0x4ba6,
3438
0x87, 0x95, 0x13, 0x19, 0xf5, 0x2a, 0x96, 0x6b);
@@ -56,6 +60,7 @@ static bool acpi_nondev_subnode_extract(const union acpi_object *desc,
5660
dn->name = link->package.elements[0].string.pointer;
5761
dn->fwnode.ops = &acpi_data_fwnode_ops;
5862
dn->parent = parent;
63+
INIT_LIST_HEAD(&dn->data.properties);
5964
INIT_LIST_HEAD(&dn->data.subnodes);
6065

6166
result = acpi_extract_properties(desc, &dn->data);
@@ -288,6 +293,35 @@ static void acpi_init_of_compatible(struct acpi_device *adev)
288293
adev->flags.of_compatible_ok = 1;
289294
}
290295

296+
static bool acpi_is_property_guid(const guid_t *guid)
297+
{
298+
int i;
299+
300+
for (i = 0; i < ARRAY_SIZE(prp_guids); i++) {
301+
if (guid_equal(guid, &prp_guids[i]))
302+
return true;
303+
}
304+
305+
return false;
306+
}
307+
308+
struct acpi_device_properties *
309+
acpi_data_add_props(struct acpi_device_data *data, const guid_t *guid,
310+
const union acpi_object *properties)
311+
{
312+
struct acpi_device_properties *props;
313+
314+
props = kzalloc(sizeof(*props), GFP_KERNEL);
315+
if (props) {
316+
INIT_LIST_HEAD(&props->list);
317+
props->guid = guid;
318+
props->properties = properties;
319+
list_add_tail(&props->list, &data->properties);
320+
}
321+
322+
return props;
323+
}
324+
291325
static bool acpi_extract_properties(const union acpi_object *desc,
292326
struct acpi_device_data *data)
293327
{
@@ -312,21 +346,21 @@ static bool acpi_extract_properties(const union acpi_object *desc,
312346
properties->type != ACPI_TYPE_PACKAGE)
313347
break;
314348

315-
if (!guid_equal((guid_t *)guid->buffer.pointer, &prp_guid))
349+
if (!acpi_is_property_guid((guid_t *)guid->buffer.pointer))
316350
continue;
317351

318352
/*
319353
* We found the matching GUID. Now validate the format of the
320354
* package immediately following it.
321355
*/
322356
if (!acpi_properties_format_valid(properties))
323-
break;
357+
continue;
324358

325-
data->properties = properties;
326-
return true;
359+
acpi_data_add_props(data, (const guid_t *)guid->buffer.pointer,
360+
properties);
327361
}
328362

329-
return false;
363+
return !list_empty(&data->properties);
330364
}
331365

332366
void acpi_init_properties(struct acpi_device *adev)
@@ -336,6 +370,7 @@ void acpi_init_properties(struct acpi_device *adev)
336370
acpi_status status;
337371
bool acpi_of = false;
338372

373+
INIT_LIST_HEAD(&adev->data.properties);
339374
INIT_LIST_HEAD(&adev->data.subnodes);
340375

341376
if (!adev->handle)
@@ -398,11 +433,16 @@ static void acpi_destroy_nondev_subnodes(struct list_head *list)
398433

399434
void acpi_free_properties(struct acpi_device *adev)
400435
{
436+
struct acpi_device_properties *props, *tmp;
437+
401438
acpi_destroy_nondev_subnodes(&adev->data.subnodes);
402439
ACPI_FREE((void *)adev->data.pointer);
403440
adev->data.of_compatible = NULL;
404441
adev->data.pointer = NULL;
405-
adev->data.properties = NULL;
442+
list_for_each_entry_safe(props, tmp, &adev->data.properties, list) {
443+
list_del(&props->list);
444+
kfree(props);
445+
}
406446
}
407447

408448
/**
@@ -427,32 +467,37 @@ static int acpi_data_get_property(const struct acpi_device_data *data,
427467
const char *name, acpi_object_type type,
428468
const union acpi_object **obj)
429469
{
430-
const union acpi_object *properties;
431-
int i;
470+
const struct acpi_device_properties *props;
432471

433472
if (!data || !name)
434473
return -EINVAL;
435474

436-
if (!data->pointer || !data->properties)
475+
if (!data->pointer || list_empty(&data->properties))
437476
return -EINVAL;
438477

439-
properties = data->properties;
440-
for (i = 0; i < properties->package.count; i++) {
441-
const union acpi_object *propname, *propvalue;
442-
const union acpi_object *property;
478+
list_for_each_entry(props, &data->properties, list) {
479+
const union acpi_object *properties;
480+
unsigned int i;
443481

444-
property = &properties->package.elements[i];
482+
properties = props->properties;
483+
for (i = 0; i < properties->package.count; i++) {
484+
const union acpi_object *propname, *propvalue;
485+
const union acpi_object *property;
445486

446-
propname = &property->package.elements[0];
447-
propvalue = &property->package.elements[1];
487+
property = &properties->package.elements[i];
448488

449-
if (!strcmp(name, propname->string.pointer)) {
450-
if (type != ACPI_TYPE_ANY && propvalue->type != type)
451-
return -EPROTO;
452-
if (obj)
453-
*obj = propvalue;
489+
propname = &property->package.elements[0];
490+
propvalue = &property->package.elements[1];
454491

455-
return 0;
492+
if (!strcmp(name, propname->string.pointer)) {
493+
if (type != ACPI_TYPE_ANY &&
494+
propvalue->type != type)
495+
return -EPROTO;
496+
if (obj)
497+
*obj = propvalue;
498+
499+
return 0;
500+
}
456501
}
457502
}
458503
return -EINVAL;

drivers/acpi/x86/apple.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,8 @@ void acpi_extract_apple_properties(struct acpi_device *adev)
132132
}
133133
WARN_ON(free_space != (void *)newprops + newsize);
134134

135-
adev->data.properties = newprops;
136135
adev->data.pointer = newprops;
136+
acpi_data_add_props(&adev->data, &apple_prp_guid, newprops);
137137

138138
out_free:
139139
ACPI_FREE(props);

drivers/crypto/qat/qat_common/adf_aer.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,6 @@ static pci_ers_result_t adf_slot_reset(struct pci_dev *pdev)
198198
pr_err("QAT: Can't find acceleration device\n");
199199
return PCI_ERS_RESULT_DISCONNECT;
200200
}
201-
pci_cleanup_aer_uncorrect_error_status(pdev);
202201
if (adf_dev_aer_schedule_reset(accel_dev, ADF_DEV_RESET_SYNC))
203202
return PCI_ERS_RESULT_DISCONNECT;
204203

drivers/dma/ioat/init.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,7 +1252,6 @@ static pci_ers_result_t ioat_pcie_error_detected(struct pci_dev *pdev,
12521252
static pci_ers_result_t ioat_pcie_error_slot_reset(struct pci_dev *pdev)
12531253
{
12541254
pci_ers_result_t result = PCI_ERS_RESULT_RECOVERED;
1255-
int err;
12561255

12571256
dev_dbg(&pdev->dev, "%s post reset handling\n", DRV_NAME);
12581257

@@ -1267,12 +1266,6 @@ static pci_ers_result_t ioat_pcie_error_slot_reset(struct pci_dev *pdev)
12671266
pci_wake_from_d3(pdev, false);
12681267
}
12691268

1270-
err = pci_cleanup_aer_uncorrect_error_status(pdev);
1271-
if (err) {
1272-
dev_err(&pdev->dev,
1273-
"AER uncorrect error status clear failed: %#x\n", err);
1274-
}
1275-
12761269
return result;
12771270
}
12781271

drivers/gpio/gpiolib-acpi.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1198,7 +1198,7 @@ int acpi_gpio_count(struct device *dev, const char *con_id)
11981198
bool acpi_can_fallback_to_crs(struct acpi_device *adev, const char *con_id)
11991199
{
12001200
/* Never allow fallback if the device has properties */
1201-
if (adev->data.properties || adev->driver_gpios)
1201+
if (acpi_dev_has_props(adev) || adev->driver_gpios)
12021202
return false;
12031203

12041204
return con_id == NULL;

drivers/infiniband/hw/hfi1/pcie.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,6 @@ pci_resume(struct pci_dev *pdev)
650650
struct hfi1_devdata *dd = pci_get_drvdata(pdev);
651651

652652
dd_dev_info(dd, "HFI1 resume function called\n");
653-
pci_cleanup_aer_uncorrect_error_status(pdev);
654653
/*
655654
* Running jobs will fail, since it's asynchronous
656655
* unlike sysfs-requested reset. Better than

drivers/infiniband/hw/qib/qib_pcie.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,6 @@ qib_pci_resume(struct pci_dev *pdev)
597597
struct qib_devdata *dd = pci_get_drvdata(pdev);
598598

599599
qib_devinfo(pdev, "QIB resume function called\n");
600-
pci_cleanup_aer_uncorrect_error_status(pdev);
601600
/*
602601
* Running jobs will fail, since it's asynchronous
603602
* unlike sysfs-requested reset. Better than

drivers/net/ethernet/atheros/alx/main.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1964,8 +1964,6 @@ static pci_ers_result_t alx_pci_error_slot_reset(struct pci_dev *pdev)
19641964
if (!alx_reset_mac(hw))
19651965
rc = PCI_ERS_RESULT_RECOVERED;
19661966
out:
1967-
pci_cleanup_aer_uncorrect_error_status(pdev);
1968-
19691967
rtnl_unlock();
19701968

19711969
return rc;

0 commit comments

Comments
 (0)