.. | .. |
---|
48 | 48 | #define PCI_PM_D3HOT_WAIT 10 /* msec */ |
---|
49 | 49 | #define PCI_PM_D3COLD_WAIT 100 /* msec */ |
---|
50 | 50 | |
---|
| 51 | +/* |
---|
| 52 | + * Following exit from Conventional Reset, devices must be ready within 1 sec |
---|
| 53 | + * (PCIe r6.0 sec 6.6.1). A D3cold to D0 transition implies a Conventional |
---|
| 54 | + * Reset (PCIe r6.0 sec 5.8). |
---|
| 55 | + */ |
---|
| 56 | +#define PCI_RESET_WAIT 1000 /* msec */ |
---|
| 57 | +/* |
---|
| 58 | + * Devices may extend the 1 sec period through Request Retry Status completions |
---|
| 59 | + * (PCIe r6.0 sec 2.3.1). The spec does not provide an upper limit, but 60 sec |
---|
| 60 | + * ought to be enough for any device to become responsive. |
---|
| 61 | + */ |
---|
| 62 | +#define PCIE_RESET_READY_POLL_MS 60000 /* msec */ |
---|
| 63 | + |
---|
51 | 64 | /** |
---|
52 | 65 | * struct pci_platform_pm_ops - Firmware PM callbacks |
---|
53 | 66 | * |
---|
.. | .. |
---|
109 | 122 | void pci_free_cap_save_buffers(struct pci_dev *dev); |
---|
110 | 123 | bool pci_bridge_d3_possible(struct pci_dev *dev); |
---|
111 | 124 | void pci_bridge_d3_update(struct pci_dev *dev); |
---|
112 | | -void pci_bridge_wait_for_secondary_bus(struct pci_dev *dev); |
---|
| 125 | +int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type, |
---|
| 126 | + int timeout); |
---|
113 | 127 | |
---|
114 | 128 | static inline void pci_wakeup_event(struct pci_dev *dev) |
---|
115 | 129 | { |
---|
.. | .. |
---|
357 | 371 | * @dev - pci device to set new error_state |
---|
358 | 372 | * @new - the state we want dev to be in |
---|
359 | 373 | * |
---|
360 | | - * Must be called with device_lock held. |
---|
| 374 | + * If the device is experiencing perm_failure, it has to remain in that state. |
---|
| 375 | + * Any other transition is allowed. |
---|
361 | 376 | * |
---|
362 | 377 | * Returns true if state has been changed to the requested state. |
---|
363 | 378 | */ |
---|
364 | 379 | static inline bool pci_dev_set_io_state(struct pci_dev *dev, |
---|
365 | 380 | pci_channel_state_t new) |
---|
366 | 381 | { |
---|
367 | | - bool changed = false; |
---|
| 382 | + pci_channel_state_t old; |
---|
368 | 383 | |
---|
369 | | - device_lock_assert(&dev->dev); |
---|
370 | 384 | switch (new) { |
---|
371 | 385 | case pci_channel_io_perm_failure: |
---|
372 | | - switch (dev->error_state) { |
---|
373 | | - case pci_channel_io_frozen: |
---|
374 | | - case pci_channel_io_normal: |
---|
375 | | - case pci_channel_io_perm_failure: |
---|
376 | | - changed = true; |
---|
377 | | - break; |
---|
378 | | - } |
---|
379 | | - break; |
---|
| 386 | + xchg(&dev->error_state, pci_channel_io_perm_failure); |
---|
| 387 | + return true; |
---|
380 | 388 | case pci_channel_io_frozen: |
---|
381 | | - switch (dev->error_state) { |
---|
382 | | - case pci_channel_io_frozen: |
---|
383 | | - case pci_channel_io_normal: |
---|
384 | | - changed = true; |
---|
385 | | - break; |
---|
386 | | - } |
---|
387 | | - break; |
---|
| 389 | + old = cmpxchg(&dev->error_state, pci_channel_io_normal, |
---|
| 390 | + pci_channel_io_frozen); |
---|
| 391 | + return old != pci_channel_io_perm_failure; |
---|
388 | 392 | case pci_channel_io_normal: |
---|
389 | | - switch (dev->error_state) { |
---|
390 | | - case pci_channel_io_frozen: |
---|
391 | | - case pci_channel_io_normal: |
---|
392 | | - changed = true; |
---|
393 | | - break; |
---|
394 | | - } |
---|
395 | | - break; |
---|
| 393 | + old = cmpxchg(&dev->error_state, pci_channel_io_frozen, |
---|
| 394 | + pci_channel_io_normal); |
---|
| 395 | + return old != pci_channel_io_perm_failure; |
---|
| 396 | + default: |
---|
| 397 | + return false; |
---|
396 | 398 | } |
---|
397 | | - if (changed) |
---|
398 | | - dev->error_state = new; |
---|
399 | | - return changed; |
---|
400 | 399 | } |
---|
401 | 400 | |
---|
402 | 401 | static inline int pci_dev_set_disconnected(struct pci_dev *dev, void *unused) |
---|
403 | 402 | { |
---|
404 | | - device_lock(&dev->dev); |
---|
405 | 403 | pci_dev_set_io_state(dev, pci_channel_io_perm_failure); |
---|
406 | | - device_unlock(&dev->dev); |
---|
407 | 404 | |
---|
408 | 405 | return 0; |
---|
409 | 406 | } |
---|