mei: read and print all six FW status registers
authorAlexander Usyskin <alexander.usyskin@intel.com>
Wed, 19 Nov 2014 15:01:38 +0000 (17:01 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 27 Nov 2014 03:06:41 +0000 (19:06 -0800)
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>
drivers/misc/mei/hw-me-regs.h
drivers/misc/mei/hw-me.c
drivers/misc/mei/hw-me.h
drivers/misc/mei/hw-txe.c
drivers/misc/mei/init.c
drivers/misc/mei/mei_dev.h
drivers/misc/mei/pci-me.c

index c5feafdd58a8097370a3edb17c9d196e609dddc9..9eb7ed70ace2193e2d729f21702c08f81687fa6b 100644 (file)
 #define MEI_DEV_ID_WPT_LP     0x9CBA  /* Wildcat Point LP */
 #define MEI_DEV_ID_WPT_LP_2   0x9CBB  /* Wildcat Point LP 2 */
 
-/* Host Firmware Status Registers in PCI Config Space */
-#define PCI_CFG_HFS_1         0x40
-#define PCI_CFG_HFS_2         0x48
-
 /*
  * MEI HW Section
  */
 
+/* Host Firmware Status Registers in PCI Config Space */
+#define PCI_CFG_HFS_1         0x40
+#define PCI_CFG_HFS_2         0x48
+#define PCI_CFG_HFS_3         0x60
+#define PCI_CFG_HFS_4         0x64
+#define PCI_CFG_HFS_5         0x68
+#define PCI_CFG_HFS_6         0x6C
+
 /* MEI registers */
 /* H_CB_WW - Host Circular Buffer (CB) Write Window register */
 #define H_CB_WW    0
index 7ce7cf4b6092b20dc0c9733fd615dcb9e733a8b0..ff2755062b4420cf3239a80e0f767d6dc333b6a6 100644 (file)
@@ -835,6 +835,14 @@ static bool mei_me_fw_type_sps(struct pci_dev *pdev)
        .fw_status.status[0] = PCI_CFG_HFS_1,   \
        .fw_status.status[1] = PCI_CFG_HFS_2
 
+#define MEI_CFG_PCH8_HFS                        \
+       .fw_status.count = 6,                   \
+       .fw_status.status[0] = PCI_CFG_HFS_1,   \
+       .fw_status.status[1] = PCI_CFG_HFS_2,   \
+       .fw_status.status[2] = PCI_CFG_HFS_3,   \
+       .fw_status.status[3] = PCI_CFG_HFS_4,   \
+       .fw_status.status[4] = PCI_CFG_HFS_5,   \
+       .fw_status.status[5] = PCI_CFG_HFS_6
 
 /* ICH Legacy devices */
 const struct mei_cfg mei_me_legacy_cfg = {
@@ -858,9 +866,14 @@ const struct mei_cfg mei_me_pch_cpt_pbg_cfg = {
        MEI_CFG_FW_NM,
 };
 
-/* PCH Lynx Point with quirk for SPS Firmware exclusion */
-const struct mei_cfg mei_me_lpt_cfg = {
-       MEI_CFG_PCH_HFS,
+/* PCH8 Lynx Point and newer devices */
+const struct mei_cfg mei_me_pch8_cfg = {
+       MEI_CFG_PCH8_HFS,
+};
+
+/* PCH8 Lynx Point with quirk for SPS Firmware exclusion */
+const struct mei_cfg mei_me_pch8_sps_cfg = {
+       MEI_CFG_PCH8_HFS,
        MEI_CFG_FW_SPS,
 };
 
index e44ed1d039117fd42a5d5eae3bf7f129164d0f3c..d6567af44377e8deaf33a5a60888f58a128a7588 100644 (file)
@@ -65,7 +65,8 @@ extern const struct mei_cfg mei_me_legacy_cfg;
 extern const struct mei_cfg mei_me_ich_cfg;
 extern const struct mei_cfg mei_me_pch_cfg;
 extern const struct mei_cfg mei_me_pch_cpt_pbg_cfg;
-extern const struct mei_cfg mei_me_lpt_cfg;
+extern const struct mei_cfg mei_me_pch8_cfg;
+extern const struct mei_cfg mei_me_pch8_sps_cfg;
 
 struct mei_device *mei_me_dev_init(struct pci_dev *pdev,
                                   const struct mei_cfg *cfg);
index c5e1902e493f854a845f0114cc50c38aabfcfefa..618ea721aca8845dec1049cfa164d0fe4e3cedfa 100644 (file)
@@ -700,11 +700,10 @@ static int mei_txe_write(struct mei_device *dev,
        mei_txe_input_ready_interrupt_enable(dev);
 
        if (!mei_txe_is_input_ready(dev)) {
-               struct mei_fw_status fw_status;
+               char fw_sts_str[MEI_FW_STATUS_STR_SZ];
 
-               mei_fw_status(dev, &fw_status);
-               dev_err(dev->dev, "Input is not ready " FW_STS_FMT "\n",
-                       FW_STS_PRM(fw_status));
+               mei_fw_status_str(dev, fw_sts_str, MEI_FW_STATUS_STR_SZ);
+               dev_err(dev->dev, "Input is not ready %s\n", fw_sts_str);
                return -EAGAIN;
        }
 
index 7901d076c1270561f6cd24b0a701686611d89418..9306219d5675442b186b0ab6381fdd246ad09e60 100644 (file)
@@ -54,6 +54,35 @@ const char *mei_pg_state_str(enum mei_pg_state state)
 #undef MEI_PG_STATE
 }
 
+/**
+ * mei_fw_status2str - convert fw status registers to printable string
+ *
+ * @fw_status:  firmware status
+ * @buf: string buffer at minimal size MEI_FW_STATUS_STR_SZ
+ * @len: buffer len must be >= MEI_FW_STATUS_STR_SZ
+ *
+ * Return: number of bytes written or -EINVAL if buffer is to small
+ */
+ssize_t mei_fw_status2str(struct mei_fw_status *fw_status,
+                         char *buf, size_t len)
+{
+       ssize_t cnt = 0;
+       int i;
+
+       buf[0] = '\0';
+
+       if (len < MEI_FW_STATUS_STR_SZ)
+               return -EINVAL;
+
+       for (i = 0; i < fw_status->count; i++)
+               cnt += scnprintf(buf + cnt, len - cnt, "%08X ",
+                               fw_status->status[i]);
+
+       /* drop last space */
+       buf[cnt] = '\0';
+       return cnt;
+}
+EXPORT_SYMBOL_GPL(mei_fw_status2str);
 
 /**
  * mei_cancel_work - Cancel mei background jobs
@@ -86,12 +115,11 @@ int mei_reset(struct mei_device *dev)
            state != MEI_DEV_DISABLED &&
            state != MEI_DEV_POWER_DOWN &&
            state != MEI_DEV_POWER_UP) {
-               struct mei_fw_status fw_status;
+               char fw_sts_str[MEI_FW_STATUS_STR_SZ];
 
-               mei_fw_status(dev, &fw_status);
-               dev_warn(dev->dev,
-                       "unexpected reset: dev_state = %s " FW_STS_FMT "\n",
-                       mei_dev_state_str(state), FW_STS_PRM(fw_status));
+               mei_fw_status_str(dev, fw_sts_str, MEI_FW_STATUS_STR_SZ);
+               dev_warn(dev->dev, "unexpected reset: dev_state = %s fw status = %s\n",
+                        mei_dev_state_str(state), fw_sts_str);
        }
 
        /* we're already in reset, cancel the init timer
index 1288a5cf60b9647335f5c92aead2aa489393f29d..c90c16b29c080f9e14a0d1352697b6378b279993 100644 (file)
@@ -152,7 +152,10 @@ struct mei_msg_data {
 };
 
 /* Maximum number of processed FW status registers */
-#define MEI_FW_STATUS_MAX 2
+#define MEI_FW_STATUS_MAX 6
+/* Minimal  buffer for FW status string (8 bytes in dw + space or '\0') */
+#define MEI_FW_STATUS_STR_SZ (MEI_FW_STATUS_MAX * (8 + 1))
+
 
 /*
  * struct mei_fw_status - storage of FW status data
@@ -805,11 +808,6 @@ static inline int mei_fw_status(struct mei_device *dev,
        return dev->ops->fw_status(dev, fw_status);
 }
 
-#define FW_STS_FMT "%08X %08X"
-#define FW_STS_PRM(fw_status) \
-       (fw_status).count > 0 ? (fw_status).status[0] : 0xDEADBEEF, \
-       (fw_status).count > 1 ? (fw_status).status[1] : 0xDEADBEEF
-
 bool mei_hbuf_acquire(struct mei_device *dev);
 
 bool mei_write_is_idle(struct mei_device *dev);
@@ -833,4 +831,32 @@ void mei_deregister(struct mei_device *dev);
        (hdr)->host_addr, (hdr)->me_addr, \
        (hdr)->length, (hdr)->internal, (hdr)->msg_complete
 
+ssize_t mei_fw_status2str(struct mei_fw_status *fw_sts, char *buf, size_t len);
+/**
+ * mei_fw_status_str - fetch and convert fw status registers to printable string
+ *
+ * @dev: the device structure
+ * @buf: string buffer at minimal size MEI_FW_STATUS_STR_SZ
+ * @len: buffer len must be >= MEI_FW_STATUS_STR_SZ
+ *
+ * Return: number of bytes written or < 0 on failure
+ */
+static inline ssize_t mei_fw_status_str(struct mei_device *dev,
+                                       char *buf, size_t len)
+{
+       struct mei_fw_status fw_status;
+       int ret;
+
+       buf[0] = '\0';
+
+       ret = mei_fw_status(dev, &fw_status);
+       if (ret)
+               return ret;
+
+       ret = mei_fw_status2str(&fw_status, buf, MEI_FW_STATUS_STR_SZ);
+
+       return ret;
+}
+
+
 #endif
index f3225b1643abbb7f9654a9f577a76ab5cddb0c2c..b0da60f10acfcdcc08593bdcd65bbf6203a38538 100644 (file)
@@ -76,12 +76,12 @@ static const struct pci_device_id mei_me_pci_tbl[] = {
        {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_1, mei_me_pch_cfg)},
        {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_2, mei_me_pch_cfg)},
        {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_3, mei_me_pch_cfg)},
-       {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_H, mei_me_lpt_cfg)},
-       {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_W, mei_me_lpt_cfg)},
-       {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_LP, mei_me_pch_cfg)},
-       {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_HR, mei_me_lpt_cfg)},
-       {MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP, mei_me_pch_cfg)},
-       {MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP_2, mei_me_pch_cfg)},
+       {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_H, mei_me_pch8_sps_cfg)},
+       {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_W, mei_me_pch8_sps_cfg)},
+       {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_LP, mei_me_pch8_cfg)},
+       {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_HR, mei_me_pch8_sps_cfg)},
+       {MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP, mei_me_pch8_cfg)},
+       {MEI_PCI_DEVICE(MEI_DEV_ID_WPT_LP_2, mei_me_pch8_cfg)},
 
        /* required last entry */
        {0, }
This page took 0.055473 seconds and 5 git commands to generate.