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

mei: read and print all six FW status registers

ME devices prior to PCH8 (Lynx Point) have two FW status registers,
on PCH8 and newer excluding txe there are six FW status registers.

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
edca5ea3 e88281ed

+100 -29
+8 -4
drivers/misc/mei/hw-me-regs.h
··· 117 117 #define MEI_DEV_ID_WPT_LP 0x9CBA /* Wildcat Point LP */ 118 118 #define MEI_DEV_ID_WPT_LP_2 0x9CBB /* Wildcat Point LP 2 */ 119 119 120 - /* Host Firmware Status Registers in PCI Config Space */ 121 - #define PCI_CFG_HFS_1 0x40 122 - #define PCI_CFG_HFS_2 0x48 123 - 124 120 /* 125 121 * MEI HW Section 126 122 */ 123 + 124 + /* Host Firmware Status Registers in PCI Config Space */ 125 + #define PCI_CFG_HFS_1 0x40 126 + #define PCI_CFG_HFS_2 0x48 127 + #define PCI_CFG_HFS_3 0x60 128 + #define PCI_CFG_HFS_4 0x64 129 + #define PCI_CFG_HFS_5 0x68 130 + #define PCI_CFG_HFS_6 0x6C 127 131 128 132 /* MEI registers */ 129 133 /* H_CB_WW - Host Circular Buffer (CB) Write Window register */
+16 -3
drivers/misc/mei/hw-me.c
··· 835 835 .fw_status.status[0] = PCI_CFG_HFS_1, \ 836 836 .fw_status.status[1] = PCI_CFG_HFS_2 837 837 838 + #define MEI_CFG_PCH8_HFS \ 839 + .fw_status.count = 6, \ 840 + .fw_status.status[0] = PCI_CFG_HFS_1, \ 841 + .fw_status.status[1] = PCI_CFG_HFS_2, \ 842 + .fw_status.status[2] = PCI_CFG_HFS_3, \ 843 + .fw_status.status[3] = PCI_CFG_HFS_4, \ 844 + .fw_status.status[4] = PCI_CFG_HFS_5, \ 845 + .fw_status.status[5] = PCI_CFG_HFS_6 838 846 839 847 /* ICH Legacy devices */ 840 848 const struct mei_cfg mei_me_legacy_cfg = { ··· 866 858 MEI_CFG_FW_NM, 867 859 }; 868 860 869 - /* PCH Lynx Point with quirk for SPS Firmware exclusion */ 870 - const struct mei_cfg mei_me_lpt_cfg = { 871 - MEI_CFG_PCH_HFS, 861 + /* PCH8 Lynx Point and newer devices */ 862 + const struct mei_cfg mei_me_pch8_cfg = { 863 + MEI_CFG_PCH8_HFS, 864 + }; 865 + 866 + /* PCH8 Lynx Point with quirk for SPS Firmware exclusion */ 867 + const struct mei_cfg mei_me_pch8_sps_cfg = { 868 + MEI_CFG_PCH8_HFS, 872 869 MEI_CFG_FW_SPS, 873 870 }; 874 871
+2 -1
drivers/misc/mei/hw-me.h
··· 65 65 extern const struct mei_cfg mei_me_ich_cfg; 66 66 extern const struct mei_cfg mei_me_pch_cfg; 67 67 extern const struct mei_cfg mei_me_pch_cpt_pbg_cfg; 68 - extern const struct mei_cfg mei_me_lpt_cfg; 68 + extern const struct mei_cfg mei_me_pch8_cfg; 69 + extern const struct mei_cfg mei_me_pch8_sps_cfg; 69 70 70 71 struct mei_device *mei_me_dev_init(struct pci_dev *pdev, 71 72 const struct mei_cfg *cfg);
+3 -4
drivers/misc/mei/hw-txe.c
··· 700 700 mei_txe_input_ready_interrupt_enable(dev); 701 701 702 702 if (!mei_txe_is_input_ready(dev)) { 703 - struct mei_fw_status fw_status; 703 + char fw_sts_str[MEI_FW_STATUS_STR_SZ]; 704 704 705 - mei_fw_status(dev, &fw_status); 706 - dev_err(dev->dev, "Input is not ready " FW_STS_FMT "\n", 707 - FW_STS_PRM(fw_status)); 705 + mei_fw_status_str(dev, fw_sts_str, MEI_FW_STATUS_STR_SZ); 706 + dev_err(dev->dev, "Input is not ready %s\n", fw_sts_str); 708 707 return -EAGAIN; 709 708 } 710 709
+33 -5
drivers/misc/mei/init.c
··· 54 54 #undef MEI_PG_STATE 55 55 } 56 56 57 + /** 58 + * mei_fw_status2str - convert fw status registers to printable string 59 + * 60 + * @fw_status: firmware status 61 + * @buf: string buffer at minimal size MEI_FW_STATUS_STR_SZ 62 + * @len: buffer len must be >= MEI_FW_STATUS_STR_SZ 63 + * 64 + * Return: number of bytes written or -EINVAL if buffer is to small 65 + */ 66 + ssize_t mei_fw_status2str(struct mei_fw_status *fw_status, 67 + char *buf, size_t len) 68 + { 69 + ssize_t cnt = 0; 70 + int i; 71 + 72 + buf[0] = '\0'; 73 + 74 + if (len < MEI_FW_STATUS_STR_SZ) 75 + return -EINVAL; 76 + 77 + for (i = 0; i < fw_status->count; i++) 78 + cnt += scnprintf(buf + cnt, len - cnt, "%08X ", 79 + fw_status->status[i]); 80 + 81 + /* drop last space */ 82 + buf[cnt] = '\0'; 83 + return cnt; 84 + } 85 + EXPORT_SYMBOL_GPL(mei_fw_status2str); 57 86 58 87 /** 59 88 * mei_cancel_work - Cancel mei background jobs ··· 115 86 state != MEI_DEV_DISABLED && 116 87 state != MEI_DEV_POWER_DOWN && 117 88 state != MEI_DEV_POWER_UP) { 118 - struct mei_fw_status fw_status; 89 + char fw_sts_str[MEI_FW_STATUS_STR_SZ]; 119 90 120 - mei_fw_status(dev, &fw_status); 121 - dev_warn(dev->dev, 122 - "unexpected reset: dev_state = %s " FW_STS_FMT "\n", 123 - mei_dev_state_str(state), FW_STS_PRM(fw_status)); 91 + mei_fw_status_str(dev, fw_sts_str, MEI_FW_STATUS_STR_SZ); 92 + dev_warn(dev->dev, "unexpected reset: dev_state = %s fw status = %s\n", 93 + mei_dev_state_str(state), fw_sts_str); 124 94 } 125 95 126 96 /* we're already in reset, cancel the init timer
+32 -6
drivers/misc/mei/mei_dev.h
··· 152 152 }; 153 153 154 154 /* Maximum number of processed FW status registers */ 155 - #define MEI_FW_STATUS_MAX 2 155 + #define MEI_FW_STATUS_MAX 6 156 + /* Minimal buffer for FW status string (8 bytes in dw + space or '\0') */ 157 + #define MEI_FW_STATUS_STR_SZ (MEI_FW_STATUS_MAX * (8 + 1)) 158 + 156 159 157 160 /* 158 161 * struct mei_fw_status - storage of FW status data ··· 808 805 return dev->ops->fw_status(dev, fw_status); 809 806 } 810 807 811 - #define FW_STS_FMT "%08X %08X" 812 - #define FW_STS_PRM(fw_status) \ 813 - (fw_status).count > 0 ? (fw_status).status[0] : 0xDEADBEEF, \ 814 - (fw_status).count > 1 ? (fw_status).status[1] : 0xDEADBEEF 815 - 816 808 bool mei_hbuf_acquire(struct mei_device *dev); 817 809 818 810 bool mei_write_is_idle(struct mei_device *dev); ··· 830 832 #define MEI_HDR_PRM(hdr) \ 831 833 (hdr)->host_addr, (hdr)->me_addr, \ 832 834 (hdr)->length, (hdr)->internal, (hdr)->msg_complete 835 + 836 + ssize_t mei_fw_status2str(struct mei_fw_status *fw_sts, char *buf, size_t len); 837 + /** 838 + * mei_fw_status_str - fetch and convert fw status registers to printable string 839 + * 840 + * @dev: the device structure 841 + * @buf: string buffer at minimal size MEI_FW_STATUS_STR_SZ 842 + * @len: buffer len must be >= MEI_FW_STATUS_STR_SZ 843 + * 844 + * Return: number of bytes written or < 0 on failure 845 + */ 846 + static inline ssize_t mei_fw_status_str(struct mei_device *dev, 847 + char *buf, size_t len) 848 + { 849 + struct mei_fw_status fw_status; 850 + int ret; 851 + 852 + buf[0] = '\0'; 853 + 854 + ret = mei_fw_status(dev, &fw_status); 855 + if (ret) 856 + return ret; 857 + 858 + ret = mei_fw_status2str(&fw_status, buf, MEI_FW_STATUS_STR_SZ); 859 + 860 + return ret; 861 + } 862 + 833 863 834 864 #endif
+6 -6
drivers/misc/mei/pci-me.c
··· 76 76 {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_1, mei_me_pch_cfg)}, 77 77 {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_2, mei_me_pch_cfg)}, 78 78 {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_3, mei_me_pch_cfg)}, 79 - {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_H, mei_me_lpt_cfg)}, 80 - {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_W, mei_me_lpt_cfg)}, 81 - {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_LP, mei_me_pch_cfg)}, 82 - {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_HR, mei_me_lpt_cfg)}, 83 - {MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP, mei_me_pch_cfg)}, 84 - {MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP_2, mei_me_pch_cfg)}, 79 + {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_H, mei_me_pch8_sps_cfg)}, 80 + {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_W, mei_me_pch8_sps_cfg)}, 81 + {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_LP, mei_me_pch8_cfg)}, 82 + {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_HR, mei_me_pch8_sps_cfg)}, 83 + {MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP, mei_me_pch8_cfg)}, 84 + {MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP_2, mei_me_pch8_cfg)}, 85 85 86 86 /* required last entry */ 87 87 {0, }