From patchwork Thu Apr 15 04:15:08 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hidetoshi Seto X-Patchwork-Id: 92646 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o3F4Fqj6014766 for ; Thu, 15 Apr 2010 04:15:52 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753568Ab0DOEPZ (ORCPT ); Thu, 15 Apr 2010 00:15:25 -0400 Received: from fgwmail5.fujitsu.co.jp ([192.51.44.35]:45190 "EHLO fgwmail5.fujitsu.co.jp" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752031Ab0DOEPU (ORCPT ); Thu, 15 Apr 2010 00:15:20 -0400 Received: from m5.gw.fujitsu.co.jp ([10.0.50.75]) by fgwmail5.fujitsu.co.jp (Fujitsu Gateway) with ESMTP id o3F4FIQ0031500 for (envelope-from seto.hidetoshi@jp.fujitsu.com); Thu, 15 Apr 2010 13:15:19 +0900 Received: from smail (m5 [127.0.0.1]) by outgoing.m5.gw.fujitsu.co.jp (Postfix) with ESMTP id 98F3D45DE4F for ; Thu, 15 Apr 2010 13:15:18 +0900 (JST) Received: from s5.gw.fujitsu.co.jp (s5.gw.fujitsu.co.jp [10.0.50.95]) by m5.gw.fujitsu.co.jp (Postfix) with ESMTP id 79D8B45DE4E for ; Thu, 15 Apr 2010 13:15:18 +0900 (JST) Received: from s5.gw.fujitsu.co.jp (localhost.localdomain [127.0.0.1]) by s5.gw.fujitsu.co.jp (Postfix) with ESMTP id 5B5D01DB803C for ; Thu, 15 Apr 2010 13:15:18 +0900 (JST) Received: from m106.s.css.fujitsu.com (m106.s.css.fujitsu.com [10.249.87.106]) by s5.gw.fujitsu.co.jp (Postfix) with ESMTP id 102501DB805B for ; Thu, 15 Apr 2010 13:15:15 +0900 (JST) Received: from m106.css.fujitsu.com (m106 [127.0.0.1]) by m106.s.css.fujitsu.com (Postfix) with ESMTP id AFD115B8C51; Thu, 15 Apr 2010 13:15:14 +0900 (JST) Received: from [127.0.0.1] (unknown [10.124.100.141]) by m106.s.css.fujitsu.com (Postfix) with ESMTP id 2F2925B8C56; Thu, 15 Apr 2010 13:15:14 +0900 (JST) X-SecurityPolicyCheck-FJ: OK by FujitsuOutboundMailChecker v1.3.1 Received: from FMVDA2A041[10.124.100.141] by FMVDA2A041 (FujitsuOutboundMailChecker v1.3.1/9992[10.124.100.141]); Thu, 15 Apr 2010 13:15:12 +0900 (JST) Message-ID: <4BC692CC.1020505@jp.fujitsu.com> Date: Thu, 15 Apr 2010 13:15:08 +0900 From: Hidetoshi Seto User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; ja; rv:1.9.1.9) Gecko/20100317 Thunderbird/3.0.4 MIME-Version: 1.0 To: linux-pci@vger.kernel.org CC: Jesse Barnes , Kenji Kaneshige Subject: [PATCH 09/18] aerdrv: rework aer_isr_one_error() References: <4BC690E8.307@jp.fujitsu.com> In-Reply-To: <4BC690E8.307@jp.fujitsu.com> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Thu, 15 Apr 2010 04:15:52 +0000 (UTC) diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index f5eb69f..ca14058 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -208,6 +208,9 @@ static int find_device_iter(struct pci_dev *dev, void *data) * Return true if found. * * Invoked by DPC when error is detected at the Root Port. + * Caller of this function must set id, severity, and multi_error_valid of + * struct aer_err_info pointed by @e_info properly. This function must fill + * e_info->error_dev_num and e_info->dev[], based on the given information. */ static bool find_source_device(struct pci_dev *parent, struct aer_err_info *e_info) @@ -215,6 +218,9 @@ static bool find_source_device(struct pci_dev *parent, struct pci_dev *dev = parent; int result; + /* Must reset in this function */ + e_info->error_dev_num = 0; + /* Is Root Port an agent that sends error message? */ result = find_device_iter(dev, e_info); if (result) @@ -580,11 +586,14 @@ static struct aer_err_source *get_e_source(struct aer_rpc *rpc) * @info: pointer to structure to store the error record * * Return 1 on success, 0 on error. + * + * Note that @info is reused among all error devices. Clear fields properly. */ static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info) { int pos, temp; + /* Must reset in this function */ info->status = 0; info->tlp_header_valid = 0; @@ -657,11 +666,10 @@ static void aer_isr_one_error(struct pcie_device *p_device, struct aer_err_source *e_src) { struct aer_err_info *e_info; - int i; /* struct aer_err_info might be big, so we allocate it with slab */ e_info = kmalloc(sizeof(struct aer_err_info), GFP_KERNEL); - if (e_info == NULL) { + if (!e_info) { dev_printk(KERN_DEBUG, &p_device->port->dev, "Can't allocate mem when processing AER errors\n"); return; @@ -671,26 +679,33 @@ static void aer_isr_one_error(struct pcie_device *p_device, * There is a possibility that both correctable error and * uncorrectable error being logged. Report correctable error first. */ - for (i = 1; i & ROOT_ERR_STATUS_MASKS ; i <<= 2) { - if (i > 4) - break; - if (!(e_src->status & i)) - continue; - - memset(e_info, 0, sizeof(struct aer_err_info)); - - /* Init comprehensive error information */ - if (i & PCI_ERR_ROOT_COR_RCV) { - e_info->id = ERR_COR_ID(e_src->id); - e_info->severity = AER_CORRECTABLE; - } else { - e_info->id = ERR_UNCOR_ID(e_src->id); - e_info->severity = ((e_src->status >> 6) & 1); - } - if (e_src->status & - (PCI_ERR_ROOT_MULTI_COR_RCV | - PCI_ERR_ROOT_MULTI_UNCOR_RCV)) + if (e_src->status & PCI_ERR_ROOT_COR_RCV) { + e_info->id = ERR_COR_ID(e_src->id); + e_info->severity = AER_CORRECTABLE; + + if (e_src->status & PCI_ERR_ROOT_MULTI_COR_RCV) + e_info->multi_error_valid = 1; + else + e_info->multi_error_valid = 0; + + aer_print_port_info(p_device->port, e_info); + + if (find_source_device(p_device->port, e_info)) + aer_process_err_devices(p_device, e_info); + } + + if (e_src->status & PCI_ERR_ROOT_UNCOR_RCV) { + e_info->id = ERR_UNCOR_ID(e_src->id); + + if (e_src->status & PCI_ERR_ROOT_FATAL_RCV) + e_info->severity = AER_FATAL; + else + e_info->severity = AER_NONFATAL; + + if (e_src->status & PCI_ERR_ROOT_MULTI_UNCOR_RCV) e_info->multi_error_valid = 1; + else + e_info->multi_error_valid = 0; aer_print_port_info(p_device->port, e_info);