diff options
author | Gavin Shan <shangw@linux.vnet.ibm.com> | 2013-11-22 03:28:45 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2013-12-05 00:08:18 -0500 |
commit | 93aef2a789778e7ec787179fc9b34ca4885a5ef3 (patch) | |
tree | 0823e462383499c02d7e0a27eef6157eb7aac35d /arch | |
parent | d905c5df9aef38d63df268f6f5e7b13894f626d3 (diff) |
powerpc/powernv: Move PHB-diag dump functions around
Prior to the completion of PCI enumeration, we actively detects
EEH errors on PCI config cycles and dump PHB diag-data if necessary.
The EEH backend also dumps PHB diag-data in case of frozen PE or
fenced PHB. However, we are using different functions to dump the
PHB diag-data for those 2 cases.
The patch merges the functions for dumping PHB diag-data to one so
that we can avoid duplicate code. Also, we never dump PHB3 diag-data
during PCI config cycles with frozen PE. The patch fixes it as well.
Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/platforms/powernv/eeh-ioda.c | 150 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/pci.c | 196 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/pci.h | 3 |
3 files changed, 144 insertions, 205 deletions
diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c index 02245cee7818..be33a16408be 100644 --- a/arch/powerpc/platforms/powernv/eeh-ioda.c +++ b/arch/powerpc/platforms/powernv/eeh-ioda.c | |||
@@ -681,164 +681,20 @@ static void ioda_eeh_hub_diag(struct pci_controller *hose) | |||
681 | } | 681 | } |
682 | } | 682 | } |
683 | 683 | ||
684 | static void ioda_eeh_p7ioc_phb_diag(struct pci_controller *hose, | ||
685 | struct OpalIoPhbErrorCommon *common) | ||
686 | { | ||
687 | struct OpalIoP7IOCPhbErrorData *data; | ||
688 | int i; | ||
689 | |||
690 | data = (struct OpalIoP7IOCPhbErrorData *)common; | ||
691 | |||
692 | pr_info("P7IOC PHB#%x Diag-data (Version: %d)\n\n", | ||
693 | hose->global_number, common->version); | ||
694 | |||
695 | pr_info(" brdgCtl: %08x\n", data->brdgCtl); | ||
696 | |||
697 | pr_info(" portStatusReg: %08x\n", data->portStatusReg); | ||
698 | pr_info(" rootCmplxStatus: %08x\n", data->rootCmplxStatus); | ||
699 | pr_info(" busAgentStatus: %08x\n", data->busAgentStatus); | ||
700 | |||
701 | pr_info(" deviceStatus: %08x\n", data->deviceStatus); | ||
702 | pr_info(" slotStatus: %08x\n", data->slotStatus); | ||
703 | pr_info(" linkStatus: %08x\n", data->linkStatus); | ||
704 | pr_info(" devCmdStatus: %08x\n", data->devCmdStatus); | ||
705 | pr_info(" devSecStatus: %08x\n", data->devSecStatus); | ||
706 | |||
707 | pr_info(" rootErrorStatus: %08x\n", data->rootErrorStatus); | ||
708 | pr_info(" uncorrErrorStatus: %08x\n", data->uncorrErrorStatus); | ||
709 | pr_info(" corrErrorStatus: %08x\n", data->corrErrorStatus); | ||
710 | pr_info(" tlpHdr1: %08x\n", data->tlpHdr1); | ||
711 | pr_info(" tlpHdr2: %08x\n", data->tlpHdr2); | ||
712 | pr_info(" tlpHdr3: %08x\n", data->tlpHdr3); | ||
713 | pr_info(" tlpHdr4: %08x\n", data->tlpHdr4); | ||
714 | pr_info(" sourceId: %08x\n", data->sourceId); | ||
715 | |||
716 | pr_info(" errorClass: %016llx\n", data->errorClass); | ||
717 | pr_info(" correlator: %016llx\n", data->correlator); | ||
718 | pr_info(" p7iocPlssr: %016llx\n", data->p7iocPlssr); | ||
719 | pr_info(" p7iocCsr: %016llx\n", data->p7iocCsr); | ||
720 | pr_info(" lemFir: %016llx\n", data->lemFir); | ||
721 | pr_info(" lemErrorMask: %016llx\n", data->lemErrorMask); | ||
722 | pr_info(" lemWOF: %016llx\n", data->lemWOF); | ||
723 | pr_info(" phbErrorStatus: %016llx\n", data->phbErrorStatus); | ||
724 | pr_info(" phbFirstErrorStatus: %016llx\n", data->phbFirstErrorStatus); | ||
725 | pr_info(" phbErrorLog0: %016llx\n", data->phbErrorLog0); | ||
726 | pr_info(" phbErrorLog1: %016llx\n", data->phbErrorLog1); | ||
727 | pr_info(" mmioErrorStatus: %016llx\n", data->mmioErrorStatus); | ||
728 | pr_info(" mmioFirstErrorStatus: %016llx\n", data->mmioFirstErrorStatus); | ||
729 | pr_info(" mmioErrorLog0: %016llx\n", data->mmioErrorLog0); | ||
730 | pr_info(" mmioErrorLog1: %016llx\n", data->mmioErrorLog1); | ||
731 | pr_info(" dma0ErrorStatus: %016llx\n", data->dma0ErrorStatus); | ||
732 | pr_info(" dma0FirstErrorStatus: %016llx\n", data->dma0FirstErrorStatus); | ||
733 | pr_info(" dma0ErrorLog0: %016llx\n", data->dma0ErrorLog0); | ||
734 | pr_info(" dma0ErrorLog1: %016llx\n", data->dma0ErrorLog1); | ||
735 | pr_info(" dma1ErrorStatus: %016llx\n", data->dma1ErrorStatus); | ||
736 | pr_info(" dma1FirstErrorStatus: %016llx\n", data->dma1FirstErrorStatus); | ||
737 | pr_info(" dma1ErrorLog0: %016llx\n", data->dma1ErrorLog0); | ||
738 | pr_info(" dma1ErrorLog1: %016llx\n", data->dma1ErrorLog1); | ||
739 | |||
740 | for (i = 0; i < OPAL_P7IOC_NUM_PEST_REGS; i++) { | ||
741 | if ((data->pestA[i] >> 63) == 0 && | ||
742 | (data->pestB[i] >> 63) == 0) | ||
743 | continue; | ||
744 | |||
745 | pr_info(" PE[%3d] PESTA: %016llx\n", i, data->pestA[i]); | ||
746 | pr_info(" PESTB: %016llx\n", data->pestB[i]); | ||
747 | } | ||
748 | } | ||
749 | |||
750 | static void ioda_eeh_phb3_phb_diag(struct pci_controller *hose, | ||
751 | struct OpalIoPhbErrorCommon *common) | ||
752 | { | ||
753 | struct OpalIoPhb3ErrorData *data; | ||
754 | int i; | ||
755 | |||
756 | data = (struct OpalIoPhb3ErrorData*)common; | ||
757 | pr_info("PHB3 PHB#%x Diag-data (Version: %d)\n\n", | ||
758 | hose->global_number, common->version); | ||
759 | |||
760 | pr_info(" brdgCtl: %08x\n", data->brdgCtl); | ||
761 | |||
762 | pr_info(" portStatusReg: %08x\n", data->portStatusReg); | ||
763 | pr_info(" rootCmplxStatus: %08x\n", data->rootCmplxStatus); | ||
764 | pr_info(" busAgentStatus: %08x\n", data->busAgentStatus); | ||
765 | |||
766 | pr_info(" deviceStatus: %08x\n", data->deviceStatus); | ||
767 | pr_info(" slotStatus: %08x\n", data->slotStatus); | ||
768 | pr_info(" linkStatus: %08x\n", data->linkStatus); | ||
769 | pr_info(" devCmdStatus: %08x\n", data->devCmdStatus); | ||
770 | pr_info(" devSecStatus: %08x\n", data->devSecStatus); | ||
771 | |||
772 | pr_info(" rootErrorStatus: %08x\n", data->rootErrorStatus); | ||
773 | pr_info(" uncorrErrorStatus: %08x\n", data->uncorrErrorStatus); | ||
774 | pr_info(" corrErrorStatus: %08x\n", data->corrErrorStatus); | ||
775 | pr_info(" tlpHdr1: %08x\n", data->tlpHdr1); | ||
776 | pr_info(" tlpHdr2: %08x\n", data->tlpHdr2); | ||
777 | pr_info(" tlpHdr3: %08x\n", data->tlpHdr3); | ||
778 | pr_info(" tlpHdr4: %08x\n", data->tlpHdr4); | ||
779 | pr_info(" sourceId: %08x\n", data->sourceId); | ||
780 | pr_info(" errorClass: %016llx\n", data->errorClass); | ||
781 | pr_info(" correlator: %016llx\n", data->correlator); | ||
782 | pr_info(" nFir: %016llx\n", data->nFir); | ||
783 | pr_info(" nFirMask: %016llx\n", data->nFirMask); | ||
784 | pr_info(" nFirWOF: %016llx\n", data->nFirWOF); | ||
785 | pr_info(" PhbPlssr: %016llx\n", data->phbPlssr); | ||
786 | pr_info(" PhbCsr: %016llx\n", data->phbCsr); | ||
787 | pr_info(" lemFir: %016llx\n", data->lemFir); | ||
788 | pr_info(" lemErrorMask: %016llx\n", data->lemErrorMask); | ||
789 | pr_info(" lemWOF: %016llx\n", data->lemWOF); | ||
790 | pr_info(" phbErrorStatus: %016llx\n", data->phbErrorStatus); | ||
791 | pr_info(" phbFirstErrorStatus: %016llx\n", data->phbFirstErrorStatus); | ||
792 | pr_info(" phbErrorLog0: %016llx\n", data->phbErrorLog0); | ||
793 | pr_info(" phbErrorLog1: %016llx\n", data->phbErrorLog1); | ||
794 | pr_info(" mmioErrorStatus: %016llx\n", data->mmioErrorStatus); | ||
795 | pr_info(" mmioFirstErrorStatus: %016llx\n", data->mmioFirstErrorStatus); | ||
796 | pr_info(" mmioErrorLog0: %016llx\n", data->mmioErrorLog0); | ||
797 | pr_info(" mmioErrorLog1: %016llx\n", data->mmioErrorLog1); | ||
798 | pr_info(" dma0ErrorStatus: %016llx\n", data->dma0ErrorStatus); | ||
799 | pr_info(" dma0FirstErrorStatus: %016llx\n", data->dma0FirstErrorStatus); | ||
800 | pr_info(" dma0ErrorLog0: %016llx\n", data->dma0ErrorLog0); | ||
801 | pr_info(" dma0ErrorLog1: %016llx\n", data->dma0ErrorLog1); | ||
802 | pr_info(" dma1ErrorStatus: %016llx\n", data->dma1ErrorStatus); | ||
803 | pr_info(" dma1FirstErrorStatus: %016llx\n", data->dma1FirstErrorStatus); | ||
804 | pr_info(" dma1ErrorLog0: %016llx\n", data->dma1ErrorLog0); | ||
805 | pr_info(" dma1ErrorLog1: %016llx\n", data->dma1ErrorLog1); | ||
806 | |||
807 | for (i = 0; i < OPAL_PHB3_NUM_PEST_REGS; i++) { | ||
808 | if ((data->pestA[i] >> 63) == 0 && | ||
809 | (data->pestB[i] >> 63) == 0) | ||
810 | continue; | ||
811 | |||
812 | pr_info(" PE[%3d] PESTA: %016llx\n", i, data->pestA[i]); | ||
813 | pr_info(" PESTB: %016llx\n", data->pestB[i]); | ||
814 | } | ||
815 | } | ||
816 | |||
817 | static void ioda_eeh_phb_diag(struct pci_controller *hose) | 684 | static void ioda_eeh_phb_diag(struct pci_controller *hose) |
818 | { | 685 | { |
819 | struct pnv_phb *phb = hose->private_data; | 686 | struct pnv_phb *phb = hose->private_data; |
820 | struct OpalIoPhbErrorCommon *common; | ||
821 | long rc; | 687 | long rc; |
822 | 688 | ||
823 | common = (struct OpalIoPhbErrorCommon *)phb->diag.blob; | 689 | rc = opal_pci_get_phb_diag_data2(phb->opal_id, phb->diag.blob, |
824 | rc = opal_pci_get_phb_diag_data2(phb->opal_id, common, PAGE_SIZE); | 690 | PNV_PCI_DIAG_BUF_SIZE); |
825 | if (rc != OPAL_SUCCESS) { | 691 | if (rc != OPAL_SUCCESS) { |
826 | pr_warning("%s: Failed to get diag-data for PHB#%x (%ld)\n", | 692 | pr_warning("%s: Failed to get diag-data for PHB#%x (%ld)\n", |
827 | __func__, hose->global_number, rc); | 693 | __func__, hose->global_number, rc); |
828 | return; | 694 | return; |
829 | } | 695 | } |
830 | 696 | ||
831 | switch (common->ioType) { | 697 | pnv_pci_dump_phb_diag_data(hose, phb->diag.blob); |
832 | case OPAL_PHB_ERROR_DATA_TYPE_P7IOC: | ||
833 | ioda_eeh_p7ioc_phb_diag(hose, common); | ||
834 | break; | ||
835 | case OPAL_PHB_ERROR_DATA_TYPE_PHB3: | ||
836 | ioda_eeh_phb3_phb_diag(hose, common); | ||
837 | break; | ||
838 | default: | ||
839 | pr_warning("%s: Unrecognized I/O chip %d\n", | ||
840 | __func__, common->ioType); | ||
841 | } | ||
842 | } | 698 | } |
843 | 699 | ||
844 | static int ioda_eeh_get_phb_pe(struct pci_controller *hose, | 700 | static int ioda_eeh_get_phb_pe(struct pci_controller *hose, |
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index 6f3d49c18d64..bac289aac7cc 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c | |||
@@ -124,77 +124,157 @@ static void pnv_teardown_msi_irqs(struct pci_dev *pdev) | |||
124 | } | 124 | } |
125 | #endif /* CONFIG_PCI_MSI */ | 125 | #endif /* CONFIG_PCI_MSI */ |
126 | 126 | ||
127 | static void pnv_pci_dump_p7ioc_diag_data(struct pnv_phb *phb) | 127 | static void pnv_pci_dump_p7ioc_diag_data(struct pci_controller *hose, |
128 | struct OpalIoPhbErrorCommon *common) | ||
128 | { | 129 | { |
129 | struct OpalIoP7IOCPhbErrorData *data = &phb->diag.p7ioc; | 130 | struct OpalIoP7IOCPhbErrorData *data; |
130 | int i; | 131 | int i; |
131 | 132 | ||
132 | pr_info("PHB %d diagnostic data:\n", phb->hose->global_number); | 133 | data = (struct OpalIoP7IOCPhbErrorData *)common; |
133 | 134 | pr_info("P7IOC PHB#%d Diag-data (Version: %d)\n\n", | |
134 | pr_info(" brdgCtl = 0x%08x\n", data->brdgCtl); | 135 | hose->global_number, common->version); |
135 | 136 | ||
136 | pr_info(" portStatusReg = 0x%08x\n", data->portStatusReg); | 137 | pr_info(" brdgCtl: %08x\n", data->brdgCtl); |
137 | pr_info(" rootCmplxStatus = 0x%08x\n", data->rootCmplxStatus); | 138 | |
138 | pr_info(" busAgentStatus = 0x%08x\n", data->busAgentStatus); | 139 | pr_info(" portStatusReg: %08x\n", data->portStatusReg); |
139 | 140 | pr_info(" rootCmplxStatus: %08x\n", data->rootCmplxStatus); | |
140 | pr_info(" deviceStatus = 0x%08x\n", data->deviceStatus); | 141 | pr_info(" busAgentStatus: %08x\n", data->busAgentStatus); |
141 | pr_info(" slotStatus = 0x%08x\n", data->slotStatus); | 142 | |
142 | pr_info(" linkStatus = 0x%08x\n", data->linkStatus); | 143 | pr_info(" deviceStatus: %08x\n", data->deviceStatus); |
143 | pr_info(" devCmdStatus = 0x%08x\n", data->devCmdStatus); | 144 | pr_info(" slotStatus: %08x\n", data->slotStatus); |
144 | pr_info(" devSecStatus = 0x%08x\n", data->devSecStatus); | 145 | pr_info(" linkStatus: %08x\n", data->linkStatus); |
145 | 146 | pr_info(" devCmdStatus: %08x\n", data->devCmdStatus); | |
146 | pr_info(" rootErrorStatus = 0x%08x\n", data->rootErrorStatus); | 147 | pr_info(" devSecStatus: %08x\n", data->devSecStatus); |
147 | pr_info(" uncorrErrorStatus = 0x%08x\n", data->uncorrErrorStatus); | 148 | |
148 | pr_info(" corrErrorStatus = 0x%08x\n", data->corrErrorStatus); | 149 | pr_info(" rootErrorStatus: %08x\n", data->rootErrorStatus); |
149 | pr_info(" tlpHdr1 = 0x%08x\n", data->tlpHdr1); | 150 | pr_info(" uncorrErrorStatus: %08x\n", data->uncorrErrorStatus); |
150 | pr_info(" tlpHdr2 = 0x%08x\n", data->tlpHdr2); | 151 | pr_info(" corrErrorStatus: %08x\n", data->corrErrorStatus); |
151 | pr_info(" tlpHdr3 = 0x%08x\n", data->tlpHdr3); | 152 | pr_info(" tlpHdr1: %08x\n", data->tlpHdr1); |
152 | pr_info(" tlpHdr4 = 0x%08x\n", data->tlpHdr4); | 153 | pr_info(" tlpHdr2: %08x\n", data->tlpHdr2); |
153 | pr_info(" sourceId = 0x%08x\n", data->sourceId); | 154 | pr_info(" tlpHdr3: %08x\n", data->tlpHdr3); |
154 | 155 | pr_info(" tlpHdr4: %08x\n", data->tlpHdr4); | |
155 | pr_info(" errorClass = 0x%016llx\n", data->errorClass); | 156 | pr_info(" sourceId: %08x\n", data->sourceId); |
156 | pr_info(" correlator = 0x%016llx\n", data->correlator); | 157 | pr_info(" errorClass: %016llx\n", data->errorClass); |
157 | 158 | pr_info(" correlator: %016llx\n", data->correlator); | |
158 | pr_info(" p7iocPlssr = 0x%016llx\n", data->p7iocPlssr); | 159 | pr_info(" p7iocPlssr: %016llx\n", data->p7iocPlssr); |
159 | pr_info(" p7iocCsr = 0x%016llx\n", data->p7iocCsr); | 160 | pr_info(" p7iocCsr: %016llx\n", data->p7iocCsr); |
160 | pr_info(" lemFir = 0x%016llx\n", data->lemFir); | 161 | pr_info(" lemFir: %016llx\n", data->lemFir); |
161 | pr_info(" lemErrorMask = 0x%016llx\n", data->lemErrorMask); | 162 | pr_info(" lemErrorMask: %016llx\n", data->lemErrorMask); |
162 | pr_info(" lemWOF = 0x%016llx\n", data->lemWOF); | 163 | pr_info(" lemWOF: %016llx\n", data->lemWOF); |
163 | pr_info(" phbErrorStatus = 0x%016llx\n", data->phbErrorStatus); | 164 | pr_info(" phbErrorStatus: %016llx\n", data->phbErrorStatus); |
164 | pr_info(" phbFirstErrorStatus = 0x%016llx\n", data->phbFirstErrorStatus); | 165 | pr_info(" phbFirstErrorStatus: %016llx\n", data->phbFirstErrorStatus); |
165 | pr_info(" phbErrorLog0 = 0x%016llx\n", data->phbErrorLog0); | 166 | pr_info(" phbErrorLog0: %016llx\n", data->phbErrorLog0); |
166 | pr_info(" phbErrorLog1 = 0x%016llx\n", data->phbErrorLog1); | 167 | pr_info(" phbErrorLog1: %016llx\n", data->phbErrorLog1); |
167 | pr_info(" mmioErrorStatus = 0x%016llx\n", data->mmioErrorStatus); | 168 | pr_info(" mmioErrorStatus: %016llx\n", data->mmioErrorStatus); |
168 | pr_info(" mmioFirstErrorStatus = 0x%016llx\n", data->mmioFirstErrorStatus); | 169 | pr_info(" mmioFirstErrorStatus: %016llx\n", data->mmioFirstErrorStatus); |
169 | pr_info(" mmioErrorLog0 = 0x%016llx\n", data->mmioErrorLog0); | 170 | pr_info(" mmioErrorLog0: %016llx\n", data->mmioErrorLog0); |
170 | pr_info(" mmioErrorLog1 = 0x%016llx\n", data->mmioErrorLog1); | 171 | pr_info(" mmioErrorLog1: %016llx\n", data->mmioErrorLog1); |
171 | pr_info(" dma0ErrorStatus = 0x%016llx\n", data->dma0ErrorStatus); | 172 | pr_info(" dma0ErrorStatus: %016llx\n", data->dma0ErrorStatus); |
172 | pr_info(" dma0FirstErrorStatus = 0x%016llx\n", data->dma0FirstErrorStatus); | 173 | pr_info(" dma0FirstErrorStatus: %016llx\n", data->dma0FirstErrorStatus); |
173 | pr_info(" dma0ErrorLog0 = 0x%016llx\n", data->dma0ErrorLog0); | 174 | pr_info(" dma0ErrorLog0: %016llx\n", data->dma0ErrorLog0); |
174 | pr_info(" dma0ErrorLog1 = 0x%016llx\n", data->dma0ErrorLog1); | 175 | pr_info(" dma0ErrorLog1: %016llx\n", data->dma0ErrorLog1); |
175 | pr_info(" dma1ErrorStatus = 0x%016llx\n", data->dma1ErrorStatus); | 176 | pr_info(" dma1ErrorStatus: %016llx\n", data->dma1ErrorStatus); |
176 | pr_info(" dma1FirstErrorStatus = 0x%016llx\n", data->dma1FirstErrorStatus); | 177 | pr_info(" dma1FirstErrorStatus: %016llx\n", data->dma1FirstErrorStatus); |
177 | pr_info(" dma1ErrorLog0 = 0x%016llx\n", data->dma1ErrorLog0); | 178 | pr_info(" dma1ErrorLog0: %016llx\n", data->dma1ErrorLog0); |
178 | pr_info(" dma1ErrorLog1 = 0x%016llx\n", data->dma1ErrorLog1); | 179 | pr_info(" dma1ErrorLog1: %016llx\n", data->dma1ErrorLog1); |
179 | 180 | ||
180 | for (i = 0; i < OPAL_P7IOC_NUM_PEST_REGS; i++) { | 181 | for (i = 0; i < OPAL_P7IOC_NUM_PEST_REGS; i++) { |
181 | if ((data->pestA[i] >> 63) == 0 && | 182 | if ((data->pestA[i] >> 63) == 0 && |
182 | (data->pestB[i] >> 63) == 0) | 183 | (data->pestB[i] >> 63) == 0) |
183 | continue; | 184 | continue; |
184 | pr_info(" PE[%3d] PESTA = 0x%016llx\n", i, data->pestA[i]); | 185 | |
185 | pr_info(" PESTB = 0x%016llx\n", data->pestB[i]); | 186 | pr_info(" PE[%3d] PESTA: %016llx\n", i, data->pestA[i]); |
187 | pr_info(" PESTB: %016llx\n", data->pestB[i]); | ||
186 | } | 188 | } |
187 | } | 189 | } |
188 | 190 | ||
189 | static void pnv_pci_dump_phb_diag_data(struct pnv_phb *phb) | 191 | static void pnv_pci_dump_phb3_diag_data(struct pci_controller *hose, |
192 | struct OpalIoPhbErrorCommon *common) | ||
190 | { | 193 | { |
191 | switch(phb->model) { | 194 | struct OpalIoPhb3ErrorData *data; |
192 | case PNV_PHB_MODEL_P7IOC: | 195 | int i; |
193 | pnv_pci_dump_p7ioc_diag_data(phb); | 196 | |
197 | data = (struct OpalIoPhb3ErrorData*)common; | ||
198 | pr_info("PHB3 PHB#%d Diag-data (Version: %d)\n\n", | ||
199 | hose->global_number, common->version); | ||
200 | |||
201 | pr_info(" brdgCtl: %08x\n", data->brdgCtl); | ||
202 | |||
203 | pr_info(" portStatusReg: %08x\n", data->portStatusReg); | ||
204 | pr_info(" rootCmplxStatus: %08x\n", data->rootCmplxStatus); | ||
205 | pr_info(" busAgentStatus: %08x\n", data->busAgentStatus); | ||
206 | |||
207 | pr_info(" deviceStatus: %08x\n", data->deviceStatus); | ||
208 | pr_info(" slotStatus: %08x\n", data->slotStatus); | ||
209 | pr_info(" linkStatus: %08x\n", data->linkStatus); | ||
210 | pr_info(" devCmdStatus: %08x\n", data->devCmdStatus); | ||
211 | pr_info(" devSecStatus: %08x\n", data->devSecStatus); | ||
212 | |||
213 | pr_info(" rootErrorStatus: %08x\n", data->rootErrorStatus); | ||
214 | pr_info(" uncorrErrorStatus: %08x\n", data->uncorrErrorStatus); | ||
215 | pr_info(" corrErrorStatus: %08x\n", data->corrErrorStatus); | ||
216 | pr_info(" tlpHdr1: %08x\n", data->tlpHdr1); | ||
217 | pr_info(" tlpHdr2: %08x\n", data->tlpHdr2); | ||
218 | pr_info(" tlpHdr3: %08x\n", data->tlpHdr3); | ||
219 | pr_info(" tlpHdr4: %08x\n", data->tlpHdr4); | ||
220 | pr_info(" sourceId: %08x\n", data->sourceId); | ||
221 | pr_info(" errorClass: %016llx\n", data->errorClass); | ||
222 | pr_info(" correlator: %016llx\n", data->correlator); | ||
223 | |||
224 | pr_info(" nFir: %016llx\n", data->nFir); | ||
225 | pr_info(" nFirMask: %016llx\n", data->nFirMask); | ||
226 | pr_info(" nFirWOF: %016llx\n", data->nFirWOF); | ||
227 | pr_info(" PhbPlssr: %016llx\n", data->phbPlssr); | ||
228 | pr_info(" PhbCsr: %016llx\n", data->phbCsr); | ||
229 | pr_info(" lemFir: %016llx\n", data->lemFir); | ||
230 | pr_info(" lemErrorMask: %016llx\n", data->lemErrorMask); | ||
231 | pr_info(" lemWOF: %016llx\n", data->lemWOF); | ||
232 | pr_info(" phbErrorStatus: %016llx\n", data->phbErrorStatus); | ||
233 | pr_info(" phbFirstErrorStatus: %016llx\n", data->phbFirstErrorStatus); | ||
234 | pr_info(" phbErrorLog0: %016llx\n", data->phbErrorLog0); | ||
235 | pr_info(" phbErrorLog1: %016llx\n", data->phbErrorLog1); | ||
236 | pr_info(" mmioErrorStatus: %016llx\n", data->mmioErrorStatus); | ||
237 | pr_info(" mmioFirstErrorStatus: %016llx\n", data->mmioFirstErrorStatus); | ||
238 | pr_info(" mmioErrorLog0: %016llx\n", data->mmioErrorLog0); | ||
239 | pr_info(" mmioErrorLog1: %016llx\n", data->mmioErrorLog1); | ||
240 | pr_info(" dma0ErrorStatus: %016llx\n", data->dma0ErrorStatus); | ||
241 | pr_info(" dma0FirstErrorStatus: %016llx\n", data->dma0FirstErrorStatus); | ||
242 | pr_info(" dma0ErrorLog0: %016llx\n", data->dma0ErrorLog0); | ||
243 | pr_info(" dma0ErrorLog1: %016llx\n", data->dma0ErrorLog1); | ||
244 | pr_info(" dma1ErrorStatus: %016llx\n", data->dma1ErrorStatus); | ||
245 | pr_info(" dma1FirstErrorStatus: %016llx\n", data->dma1FirstErrorStatus); | ||
246 | pr_info(" dma1ErrorLog0: %016llx\n", data->dma1ErrorLog0); | ||
247 | pr_info(" dma1ErrorLog1: %016llx\n", data->dma1ErrorLog1); | ||
248 | |||
249 | for (i = 0; i < OPAL_PHB3_NUM_PEST_REGS; i++) { | ||
250 | if ((data->pestA[i] >> 63) == 0 && | ||
251 | (data->pestB[i] >> 63) == 0) | ||
252 | continue; | ||
253 | |||
254 | pr_info(" PE[%3d] PESTA: %016llx\n", i, data->pestA[i]); | ||
255 | pr_info(" PESTB: %016llx\n", data->pestB[i]); | ||
256 | } | ||
257 | } | ||
258 | |||
259 | void pnv_pci_dump_phb_diag_data(struct pci_controller *hose, | ||
260 | unsigned char *log_buff) | ||
261 | { | ||
262 | struct OpalIoPhbErrorCommon *common; | ||
263 | |||
264 | if (!hose || !log_buff) | ||
265 | return; | ||
266 | |||
267 | common = (struct OpalIoPhbErrorCommon *)log_buff; | ||
268 | switch (common->ioType) { | ||
269 | case OPAL_PHB_ERROR_DATA_TYPE_P7IOC: | ||
270 | pnv_pci_dump_p7ioc_diag_data(hose, common); | ||
271 | break; | ||
272 | case OPAL_PHB_ERROR_DATA_TYPE_PHB3: | ||
273 | pnv_pci_dump_phb3_diag_data(hose, common); | ||
194 | break; | 274 | break; |
195 | default: | 275 | default: |
196 | pr_warning("PCI %d: Can't decode this PHB diag data\n", | 276 | pr_warn("%s: Unrecognized ioType %d\n", |
197 | phb->hose->global_number); | 277 | __func__, common->ioType); |
198 | } | 278 | } |
199 | } | 279 | } |
200 | 280 | ||
@@ -222,7 +302,7 @@ static void pnv_pci_handle_eeh_config(struct pnv_phb *phb, u32 pe_no) | |||
222 | * with the normal errors generated when probing empty slots | 302 | * with the normal errors generated when probing empty slots |
223 | */ | 303 | */ |
224 | if (has_diag) | 304 | if (has_diag) |
225 | pnv_pci_dump_phb_diag_data(phb); | 305 | pnv_pci_dump_phb_diag_data(phb->hose, phb->diag.blob); |
226 | else | 306 | else |
227 | pr_warning("PCI %d: No diag data available\n", | 307 | pr_warning("PCI %d: No diag data available\n", |
228 | phb->hose->global_number); | 308 | phb->hose->global_number); |
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index 911c24ef033e..9a11ff0c5c0b 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h | |||
@@ -176,6 +176,7 @@ struct pnv_phb { | |||
176 | union { | 176 | union { |
177 | unsigned char blob[PNV_PCI_DIAG_BUF_SIZE]; | 177 | unsigned char blob[PNV_PCI_DIAG_BUF_SIZE]; |
178 | struct OpalIoP7IOCPhbErrorData p7ioc; | 178 | struct OpalIoP7IOCPhbErrorData p7ioc; |
179 | struct OpalIoPhb3ErrorData phb3; | ||
179 | } diag; | 180 | } diag; |
180 | }; | 181 | }; |
181 | 182 | ||
@@ -184,6 +185,8 @@ extern struct pci_ops pnv_pci_ops; | |||
184 | extern struct pnv_eeh_ops ioda_eeh_ops; | 185 | extern struct pnv_eeh_ops ioda_eeh_ops; |
185 | #endif | 186 | #endif |
186 | 187 | ||
188 | void pnv_pci_dump_phb_diag_data(struct pci_controller *hose, | ||
189 | unsigned char *log_buff); | ||
187 | int pnv_pci_cfg_read(struct device_node *dn, | 190 | int pnv_pci_cfg_read(struct device_node *dn, |
188 | int where, int size, u32 *val); | 191 | int where, int size, u32 *val); |
189 | int pnv_pci_cfg_write(struct device_node *dn, | 192 | int pnv_pci_cfg_write(struct device_node *dn, |