[9610][7885][7872][7570] wlbt: reprint last service failure reason
authorIvan Priest <i.priest@samsung.com>
Tue, 1 May 2018 08:44:40 +0000 (09:44 +0100)
committerIvan Priest <i.priest@samsung.com>
Wed, 11 Jul 2018 17:46:30 +0000 (18:46 +0100)
Buffer the reason string from scsc_mx_service_failed() and reprint it
whenever a mxman_open() is rejected due to WLBT being in the failed
state. This allows historical failure reasons to be determined
more easily when they have scrolled out of the kernel log.

Change-Id: I28d7df1aba12b0b55912605071b8c3d2e80e6e76
SCSC-Bug-Id: SSB-39469
Signed-off-by: Ivan Priest <i.priest@samsung.com>
drivers/misc/samsung/scsc/mxman.c
drivers/misc/samsung/scsc/mxman.h
drivers/misc/samsung/scsc/mxproc.c
drivers/misc/samsung/scsc/panicmon.c
drivers/misc/samsung/scsc/scsc_service.c

index 7c13b407bb10076109948d7ed8875d0fc10343cc..4e4e74226564cbb71f225e26e65d6f4b4a45a00c 100755 (executable)
@@ -516,7 +516,7 @@ static void fw_crc_work_func(struct work_struct *work)
        r = do_fw_crc32_checks(mxman->fw, mxman->fw_image_size, &mxman->fwhdr, false);
        if (r) {
                SCSC_TAG_ERR(MXMAN, "do_fw_crc32_checks() failed r=%d\n", r);
-               mxman_fail(mxman, SCSC_PANIC_CODE_HOST << 15);
+               mxman_fail(mxman, SCSC_PANIC_CODE_HOST << 15, __func__);
                return;
        }
        fw_crc_wq_start(mxman);
@@ -1071,6 +1071,8 @@ void mxman_show_last_panic(struct mxman *mxman)
 
        print_panic_code(mxman->scsc_panic_code);
 
+       SCSC_TAG_INFO(MXMAN, "Reason: '%s'\n", mxman->failure_reason[0] ? mxman->failure_reason : "<null>");
+
        if (disable_recovery_handling) {
                /* Labour the point that a reboot is needed when autorecovery is disabled */
                SCSC_TAG_INFO(MXMAN, "\n\n*** HANDSET REBOOT NEEDED TO RESTART WLAN AND BT ***\n\n");
@@ -1230,7 +1232,6 @@ static void mxman_failure_work(struct work_struct *work)
                mxman->last_panic_time = local_clock();
                process_panic_record(mxman);
                SCSC_TAG_INFO(MXMAN, "Trying to schedule coredump\n");
-
                SCSC_TAG_INFO(MXMAN, "scsc_release %d.%d.%d.%d\n",
                        SCSC_RELEASE_PRODUCT,
                        SCSC_RELEASE_ITERATION,
@@ -1431,6 +1432,7 @@ static int __mxman_open(struct mxman *mxman)
        mutex_lock(&mxman->mxman_mutex);
        if (mxman->scsc_panic_code) {
                SCSC_TAG_INFO(MXMAN, "Previously recorded crash panic code: scsc_panic_code=0x%x\n", mxman->scsc_panic_code);
+               SCSC_TAG_INFO(MXMAN, "Reason: '%s'\n", mxman->failure_reason[0] ? mxman->failure_reason : "<null>");
                print_panic_code(mxman->scsc_panic_code);
        }
        srvman = scsc_mx_get_srvman(mxman->mx);
@@ -1640,25 +1642,30 @@ void mxman_close(struct mxman *mxman)
        }
 }
 
-void mxman_fail(struct mxman *mxman, u16 scsc_panic_code)
+void mxman_fail(struct mxman *mxman, u16 scsc_panic_code, const char *reason)
 {
+       SCSC_TAG_WARNING(MXMAN, "WLBT FW failure\n");
+
        /* The STARTING state allows a crash during firmware boot to be handled */
        if (mxman->mxman_state == MXMAN_STATE_STARTED || mxman->mxman_state == MXMAN_STATE_STARTING) {
                mxman->mxman_next_state = MXMAN_STATE_FAILED;
                mxman->scsc_panic_code = scsc_panic_code;
+               strlcpy(mxman->failure_reason, reason, sizeof(mxman->failure_reason));
                failure_wq_start(mxman);
        } else {
-               SCSC_TAG_WARNING(MXMAN, "Not in MXMAN_STATE_STARTED state, ignore\n");
+               SCSC_TAG_WARNING(MXMAN, "Not in MXMAN_STATE_STARTED state, ignore (state %d)\n", mxman->mxman_state);
        }
 }
 
 void mxman_freeze(struct mxman *mxman)
 {
+       SCSC_TAG_WARNING(MXMAN, "WLBT FW frozen\n");
+
        if (mxman->mxman_state == MXMAN_STATE_STARTED) {
                mxman->mxman_next_state = MXMAN_STATE_FREEZED;
                failure_wq_start(mxman);
        } else {
-               SCSC_TAG_WARNING(MXMAN, "Not in MXMAN_STATE_STARTED state, ignore\n");
+               SCSC_TAG_WARNING(MXMAN, "Not in MXMAN_STATE_STARTED state, ignore (state %d)\n", mxman->mxman_state);
        }
 }
 
index 82e310e4c3c6cd4ec6ed085c18c40ad37ea21778..9b9ad5c0aa345b2bbca920f42f570ba43ab5e271 100755 (executable)
@@ -19,7 +19,7 @@ void mxman_init(struct mxman *mxman, struct scsc_mx *mx);
 void mxman_deinit(struct mxman *mxman);
 int mxman_open(struct mxman *mxman);
 void mxman_close(struct mxman *mxman);
-void mxman_fail(struct mxman *mxman, u16 scsc_panic_code);
+void mxman_fail(struct mxman *mxman, u16 scsc_panic_code, const char *reason);
 void mxman_freeze(struct mxman *mxman);
 int mxman_force_panic(struct mxman *mxman);
 int mxman_suspend(struct mxman *mxman);
@@ -39,6 +39,8 @@ enum mxman_state {
        MXMAN_STATE_FREEZED,
 };
 
+#define SCSC_FAILURE_REASON_LEN 256
+
 struct mxman {
        struct scsc_mx          *mx;
        int                     users;
@@ -73,6 +75,7 @@ struct mxman {
 #ifdef CONFIG_SCSC_FM
        u32                     on_halt_ldos_on;
 #endif
+       char                    failure_reason[SCSC_FAILURE_REASON_LEN]; /* previous failure reason */
 };
 
 void mxman_register_gdb_channel(struct scsc_mx *mx, mxmgmt_channel_handler handler, void *data);
index 9ec5a7e1ba5abc9eb22fc82044b36bcc4ac81344..2bca3b7ce41b7c89065a34f743b432c85906d97f 100644 (file)
@@ -114,7 +114,7 @@ static ssize_t mx_procfs_mx_fail_write(struct file *file, const char __user *use
        OS_UNUSED_PARAMETER(ppos);
 
        if (mxproc)
-               mxman_fail(mxproc->mxman, SCSC_PANIC_CODE_HOST << 15);
+               mxman_fail(mxproc->mxman, SCSC_PANIC_CODE_HOST << 15, __func__);
        SCSC_TAG_DEBUG(MX_PROC, "OK\n");
 
        return count;
index 59e88ed8251f3fb43bc1fc7c5c5d7c267ed81cbd..90a960deca1c76eedc7c45ecd79ef53f1c274205 100644 (file)
@@ -17,7 +17,7 @@ static void panicmon_isr(int irq, void *data)
        SCSC_TAG_DEBUG(PANIC_MON, "panicmon=%p panicmon->mx=%p mxman=%p\n", panicmon, panicmon->mx, scsc_mx_get_mxman(panicmon->mx));
        /* Avoid unused parameter error */
        (void)irq;
-       mxman_fail(scsc_mx_get_mxman(panicmon->mx), SCSC_PANIC_CODE_FW << 15);
+       mxman_fail(scsc_mx_get_mxman(panicmon->mx), SCSC_PANIC_CODE_FW << 15, __func__);
 }
 
 
index 27fbcbc390e8693d4a980370c0bc4ac858fca9b0..8dd342dd0428d2e66e41dcb6d03e63fe8c09ec3b 100755 (executable)
@@ -478,7 +478,7 @@ void scsc_mx_service_service_failed(struct scsc_service *service, const char *re
 
        SCSC_TAG_INFO(MXMAN, "Reporting host panic code 0x%02x\n", host_panic_code);
 
-       mxman_fail(scsc_mx_get_mxman(mx), host_panic_code);
+       mxman_fail(scsc_mx_get_mxman(mx), host_panic_code, reason);
 }
 EXPORT_SYMBOL(scsc_mx_service_service_failed);