Re: [PATCH 03/10] aacraid: Added EEH support
On 1.12.2015 13:39, Raghava Aditya Renukunta wrote: > From: Raghava Aditya Renukunta> > Added support for PCI EEH(extended error handling). > > Signed-off-by: Raghava Aditya Renukunta Reviewed-by: Tomas Henzl Tomas -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 03/10] aacraid: Added EEH support
Hello Johannes, > -Original Message- > From: Johannes Thumshirn [mailto:jthumsh...@suse.de] > Sent: Wednesday, December 2, 2015 1:42 AM > To: Raghava Aditya Renukunta; jbottom...@parallels.com; linux- > s...@vger.kernel.org > Cc: Mahesh Rajashekhara; Murthy Bhat; Santosh Akula; Gana Sridaran; > aacr...@pmc-sierra.com; Rich Bono > Subject: Re: [PATCH 03/10] aacraid: Added EEH support > > On Tue, 2015-12-01 at 04:39 -0800, Raghava Aditya Renukunta wrote: > > From: Raghava Aditya Renukunta <raghavaaditya.renuku...@pmcs.com> > > > > Added support for PCI EEH(extended error handling). > > > > Signed-off-by: Raghava Aditya Renukunta > > <raghavaaditya.renuku...@pmcs.com> > > --- > > drivers/scsi/aacraid/aacraid.h | 1 + > > drivers/scsi/aacraid/linit.c | 138 > > + > > 2 files changed, 139 insertions(+) > > > > diff --git a/drivers/scsi/aacraid/aacraid.h > > b/drivers/scsi/aacraid/aacraid.h index d133c4a..594de5f 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 fa0fc44..0147210 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: > > @@ -1501,6 +1505,139 @@ static void aac_remove_one(struct pci_dev > *pdev) > > } > > } > > > > +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); > > + aac_fib_free_tag(>fibs[i]); > > + > > + if (aac->handle_pci_error) > > + cmd->result = DID_NO_CONNECT << 16; > > + else > > + cmd->result = DID_RESET << 16; > > + > > + cmd->scsi_done(cmd); > > + } > > + } > > +} > > + > > +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(>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; > > +} > > + > > +pci_ers_result_t aac_pci_mmio_enabled(struct pci_dev *pdev) { > > + dev_err(>dev, "aacraid: PCI error - mmio enabled\n"); > > + return PCI_ERS_RESULT_NEED_RESET; > > +} > > + > > +pci_ers_result_t aac_pci_slot_reset(struct pci_dev *pdev) { > > + dev_err(>dev, "aacraid: PCI error - slot rese
Re: [PATCH 03/10] aacraid: Added EEH support
On Tue, 2015-12-01 at 04:39 -0800, Raghava Aditya Renukunta wrote: > From: Raghava Aditya Renukunta> > Added support for PCI EEH(extended error handling). > > Signed-off-by: Raghava Aditya Renukunta > --- > drivers/scsi/aacraid/aacraid.h | 1 + > drivers/scsi/aacraid/linit.c | 138 > + > 2 files changed, 139 insertions(+) > > diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h > index d133c4a..594de5f 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 fa0fc44..0147210 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: > @@ -1501,6 +1505,139 @@ static void aac_remove_one(struct pci_dev *pdev) > } > } > > +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); > + aac_fib_free_tag(>fibs[i]); > + > + if (aac->handle_pci_error) > + cmd->result = DID_NO_CONNECT << 16; > + else > + cmd->result = DID_RESET << 16; > + > + cmd->scsi_done(cmd); > + } > + } > +} > + > +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(>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; > +} > + > +pci_ers_result_t aac_pci_mmio_enabled(struct pci_dev *pdev) > +{ > + dev_err(>dev, "aacraid: PCI error - mmio enabled\n"); > + return PCI_ERS_RESULT_NEED_RESET; > +} > + > +pci_ers_result_t aac_pci_slot_reset(struct pci_dev *pdev) > +{ > + dev_err(>dev, "aacraid: PCI error - slot reset\n"); > + pci_restore_state(pdev); > + if (pci_enable_device(pdev)) { > + dev_warn(>dev, > + "aacraid: failed to enable slave\n"); > + goto fail_device; > + } > + > + pci_set_master(pdev); > + > + if (pci_enable_device_mem(pdev)) { > + dev_err(>dev, "pci_enable_device_mem failed\n"); > + goto fail_device; > + } > + > + return PCI_ERS_RESULT_RECOVERED; > + > +fail_device: > + dev_err(>dev, "aacraid: PCI error - slot reset failed\n"); > + return PCI_ERS_RESULT_DISCONNECT; > +} > + > + > +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(>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(>dev, > + "aacraid: unable to map adapter.\n"); > + > + return; > +
[PATCH 03/10] aacraid: Added EEH support
From: Raghava Aditya RenukuntaAdded support for PCI EEH(extended error handling). Signed-off-by: Raghava Aditya Renukunta --- drivers/scsi/aacraid/aacraid.h | 1 + drivers/scsi/aacraid/linit.c | 138 + 2 files changed, 139 insertions(+) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index d133c4a..594de5f 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 fa0fc44..0147210 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: @@ -1501,6 +1505,139 @@ static void aac_remove_one(struct pci_dev *pdev) } } +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); + aac_fib_free_tag(>fibs[i]); + + if (aac->handle_pci_error) + cmd->result = DID_NO_CONNECT << 16; + else + cmd->result = DID_RESET << 16; + + cmd->scsi_done(cmd); + } + } +} + +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(>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; +} + +pci_ers_result_t aac_pci_mmio_enabled(struct pci_dev *pdev) +{ + dev_err(>dev, "aacraid: PCI error - mmio enabled\n"); + return PCI_ERS_RESULT_NEED_RESET; +} + +pci_ers_result_t aac_pci_slot_reset(struct pci_dev *pdev) +{ + dev_err(>dev, "aacraid: PCI error - slot reset\n"); + pci_restore_state(pdev); + if (pci_enable_device(pdev)) { + dev_warn(>dev, + "aacraid: failed to enable slave\n"); + goto fail_device; + } + + pci_set_master(pdev); + + if (pci_enable_device_mem(pdev)) { + dev_err(>dev, "pci_enable_device_mem failed\n"); + goto fail_device; + } + + return PCI_ERS_RESULT_RECOVERED; + +fail_device: + dev_err(>dev, "aacraid: PCI error - slot reset failed\n"); + return PCI_ERS_RESULT_DISCONNECT; +} + + +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(>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(>dev, + "aacraid: unable to map adapter.\n"); + + return; + } + } + + msleep(1); + + aac_acquire_resources(aac); + + /* +* reset this flag to unblock ioctl() as it was set +* at aac_send_shutdown() to block ioctls from upperlayer +