From patchwork Wed Feb 3 00:58:01 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Raghava Aditya Renukunta X-Patchwork-Id: 8196581 Return-Path: X-Original-To: patchwork-linux-scsi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 36D7D9FBE9 for ; Wed, 3 Feb 2016 00:48:05 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1F1C6201ED for ; Wed, 3 Feb 2016 00:48:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0950920211 for ; Wed, 3 Feb 2016 00:48:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754874AbcBCAsB (ORCPT ); Tue, 2 Feb 2016 19:48:01 -0500 Received: from bby1mta03.pmc-sierra.com ([216.241.235.118]:58422 "EHLO bby1mta03.pmc-sierra.bc.ca" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754826AbcBCAsA (ORCPT ); Tue, 2 Feb 2016 19:48:00 -0500 Received: from bby1mta03.pmc-sierra.bc.ca (localhost.pmc-sierra.bc.ca [127.0.0.1]) by localhost (Postfix) with SMTP id A20EF10707AD; Tue, 2 Feb 2016 16:47:59 -0800 (PST) Received: from smtp.pmcs.com (bby1cas04.pmc-sierra.internal [216.241.227.182]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by bby1mta03.pmc-sierra.bc.ca (Postfix) with ESMTP id 7347C1070747; Tue, 2 Feb 2016 16:47:59 -0800 (PST) Received: from localhost (216.241.227.4) by bby1cas04.pmc-sierra.internal (216.241.227.182) with Microsoft SMTP Server (TLS) id 14.3.123.3; Tue, 2 Feb 2016 16:47:59 -0800 From: Raghava Aditya Renukunta To: , , CC: , , , , , , , , Subject: [PATCH V5 03/10] aacraid: Added EEH support Date: Tue, 2 Feb 2016 16:58:01 -0800 Message-ID: <1454461088-32482-4-git-send-email-RaghavaAditya.Renukunta@pmcs.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1454461088-32482-1-git-send-email-RaghavaAditya.Renukunta@pmcs.com> References: <1454461088-32482-1-git-send-email-RaghavaAditya.Renukunta@pmcs.com> MIME-Version: 1.0 X-Originating-IP: [216.241.227.4] DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pmcs.com; h=from:to:cc:subject:date:message-id:in-reply-to:references:mime-version:content-type; s=default; bh=dcyex8WPQMt5nNU5j5ljqr1s6p+hvBZvLwpX4wDb2Lg=; b=gK01lvvZzPQ3MWsj13pXO5rmyMJQvRuJcMN7P0KIaeG16pDrLkU2coFk0GuCdlomaK0C6cz7p491Bhv7CVC38tNV9f/QmdE17+PxzEidqFBEcvGimUtvUt1ujf2eOJKvbNP7VVIYL07eMuXSn/1Y0xE5iQmt5Yoctgz2XIcO+Wk= Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Spam-Status: No, score=-7.2 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Raghava Aditya Renukunta Added support for PCI EEH(extended error handling). Changes in V2: Made local functions static Removed call to aac_fib_free_tag Set adapter_shutdown flag when PCI error detected Changes in V3: None Changes in V4: Removed setting of adapter_shutdown flag when \ PCI error detected Changes in V5: Removed CONFIG_PM macro conditional compilation for \ aac_release_resources and aac_acquire_resources Signed-off-by: Raghava Aditya Renukunta Reviewed-by: Tomas Henzl Reviewed-by: Johannes Thumshirn --- drivers/scsi/aacraid/aacraid.h | 1 + drivers/scsi/aacraid/linit.c | 140 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 140 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index fff1306..2916288 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1235,6 +1235,7 @@ struct aac_dev struct msix_entry msixentry[AAC_MAX_MSIX]; struct aac_msix_ctx aac_msix[AAC_MAX_MSIX]; /* context */ u8 adapter_shutdown; + u32 handle_pci_error; }; #define aac_adapter_interrupt(dev) \ diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 129a515..822b695 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -1298,6 +1299,9 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) goto out_deinit; scsi_scan_host(shost); + pci_enable_pcie_error_reporting(pdev); + pci_save_state(pdev); + return 0; out_deinit: @@ -1319,7 +1323,6 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) return error; } -#if (defined(CONFIG_PM)) static void aac_release_resources(struct aac_dev *aac) { int i; @@ -1414,6 +1417,8 @@ error_iounmap: return -1; } + +#if (defined(CONFIG_PM)) static int aac_suspend(struct pci_dev *pdev, pm_message_t state) { @@ -1501,6 +1506,138 @@ static void aac_remove_one(struct pci_dev *pdev) } } +static void aac_flush_ios(struct aac_dev *aac) +{ + int i; + struct scsi_cmnd *cmd; + + for (i = 0; i < aac->scsi_host_ptr->can_queue; i++) { + cmd = (struct scsi_cmnd *)aac->fibs[i].callback_data; + if (cmd && (cmd->SCp.phase == AAC_OWNER_FIRMWARE)) { + scsi_dma_unmap(cmd); + + if (aac->handle_pci_error) + cmd->result = DID_NO_CONNECT << 16; + else + cmd->result = DID_RESET << 16; + + cmd->scsi_done(cmd); + } + } +} + +static pci_ers_result_t aac_pci_error_detected(struct pci_dev *pdev, + enum pci_channel_state error) +{ + struct Scsi_Host *shost = pci_get_drvdata(pdev); + struct aac_dev *aac = shost_priv(shost); + + dev_err(&pdev->dev, "aacraid: PCI error detected %x\n", error); + + switch (error) { + case pci_channel_io_normal: + return PCI_ERS_RESULT_CAN_RECOVER; + case pci_channel_io_frozen: + aac->handle_pci_error = 1; + + scsi_block_requests(aac->scsi_host_ptr); + aac_flush_ios(aac); + aac_release_resources(aac); + + pci_disable_pcie_error_reporting(pdev); + aac_adapter_ioremap(aac, 0); + + return PCI_ERS_RESULT_NEED_RESET; + case pci_channel_io_perm_failure: + aac->handle_pci_error = 1; + + aac_flush_ios(aac); + return PCI_ERS_RESULT_DISCONNECT; + } + + return PCI_ERS_RESULT_NEED_RESET; +} + +static pci_ers_result_t aac_pci_mmio_enabled(struct pci_dev *pdev) +{ + dev_err(&pdev->dev, "aacraid: PCI error - mmio enabled\n"); + return PCI_ERS_RESULT_NEED_RESET; +} + +static pci_ers_result_t aac_pci_slot_reset(struct pci_dev *pdev) +{ + dev_err(&pdev->dev, "aacraid: PCI error - slot reset\n"); + pci_restore_state(pdev); + if (pci_enable_device(pdev)) { + dev_warn(&pdev->dev, + "aacraid: failed to enable slave\n"); + goto fail_device; + } + + pci_set_master(pdev); + + if (pci_enable_device_mem(pdev)) { + dev_err(&pdev->dev, "pci_enable_device_mem failed\n"); + goto fail_device; + } + + return PCI_ERS_RESULT_RECOVERED; + +fail_device: + dev_err(&pdev->dev, "aacraid: PCI error - slot reset failed\n"); + return PCI_ERS_RESULT_DISCONNECT; +} + + +static void aac_pci_resume(struct pci_dev *pdev) +{ + struct Scsi_Host *shost = pci_get_drvdata(pdev); + struct scsi_device *sdev = NULL; + struct aac_dev *aac = (struct aac_dev *)shost_priv(shost); + + pci_cleanup_aer_uncorrect_error_status(pdev); + + if (aac_adapter_ioremap(aac, aac->base_size)) { + + dev_err(&pdev->dev, "aacraid: ioremap failed\n"); + /* remap failed, go back ... */ + aac->comm_interface = AAC_COMM_PRODUCER; + if (aac_adapter_ioremap(aac, AAC_MIN_FOOTPRINT_SIZE)) { + dev_warn(&pdev->dev, + "aacraid: unable to map adapter.\n"); + + return; + } + } + + msleep(10000); + + aac_acquire_resources(aac); + + /* + * reset this flag to unblock ioctl() as it was set + * at aac_send_shutdown() to block ioctls from upperlayer + */ + aac->adapter_shutdown = 0; + aac->handle_pci_error = 0; + + shost_for_each_device(sdev, shost) + if (sdev->sdev_state == SDEV_OFFLINE) + sdev->sdev_state = SDEV_RUNNING; + scsi_unblock_requests(aac->scsi_host_ptr); + scsi_scan_host(aac->scsi_host_ptr); + pci_save_state(pdev); + + dev_err(&pdev->dev, "aacraid: PCI error - resume\n"); +} + +static struct pci_error_handlers aac_pci_err_handler = { + .error_detected = aac_pci_error_detected, + .mmio_enabled = aac_pci_mmio_enabled, + .slot_reset = aac_pci_slot_reset, + .resume = aac_pci_resume, +}; + static struct pci_driver aac_pci_driver = { .name = AAC_DRIVERNAME, .id_table = aac_pci_tbl, @@ -1511,6 +1648,7 @@ static struct pci_driver aac_pci_driver = { .resume = aac_resume, #endif .shutdown = aac_shutdown, + .err_handler = &aac_pci_err_handler, }; static int __init aac_init(void)