Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mei: extract fw status registers

Fetch FW status registers, as they are important in
in understanding of FW reset reasons

Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Alexander Usyskin and committed by
Greg Kroah-Hartman
04dd3661 61a1aea7

+127 -5
+55
drivers/misc/mei/hw-me.c
··· 696 696 mutex_unlock(&dev->device_lock); 697 697 return IRQ_HANDLED; 698 698 } 699 + 700 + /** 701 + * mei_me_fw_status - retrieve fw status from the pci config space 702 + * 703 + * @dev: the device structure 704 + * @fw_status: fw status registers storage 705 + * 706 + * returns 0 on success an error code otherwise 707 + */ 708 + static int mei_me_fw_status(struct mei_device *dev, 709 + struct mei_fw_status *fw_status) 710 + { 711 + const u32 pci_cfg_reg[] = {PCI_CFG_HFS_1, PCI_CFG_HFS_2}; 712 + int i; 713 + 714 + if (!fw_status) 715 + return -EINVAL; 716 + 717 + switch (dev->pdev->device) { 718 + case MEI_DEV_ID_IBXPK_1: 719 + case MEI_DEV_ID_IBXPK_2: 720 + case MEI_DEV_ID_CPT_1: 721 + case MEI_DEV_ID_PBG_1: 722 + case MEI_DEV_ID_PPT_1: 723 + case MEI_DEV_ID_PPT_2: 724 + case MEI_DEV_ID_PPT_3: 725 + case MEI_DEV_ID_LPT_H: 726 + case MEI_DEV_ID_LPT_W: 727 + case MEI_DEV_ID_LPT_LP: 728 + case MEI_DEV_ID_LPT_HR: 729 + case MEI_DEV_ID_WPT_LP: 730 + fw_status->count = 2; 731 + break; 732 + case MEI_DEV_ID_ICH10_1: 733 + case MEI_DEV_ID_ICH10_2: 734 + case MEI_DEV_ID_ICH10_3: 735 + case MEI_DEV_ID_ICH10_4: 736 + fw_status->count = 1; 737 + break; 738 + default: 739 + fw_status->count = 0; 740 + break; 741 + } 742 + 743 + for (i = 0; i < fw_status->count && i < MEI_FW_STATUS_MAX; i++) { 744 + int ret; 745 + ret = pci_read_config_dword(dev->pdev, 746 + pci_cfg_reg[i], &fw_status->status[i]); 747 + if (ret) 748 + return ret; 749 + } 750 + return 0; 751 + } 752 + 699 753 static const struct mei_hw_ops mei_me_hw_ops = { 700 754 701 755 .pg_state = mei_me_pg_state, 702 756 757 + .fw_status = mei_me_fw_status, 703 758 .host_is_ready = mei_me_host_is_ready, 704 759 705 760 .hw_is_ready = mei_me_hw_is_ready,
+1 -1
drivers/misc/mei/hw-txe-regs.h
··· 89 89 # define PCI_CFG_TXE_FW_STS0_ERR_CODE_MSK 0x0000F000 90 90 # define PCI_CFG_TXE_FW_STS0_OP_MODE_MSK 0x000F0000 91 91 # define PCI_CFG_TXE_FW_STS0_RST_CNT_MSK 0x00F00000 92 - 92 + #define PCI_CFG_TXE_FW_STS1 0x48 93 93 94 94 #define IPC_BASE_ADDR 0x80400 /* SeC IPC Base Address */ 95 95
+36 -1
drivers/misc/mei/hw-txe.c
··· 620 620 mei_txe_input_ready_interrupt_enable(dev); 621 621 622 622 if (!mei_txe_is_input_ready(dev)) { 623 - dev_err(&dev->pdev->dev, "Input is not ready"); 623 + struct mei_fw_status fw_status; 624 + mei_fw_status(dev, &fw_status); 625 + dev_err(&dev->pdev->dev, "Input is not ready " FW_STS_FMT "\n", 626 + FW_STS_PRM(fw_status)); 624 627 return -EAGAIN; 625 628 } 626 629 ··· 1042 1039 return IRQ_HANDLED; 1043 1040 } 1044 1041 1042 + 1043 + /** 1044 + * mei_txe_fw_status - retrieve fw status from the pci config space 1045 + * 1046 + * @dev: the device structure 1047 + * @fw_status: fw status registers storage 1048 + * 1049 + * returns: 0 on success an error code otherwise 1050 + */ 1051 + static int mei_txe_fw_status(struct mei_device *dev, 1052 + struct mei_fw_status *fw_status) 1053 + { 1054 + const u32 pci_cfg_reg[] = {PCI_CFG_TXE_FW_STS0, PCI_CFG_TXE_FW_STS1}; 1055 + int i; 1056 + 1057 + if (!fw_status) 1058 + return -EINVAL; 1059 + 1060 + fw_status->count = 2; 1061 + 1062 + for (i = 0; i < fw_status->count && i < MEI_FW_STATUS_MAX; i++) { 1063 + int ret; 1064 + ret = pci_read_config_dword(dev->pdev, 1065 + pci_cfg_reg[i], &fw_status->status[i]); 1066 + if (ret) 1067 + return ret; 1068 + } 1069 + 1070 + return 0; 1071 + } 1072 + 1045 1073 static const struct mei_hw_ops mei_txe_hw_ops = { 1046 1074 1075 + .fw_status = mei_txe_fw_status, 1047 1076 .host_is_ready = mei_txe_host_is_ready, 1048 1077 1049 1078 .pg_state = mei_txe_pg_state,
+7 -3
drivers/misc/mei/init.c
··· 74 74 if (state != MEI_DEV_INITIALIZING && 75 75 state != MEI_DEV_DISABLED && 76 76 state != MEI_DEV_POWER_DOWN && 77 - state != MEI_DEV_POWER_UP) 78 - dev_warn(&dev->pdev->dev, "unexpected reset: dev_state = %s\n", 79 - mei_dev_state_str(state)); 77 + state != MEI_DEV_POWER_UP) { 78 + struct mei_fw_status fw_status; 79 + mei_fw_status(dev, &fw_status); 80 + dev_warn(&dev->pdev->dev, 81 + "unexpected reset: dev_state = %s " FW_STS_FMT "\n", 82 + mei_dev_state_str(state), FW_STS_PRM(fw_status)); 83 + } 80 84 81 85 /* we're already in reset, cancel the init timer 82 86 * if the reset was called due the hbm protocol error
+28
drivers/misc/mei/mei_dev.h
··· 153 153 unsigned char *data; 154 154 }; 155 155 156 + /* Maximum number of processed FW status registers */ 157 + #define MEI_FW_STATUS_MAX 2 158 + 159 + /* 160 + * struct mei_fw_status - storage of FW status data 161 + * 162 + * @count - number of actually available elements in array 163 + * @status - FW status registers 164 + */ 165 + struct mei_fw_status { 166 + int count; 167 + u32 status[MEI_FW_STATUS_MAX]; 168 + }; 169 + 156 170 /** 157 171 * struct mei_me_client - representation of me (fw) client 158 172 * ··· 227 213 228 214 /** struct mei_hw_ops 229 215 * 216 + * @fw_status - read FW status from PCI config space 230 217 * @host_is_ready - query for host readiness 231 218 232 219 * @hw_is_ready - query if hw is ready ··· 255 240 */ 256 241 struct mei_hw_ops { 257 242 243 + int (*fw_status)(struct mei_device *dev, 244 + struct mei_fw_status *fw_status); 258 245 bool (*host_is_ready)(struct mei_device *dev); 259 246 260 247 bool (*hw_is_ready)(struct mei_device *dev); ··· 697 680 { 698 681 return dev->ops->rdbuf_full_slots(dev); 699 682 } 683 + 684 + static inline int mei_fw_status(struct mei_device *dev, 685 + struct mei_fw_status *fw_status) 686 + { 687 + return dev->ops->fw_status(dev, fw_status); 688 + } 689 + 690 + #define FW_STS_FMT "%08X %08X" 691 + #define FW_STS_PRM(fw_status) \ 692 + (fw_status).count > 0 ? (fw_status).status[0] : 0xDEADBEEF, \ 693 + (fw_status).count > 1 ? (fw_status).status[1] : 0xDEADBEEF 700 694 701 695 bool mei_hbuf_acquire(struct mei_device *dev); 702 696