-#ifdef CONFIG_SCSI_ARCMSR_AER
-static pci_ers_result_t arcmsr_pci_slot_reset(struct pci_dev *pdev)
-{
- struct Scsi_Host *host = pci_get_drvdata(pdev);
- struct AdapterControlBlock *acb =
- (struct AdapterControlBlock *) host->hostdata;
- uint32_t intmask_org;
- int i, j;
-
- if (pci_enable_device(pdev)) {
- return PCI_ERS_RESULT_DISCONNECT;
- }
- pci_set_master(pdev);
- intmask_org = arcmsr_disable_outbound_ints(acb);
- acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED |
- ACB_F_MESSAGE_RQBUFFER_CLEARED |
- ACB_F_MESSAGE_WQBUFFER_READED);
- acb->acb_flags &= ~ACB_F_SCSISTOPADAPTER;
- for (i = 0; i < ARCMSR_MAX_TARGETID; i++)
- for (j = 0; j < ARCMSR_MAX_TARGETLUN; j++)
- acb->devstate[i][j] = ARECA_RAID_GONE;
-
- arcmsr_wait_firmware_ready(acb);
- arcmsr_iop_confirm(acb);
- /* disable all outbound interrupt */
- arcmsr_get_firmware_spec(acb);
- /*start background rebuild*/
- arcmsr_start_adapter_bgrb(acb);
- /* empty doorbell Qbuffer if door bell ringed */
- arcmsr_clear_doorbell_queue_buffer(acb);
- arcmsr_enable_eoi_mode(acb);
- /* enable outbound Post Queue,outbound doorbell Interrupt */
- arcmsr_enable_outbound_ints(acb, intmask_org);
- acb->acb_flags |= ACB_F_IOP_INITED;
-
- pci_enable_pcie_error_reporting(pdev);
- return PCI_ERS_RESULT_RECOVERED;
-}
-
-static void arcmsr_pci_ers_need_reset_forepart(struct pci_dev *pdev)
-{
- struct Scsi_Host *host = pci_get_drvdata(pdev);
- struct AdapterControlBlock *acb = (struct AdapterControlBlock *)host->hostdata;
- struct CommandControlBlock *ccb;
- uint32_t intmask_org;
- int i = 0;
-
- if (atomic_read(&acb->ccboutstandingcount) != 0) {
- /* talk to iop 331 outstanding command aborted */
- arcmsr_abort_allcmd(acb);
- /* wait for 3 sec for all command aborted*/
- ssleep(3);
- /* disable all outbound interrupt */
- intmask_org = arcmsr_disable_outbound_ints(acb);
- /* clear all outbound posted Q */
- arcmsr_done4abort_postqueue(acb);
- for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) {
- ccb = acb->pccb_pool[i];
- if (ccb->startdone == ARCMSR_CCB_START) {
- ccb->startdone = ARCMSR_CCB_ABORTED;
- arcmsr_ccb_complete(ccb, 1);
- }
- }
- /* enable all outbound interrupt */
- arcmsr_enable_outbound_ints(acb, intmask_org);
- }
- pci_disable_device(pdev);
-}
-
-static void arcmsr_pci_ers_disconnect_forepart(struct pci_dev *pdev)
-{
- struct Scsi_Host *host = pci_get_drvdata(pdev);
- struct AdapterControlBlock *acb = \
- (struct AdapterControlBlock *)host->hostdata;
-
- arcmsr_stop_adapter_bgrb(acb);
- arcmsr_flush_adapter_cache(acb);
-}
-
-static pci_ers_result_t arcmsr_pci_error_detected(struct pci_dev *pdev,
- pci_channel_state_t state)
-{
- switch (state) {
- case pci_channel_io_frozen:
- arcmsr_pci_ers_need_reset_forepart(pdev);
- return PCI_ERS_RESULT_NEED_RESET;
- case pci_channel_io_perm_failure:
- arcmsr_pci_ers_disconnect_forepart(pdev);
- return PCI_ERS_RESULT_DISCONNECT;
- break;
- default:
- return PCI_ERS_RESULT_NEED_RESET;
- }
-}
-#endif