Skip to content

Commit

Permalink
powerpc/pseries: Cleanup comments in EEH aux components
Browse files Browse the repository at this point in the history
There're several EEH aux components and the patch does some cleanup
for them so that they look more clean.

        * Duplicated comments have been removed from the header file.
        * Comments have been reorganized so that it looks more clean.
        * The leading comments of functions are adjusted for a little
          bit so that the result of "make pdfdocs" would be more
          unified.
        * Function calls "xxx ()" has been replaced by "xxx()".

Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
  • Loading branch information
Gavin Shan authored and Benjamin Herrenschmidt committed Mar 9, 2012
1 parent 1823fbf commit 29f8bf1
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 97 deletions.
34 changes: 10 additions & 24 deletions arch/powerpc/include/asm/eeh_event.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
/*
* eeh_event.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
Expand All @@ -22,32 +20,20 @@
#define ASM_POWERPC_EEH_EVENT_H
#ifdef __KERNEL__

/** EEH event -- structure holding pci controller data that describes
* a change in the isolation status of a PCI slot. A pointer
* to this struct is passed as the data pointer in a notify callback.
/*
* structure holding pci controller data that describes a
* change in the isolation status of a PCI slot. A pointer
* to this struct is passed as the data pointer in a notify
* callback.
*/
struct eeh_event {
struct list_head list;
struct device_node *dn; /* struct device node */
struct pci_dev *dev; /* affected device */
struct list_head list; /* to form event queue */
struct device_node *dn; /* struct device node */
struct pci_dev *dev; /* affected device */
};

/**
* eeh_send_failure_event - generate a PCI error event
* @dev pci device
*
* This routine builds a PCI error event which will be delivered
* to all listeners on the eeh_notifier_chain.
*
* This routine can be called within an interrupt context;
* the actual event will be delivered in a normal context
* (from a workqueue).
*/
int eeh_send_failure_event (struct device_node *dn,
struct pci_dev *dev);

/* Main recovery function */
struct pci_dn * handle_eeh_events (struct eeh_event *);
int eeh_send_failure_event(struct device_node *dn, struct pci_dev *dev);
struct pci_dn *handle_eeh_events(struct eeh_event *);

#endif /* __KERNEL__ */
#endif /* ASM_POWERPC_EEH_EVENT_H */
9 changes: 3 additions & 6 deletions arch/powerpc/platforms/pseries/eeh_cache.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/*
* eeh_cache.c
* PCI address cache; allows the lookup of PCI devices based on I/O address
*
* Copyright IBM Corporation 2004
Expand Down Expand Up @@ -47,17 +46,15 @@
* than any hash algo I could think of for this problem, even
* with the penalty of slow pointer chases for d-cache misses).
*/
struct pci_io_addr_range
{
struct pci_io_addr_range {
struct rb_node rb_node;
unsigned long addr_lo;
unsigned long addr_hi;
struct pci_dev *pcidev;
unsigned int flags;
};

static struct pci_io_addr_cache
{
static struct pci_io_addr_cache {
struct rb_root rb_root;
spinlock_t piar_lock;
} pci_io_addr_cache_root;
Expand Down Expand Up @@ -166,7 +163,7 @@ pci_addr_cache_insert(struct pci_dev *dev, unsigned long alo,

#ifdef DEBUG
printk(KERN_DEBUG "PIAR: insert range=[%lx:%lx] dev=%s\n",
alo, ahi, pci_name (dev));
alo, ahi, pci_name(dev));
#endif

rb_link_node(&piar->rb_node, parent, p);
Expand Down
136 changes: 82 additions & 54 deletions arch/powerpc/platforms/pseries/eeh_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,14 @@
#include <asm/prom.h>
#include <asm/rtas.h>


static inline const char * pcid_name (struct pci_dev *pdev)
/**
* eeh_pcid_name - Retrieve name of PCI device driver
* @pdev: PCI device
*
* This routine is used to retrieve the name of PCI device driver
* if that's valid.
*/
static inline const char *pcid_name(struct pci_dev *pdev)
{
if (pdev && pdev->dev.driver)
return pdev->dev.driver->name;
Expand Down Expand Up @@ -64,7 +70,14 @@ static void print_device_node_tree(struct pci_dn *pdn, int dent)
#endif

/**
* eeh_disable_irq - disable interrupt for the recovering device
* eeh_disable_irq - Disable interrupt for the recovering device
* @dev: PCI device
*
* This routine must be called when reporting temporary or permanent
* error to the particular PCI device to disable interrupt of that
* device. If the device has enabled MSI or MSI-X interrupt, we needn't
* do real work because EEH should freeze DMA transfers for those PCI
* devices encountering EEH errors, which includes MSI or MSI-X.
*/
static void eeh_disable_irq(struct pci_dev *dev)
{
Expand All @@ -73,7 +86,7 @@ static void eeh_disable_irq(struct pci_dev *dev)
/* Don't disable MSI and MSI-X interrupts. They are
* effectively disabled by the DMA Stopped state
* when an EEH error occurs.
*/
*/
if (dev->msi_enabled || dev->msix_enabled)
return;

Expand All @@ -85,7 +98,11 @@ static void eeh_disable_irq(struct pci_dev *dev)
}

/**
* eeh_enable_irq - enable interrupt for the recovering device
* eeh_enable_irq - Enable interrupt for the recovering device
* @dev: PCI device
*
* This routine must be called to enable interrupt while failed
* device could be resumed.
*/
static void eeh_enable_irq(struct pci_dev *dev)
{
Expand All @@ -97,15 +114,15 @@ static void eeh_enable_irq(struct pci_dev *dev)
}
}

/* ------------------------------------------------------- */
/**
* eeh_report_error - report pci error to each device driver
* eeh_report_error - Report pci error to each device driver
* @dev: PCI device
* @userdata: return value
*
* Report an EEH error to each device driver, collect up and
* merge the device driver responses. Cumulative response
* passed back in "userdata".
*/

static int eeh_report_error(struct pci_dev *dev, void *userdata)
{
enum pci_ers_result rc, *res = userdata;
Expand All @@ -122,7 +139,7 @@ static int eeh_report_error(struct pci_dev *dev, void *userdata)
!driver->err_handler->error_detected)
return 0;

rc = driver->err_handler->error_detected (dev, pci_channel_io_frozen);
rc = driver->err_handler->error_detected(dev, pci_channel_io_frozen);

/* A driver that needs a reset trumps all others */
if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
Expand All @@ -132,13 +149,14 @@ static int eeh_report_error(struct pci_dev *dev, void *userdata)
}

/**
* eeh_report_mmio_enabled - tell drivers that MMIO has been enabled
* eeh_report_mmio_enabled - Tell drivers that MMIO has been enabled
* @dev: PCI device
* @userdata: return value
*
* Tells each device driver that IO ports, MMIO and config space I/O
* are now enabled. Collects up and merges the device driver responses.
* Cumulative response passed back in "userdata".
*/

static int eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata)
{
enum pci_ers_result rc, *res = userdata;
Expand All @@ -149,7 +167,7 @@ static int eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata)
!driver->err_handler->mmio_enabled)
return 0;

rc = driver->err_handler->mmio_enabled (dev);
rc = driver->err_handler->mmio_enabled(dev);

/* A driver that needs a reset trumps all others */
if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc;
Expand All @@ -159,9 +177,15 @@ static int eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata)
}

/**
* eeh_report_reset - tell device that slot has been reset
* eeh_report_reset - Tell device that slot has been reset
* @dev: PCI device
* @userdata: return value
*
* This routine must be called while EEH tries to reset particular
* PCI device so that the associated PCI device driver could take
* some actions, usually to save data the driver needs so that the
* driver can work again while the device is recovered.
*/

static int eeh_report_reset(struct pci_dev *dev, void *userdata)
{
enum pci_ers_result rc, *res = userdata;
Expand All @@ -188,9 +212,14 @@ static int eeh_report_reset(struct pci_dev *dev, void *userdata)
}

/**
* eeh_report_resume - tell device to resume normal operations
* eeh_report_resume - Tell device to resume normal operations
* @dev: PCI device
* @userdata: return value
*
* This routine must be called to notify the device driver that it
* could resume so that the device driver can do some initialization
* to make the recovered device work again.
*/

static int eeh_report_resume(struct pci_dev *dev, void *userdata)
{
struct pci_driver *driver = dev->driver;
Expand All @@ -212,12 +241,13 @@ static int eeh_report_resume(struct pci_dev *dev, void *userdata)
}

/**
* eeh_report_failure - tell device driver that device is dead.
* eeh_report_failure - Tell device driver that device is dead.
* @dev: PCI device
* @userdata: return value
*
* This informs the device driver that the device is permanently
* dead, and that no further recovery attempts will be made on it.
*/

static int eeh_report_failure(struct pci_dev *dev, void *userdata)
{
struct pci_driver *driver = dev->driver;
Expand All @@ -238,37 +268,16 @@ static int eeh_report_failure(struct pci_dev *dev, void *userdata)
return 0;
}

/* ------------------------------------------------------- */
/**
* handle_eeh_events -- reset a PCI device after hard lockup.
*
* pSeries systems will isolate a PCI slot if the PCI-Host
* bridge detects address or data parity errors, DMA's
* occurring to wild addresses (which usually happen due to
* bugs in device drivers or in PCI adapter firmware).
* Slot isolations also occur if #SERR, #PERR or other misc
* PCI-related errors are detected.
* eeh_reset_device - Perform actual reset of a pci slot
* @pe_dn: PE associated device node
* @bus: PCI bus corresponding to the isolcated slot
*
* Recovery process consists of unplugging the device driver
* (which generated hotplug events to userspace), then issuing
* a PCI #RST to the device, then reconfiguring the PCI config
* space for all bridges & devices under this slot, and then
* finally restarting the device drivers (which cause a second
* set of hotplug events to go out to userspace).
* This routine must be called to do reset on the indicated PE.
* During the reset, udev might be invoked because those affected
* PCI devices will be removed and then added.
*/

/**
* eeh_reset_device() -- perform actual reset of a pci slot
* @bus: pointer to the pci bus structure corresponding
* to the isolated slot. A non-null value will
* cause all devices under the bus to be removed
* and then re-added.
* @pe_dn: pointer to a "Partionable Endpoint" device node.
* This is the top-level structure on which pci
* bus resets can be performed.
*/

static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus)
static int eeh_reset_device(struct pci_dn *pe_dn, struct pci_bus *bus)
{
struct device_node *dn;
int cnt, rc;
Expand All @@ -281,12 +290,13 @@ static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus)

/* Reset the pci controller. (Asserts RST#; resets config space).
* Reconfigure bridges and devices. Don't try to bring the system
* up if the reset failed for some reason. */
* up if the reset failed for some reason.
*/
rc = eeh_reset_pe(pe_dn);
if (rc)
return rc;

/* Walk over all functions on this device. */
/* Walk over all functions on this device. */
dn = pe_dn->node;
if (!pcibios_find_pci_bus(dn) && PCI_DN(dn->parent))
dn = dn->parent->child;
Expand All @@ -308,7 +318,7 @@ static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus)
* potentially weird things happen.
*/
if (bus) {
ssleep (5);
ssleep(5);
pcibios_add_pci_devices(bus);
}
pe_dn->eeh_freeze_count = cnt;
Expand All @@ -321,7 +331,24 @@ static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus)
*/
#define MAX_WAIT_FOR_RECOVERY 150

struct pci_dn * handle_eeh_events (struct eeh_event *event)
/**
* eeh_handle_event - Reset a PCI device after hard lockup.
* @event: EEH event
*
* While PHB detects address or data parity errors on particular PCI
* slot, the associated PE will be frozen. Besides, DMA's occurring
* to wild addresses (which usually happen due to bugs in device
* drivers or in PCI adapter firmware) can cause EEH error. #SERR,
* #PERR or other misc PCI-related errors also can trigger EEH errors.
*
* Recovery process consists of unplugging the device driver (which
* generated hotplug events to userspace), then issuing a PCI #RST to
* the device, then reconfiguring the PCI config space for all bridges
* & devices under this slot, and then finally restarting the device
* drivers (which cause a second set of hotplug events to go out to
* userspace).
*/
struct pci_dn *handle_eeh_events(struct eeh_event *event)
{
struct device_node *frozen_dn;
struct pci_dn *frozen_pdn;
Expand Down Expand Up @@ -350,9 +377,10 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event)
* which was always an EADS pci bridge. In the new style,
* there might not be any EADS bridges, and even when there are,
* the firmware marks them as "EEH incapable". So another
* two-step is needed to find the pci bus.. */
* two-step is needed to find the pci bus..
*/
if (!frozen_bus)
frozen_bus = pcibios_find_pci_bus (frozen_dn->parent);
frozen_bus = pcibios_find_pci_bus(frozen_dn->parent);

if (!frozen_bus) {
printk(KERN_ERR "EEH: Cannot find PCI bus "
Expand Down Expand Up @@ -395,7 +423,8 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event)
pci_walk_bus(frozen_bus, eeh_report_error, &result);

/* Get the current PCI slot state. This can take a long time,
* sometimes over 3 seconds for certain systems. */
* sometimes over 3 seconds for certain systems.
*/
rc = eeh_ops->wait_state(frozen_pdn->node, MAX_WAIT_FOR_RECOVERY*1000);
if (rc < 0 || rc == EEH_STATE_NOT_SUPPORT) {
printk(KERN_WARNING "EEH: Permanent failure\n");
Expand Down Expand Up @@ -508,4 +537,3 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event)
return NULL;
}

/* ---------- end of file ---------- */
Loading

0 comments on commit 29f8bf1

Please sign in to comment.