static void debug_work_func(struct work_struct *work) { unsigned int uSensorCnt; struct ssp_data *data = container_of(work, struct ssp_data, work_debug); ssp_dbg("[SSP]: %s(%u) - Sensor state: 0x%x, RC: %u, CC: %u, TC: %u\n", __func__, data->uIrqCnt, data->uSensorState, data->uResetCnt, data->uComFailCnt, data->uTimeOutCnt); for (uSensorCnt = 0; uSensorCnt < SENSOR_MAX; uSensorCnt++) if ((atomic_read(&data->aSensorEnable) & (1 << uSensorCnt)) || data->batchLatencyBuf[uSensorCnt]) print_sensordata(data, uSensorCnt); if (((atomic_read(&data->aSensorEnable) & (1 << ACCELEROMETER_SENSOR)) && (data->batchLatencyBuf[ACCELEROMETER_SENSOR] == 0) && (data->uIrqCnt == 0) && (data->uTimeOutCnt > 0)) || (data->uTimeOutCnt > LIMIT_TIMEOUT_CNT)) { if (data->uResetCnt < LIMIT_RESET_CNT) { pr_info("[SSP] : %s - uTimeOutCnt(%u), pending(%u)\n", __func__, data->uTimeOutCnt, !list_empty(&data->pending_list)); reset_mcu(data); } else ssp_enable(data, false); data->uTimeOutCnt = 0; data->uComFailCnt = 0; } data->uIrqCnt = 0; }
static void debug_work_func(struct work_struct *work) { unsigned int uSensorCnt; struct ssp_data *data = container_of(work, struct ssp_data, work_debug); static int uTotalIrqCnt = 0; ssp_dbg("[SSP]: %s(%u) - Sensor state: 0x%x, TO: %u, BC: %u, RC: %u\n", __func__, data->uIrqCnt, data->uAliveSensorDebug, data->uTimeOutCnt, data->uBusyCnt, data->uResetCnt); for (uSensorCnt = 0; uSensorCnt < (SENSOR_MAX - 1); uSensorCnt++) if (atomic_read(&data->aSensorEnable) & (1 << uSensorCnt)) print_sensordata(data, uSensorCnt); if((atomic_read(&data->aSensorEnable) & 0x4f) && (data->uIrqCnt == 0)) uTotalIrqCnt++; else uTotalIrqCnt = 0; data->uIrqCnt = 0; if( (uTotalIrqCnt>1) || (data->uSsdFailCnt >= 3) || (data->uInstFailCnt >= 1) || ((data->uTimeOutCnt + data->uBusyCnt) > 5) ) { if (data->uResetCnt < 20) { reset_mcu(data); data->uResetCnt++; } data->uSsdFailCnt = 0; data->uInstFailCnt = 0; uTotalIrqCnt = 0; } }
ssize_t mcu_reset_show(struct device *dev, struct device_attribute *attr, char *buf) { struct ssp_data *data = dev_get_drvdata(dev); reset_mcu(data); return sprintf(buf, "OK\n"); }
static void debug_work_func(struct work_struct *work) { unsigned int uSensorCnt; struct ssp_data *data = container_of(work, struct ssp_data, work_debug); ssp_dbg("[SSP]: %s(%u) - Sensor state: 0x%x, RC: %u, MS: %u\n", __func__, data->uIrqCnt, data->uSensorState, data->uResetCnt, data->uMissSensorCnt); if (data->fw_dl_state >= FW_DL_STATE_DOWNLOADING && data->fw_dl_state < FW_DL_STATE_DONE) { pr_info("[SSP] : %s firmware downloading state = %d\n", __func__, data->fw_dl_state); return; } else if (data->fw_dl_state == FW_DL_STATE_FAIL) { pr_err("[SSP] : %s firmware download failed = %d\n", __func__, data->fw_dl_state); return; } for (uSensorCnt = 0; uSensorCnt < (SENSOR_MAX - 1); uSensorCnt++) if (atomic_read(&data->aSensorEnable) & (1 << uSensorCnt)) print_sensordata(data, uSensorCnt); if ((atomic_read(&data->aSensorEnable) & SSP_BYPASS_SENSORS_EN_ALL)\ && (data->uIrqCnt == 0)) data->uIrqFailCnt++; else data->uIrqFailCnt = 0; if (((data->uSsdFailCnt >= LIMIT_SSD_FAIL_CNT) || (data->uInstFailCnt >= LIMIT_INSTRUCTION_FAIL_CNT) || (data->uIrqFailCnt >= LIMIT_IRQ_FAIL_CNT) || ((data->uTimeOutCnt + data->uBusyCnt) > LIMIT_TIMEOUT_CNT)) && (data->bSspShutdown == false)) { if (data->uResetCnt < LIMIT_RESET_CNT) { pr_info("[SSP] : %s - uSsdFailCnt(%u), uInstFailCnt(%u),"\ "uIrqFailCnt(%u), uTimeOutCnt(%u), uBusyCnt(%u)\n", __func__, data->uSsdFailCnt, data->uInstFailCnt, data->uIrqFailCnt, data->uTimeOutCnt, data->uBusyCnt); reset_mcu(data); data->uResetCnt++; } else ssp_enable(data, false); data->uSsdFailCnt = 0; data->uInstFailCnt = 0; data->uTimeOutCnt = 0; data->uBusyCnt = 0; data->uIrqFailCnt = 0; } data->uIrqCnt = 0; }
static void recovery_mcu(struct ssp_data *data) { if (data->uComFailCnt < LIMIT_RESET_CNT) { ssp_infof("- uTimeOutCnt(%u), pending(%u)", data->uTimeOutCnt, !list_empty(&data->pending_list)); data->uComFailCnt++; reset_mcu(data); } else { ssp_enable(data, false); } data->uTimeOutCnt = 0; }
static void debug_work_func(struct work_struct *work) { unsigned int uSensorCnt; struct ssp_data *data = container_of(work, struct ssp_data, work_debug); ssp_dbg("[SSP]: %s(%u) - Sensor state: 0x%x, RC: %u, MS: %u\n", __func__, data->uIrqCnt, data->uSensorState, data->uResetCnt, data->uMissSensorCnt); for (uSensorCnt = 0; uSensorCnt < (SENSOR_MAX - 1); uSensorCnt++) if (atomic_read(&data->aSensorEnable) & (1 << uSensorCnt)) print_sensordata(data, uSensorCnt); if ((atomic_read(&data->aSensorEnable) & 0x4f) && (data->uIrqCnt == 0)) data->uIrqFailCnt++; else data->uIrqFailCnt = 0; if (((data->uSsdFailCnt >= LIMIT_SSD_FAIL_CNT) || (data->uInstFailCnt >= LIMIT_INSTRUCTION_FAIL_CNT) || (data->uIrqFailCnt >= LIMIT_IRQ_FAIL_CNT) || ((data->uTimeOutCnt + data->uBusyCnt) > LIMIT_TIMEOUT_CNT)) && (data->bSspShutdown == false)) { if (data->uResetCnt < LIMIT_RESET_CNT) { reset_mcu(data); data->uResetCnt++; } else { if (data->bSspShutdown == false) { data->bSspShutdown = true; disable_irq_wake(data->iIrq); disable_irq(data->iIrq); } } data->uSsdFailCnt = 0; data->uInstFailCnt = 0; data->uTimeOutCnt = 0; data->uBusyCnt = 0; data->uIrqFailCnt = 0; } data->uIrqCnt = 0; }
static ssize_t set_enable_irq(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { u8 dTemp; struct ssp_data *data = dev_get_drvdata(dev); if (kstrtou8(buf, 10, &dTemp) < 0) return -1; pr_info("[SSP] %s - %d start\n", __func__, dTemp); if (dTemp) { reset_mcu(data); enable_debug_timer(data); } else if (!dTemp) { disable_debug_timer(data); ssp_enable(data, 0); } else pr_err("[SSP] %s - invalid value\n", __func__); pr_info("[SSP] %s - %d end\n", __func__, dTemp); return size; }
static void debug_polling_func(struct work_struct *work) { struct ssp_data *data = container_of((struct delayed_work *)work, struct ssp_data, polling_work); if (data->bSspShutdown) { pr_err("[SSP] : %s MCU is disabled...\n", __func__); goto out; } if (data->bRefreshing) { pr_err("[SSP] : %s MCU is refreshing another route.....\n", __func__); goto out; } #if 0 /* Check raised IRQ count number */ if (atomic_read(&data->aSensorEnable) & (!data->uSubIrqCnt)) { pr_err("[SSP] : %s(%u) aSensorEnable:0x%x. No irp happened. MCU reset now!\n", __func__, data->uSubIrqCnt, (unsigned int)atomic_read(&data->aSensorEnable)); if(data->bSspShutdown == false) { //reset_mcu(data); goto out; } else pr_err("[SSP] : %s MCU is shutdowned. Could not reset.\n", __func__); goto out; } #endif #if 1 /* Check if Acc data is the same as previous or not. */ /* Check if acc sensor keep working */ if (atomic_read(&data->aSensorEnable) & (1 << ACCELEROMETER_SENSOR)) if(check_abnormal_status(data,ACCELEROMETER_SENSOR)) { pr_err("[SSP] : Acc not working. MCU reset now...\n"); reset_mcu(data); } #endif data->uSubIrqCnt = 0; out: schedule_delayed_work(&data->polling_work, msecs_to_jiffies(SSP_MONITOR_TIME * 1000)); }
static void recovery_mcu(struct ssp_data *data) { if (data->uComFailCnt < LIMIT_RESET_CNT) { pr_info("[SSP] : %s - uTimeOutCnt(%u), pending(%u)\n", __func__, data->uTimeOutCnt, !list_empty(&data->pending_list)); data->uComFailCnt++; #if SSP_STATUS_MONITOR if (data->bRefreshing) { pr_err("[SSP] : %s MCU is refreshing another route....." "Wait 2sec\n", __func__); msleep(2000); } else #endif reset_mcu(data); } else { ssp_enable(data, false); } data->uListEmptyCnt = 0; data->uTimeOutCnt = 0; }
static void debug_work_func(struct work_struct *work) { unsigned int uSensorCnt; struct ssp_data *data = container_of(work, struct ssp_data, work_debug); ssp_dbg("[SSP]: %s(%u) - Sensor state: 0x%x, RC: %u, CC: %u DC: %u TC: %u\n", __func__, data->uIrqCnt, data->uSensorState, data->uResetCnt, data->uComFailCnt, data->uDumpCnt, data->uTimeOutCnt); switch (data->fw_dl_state) { case FW_DL_STATE_FAIL: case FW_DL_STATE_DOWNLOADING: case FW_DL_STATE_SYNC: pr_info("[SSP] : %s firmware downloading state = %d\n", __func__, data->fw_dl_state); return; } for (uSensorCnt = 0; uSensorCnt < SENSOR_MAX; uSensorCnt++) if ((atomic_read(&data->aSensorEnable) & (1 << uSensorCnt)) || data->batchLatencyBuf[uSensorCnt]) print_sensordata(data, uSensorCnt); if (data->uTimeOutCnt > LIMIT_TIMEOUT_CNT) { if (data->uComFailCnt < LIMIT_RESET_CNT) { pr_info("[SSP] : %s - uTimeOutCnt(%u), pending(%u)\n", __func__, data->uTimeOutCnt, !list_empty(&data->pending_list)); data->uComFailCnt++; reset_mcu(data); } else ssp_enable(data, false); data->uTimeOutCnt = 0; } data->uIrqCnt = 0; }
static void debug_work_func(struct work_struct *work) { unsigned int uSensorCnt; struct ssp_data *data = container_of(work, struct ssp_data, work_debug); ssp_dbg("[SSP]: %s(%u) - Sensor state: 0x%x, RC: %u, MS: %u Santi: %u Dump: %u\n", __func__, data->uIrqCnt, data->uSensorState, data->uResetCnt, data->uMissSensorCnt,data->uSanityCnt,data->uDumpCnt); if (data->fw_dl_state >= FW_DL_STATE_DOWNLOADING && data->fw_dl_state < FW_DL_STATE_DONE) { pr_info("[SSP] : %s firmware downloading state = %d\n", __func__, data->fw_dl_state); return; } else if (data->fw_dl_state == FW_DL_STATE_FAIL) { pr_err("[SSP] : %s firmware download failed = %d\n", __func__, data->fw_dl_state); return; } if(sanity_check(data)>0) data->uSanityCnt++; if (set_sensor_position(data) < 0) { pr_err("[SSP]: %s :set_sensor_position delayed \n", __func__); } for (uSensorCnt = 0; uSensorCnt < (SENSOR_MAX); uSensorCnt++) if ((atomic_read(&data->aSensorEnable) & (1 << uSensorCnt)) || data->batchLatencyBuf[uSensorCnt]) print_sensordata(data, uSensorCnt); if (((data->uSsdFailCnt >= LIMIT_SSD_FAIL_CNT) || (data->uInstFailCnt >= LIMIT_INSTRUCTION_FAIL_CNT) || (data->uIrqFailCnt >= LIMIT_IRQ_FAIL_CNT) || ((data->uTimeOutCnt + data->uBusyCnt) > LIMIT_TIMEOUT_CNT)) && (data->bSspShutdown == false)) { if (data->uResetCnt < LIMIT_RESET_CNT) { wake_lock(&data->ssp_wake_lock); pr_info("[SSP] : %s - uSsdFailCnt(%u), uInstFailCnt(%u),"\ "uIrqFailCnt(%u), uTimeOutCnt(%u), uBusyCnt(%u), pending(%u)\n", __func__, data->uSsdFailCnt, data->uInstFailCnt, data->uIrqFailCnt, data->uTimeOutCnt, data->uBusyCnt, !list_empty(&data->pending_list)); reset_mcu(data); data->uResetCnt++; wake_unlock(&data->ssp_wake_lock); } else { pr_info("[SSP] : %s - data->uResetCnt == LIMIT_RESET_CNT\n", __func__); ssp_enable(data, false); } data->uSsdFailCnt = 0; data->uInstFailCnt = 0; data->uTimeOutCnt = 0; data->uBusyCnt = 0; data->uIrqFailCnt = 0; } data->uIrqCnt = 0; }
// set from an X command cbm_errno_t rtconfig_set(rtconfig_t *rtc, const char *cmd) { charset_t new_charset = -1; debug_printf("CMD:'%s'\n", cmd); cbm_errno_t er = CBM_ERROR_SYNTAX_UNKNOWN; const char *ptr = cmd; char c = *ptr; while (c != 0 && c !='X') { ptr++; c = *ptr; } do { ptr++; c = *ptr; } while (c == ' '); // c now contains the actual command switch(c) { case '*': // enable/disable the use of advanced wildcards // look for *=+ || *=- if (*++ptr == '=') { if (*++ptr == '+') { rtc->advanced_wildcards = true; er = CBM_ERROR_OK; } else if (*ptr == '-') { rtc->advanced_wildcards = false; er = CBM_ERROR_OK; } if (er == CBM_ERROR_OK) { debug_puts("ADVANCED WILDCARDS "); if (rtc->advanced_wildcards) debug_puts("EN"); else debug_puts("DIS"); debug_puts("ABLED\n"); } } break; case 'E': // enable/disable the drive number on error messages // look for E=+ || E=- if (*++ptr == '=') { if (*++ptr == '+') { rtc->errmsg_with_drive = true; er = CBM_ERROR_OK; } else if (*ptr == '-') { rtc->errmsg_with_drive = false; er = CBM_ERROR_OK; } if (er == CBM_ERROR_OK) { debug_puts("ERRORS WITH DRIVE "); if (rtc->advanced_wildcards) debug_puts("EN"); else debug_puts("DIS"); debug_puts("ABLED\n"); } } break; case 'U': // look for "U=<unit number in ascii || binary>" ptr++; if (*ptr == '=') { ptr++; uint8_t devaddr = (*ptr); if (isdigit(*ptr)) devaddr = atoi(ptr); if (devaddr >= 4 && devaddr <= 30) { rtc->device_address = devaddr; er = CBM_ERROR_OK; debug_printf("SETTING UNIT# TO %d ON %s\n", devaddr, rtc->name); } else { er = CBM_ERROR_SYNTAX_INVAL; debug_printf("ERROR SETTING UNIT# TO %d ON %s\n", devaddr, rtc->name); } } break; case 'D': // set default drive number // look for "D=<drive number in ascii || binary>" ptr++; if (*ptr == '=') { ptr++; uint8_t drv = (*ptr); if (isdigit(*ptr)) drv=atoi(ptr); if (drv < MAX_DRIVES) { rtc->last_used_drive = drv; er = CBM_ERROR_OK; debug_printf("SETTING DRIVE# TO %d ON %s\n", drv, rtc->name); } } break; case 'I': // INIT: restore default values rtconfig_init_rtc(rtc, get_default_device_address()); er = CBM_ERROR_OK; debug_puts("RUNTIME CONFIG INITIALIZED\n"); break; case 'W': // write runtime config to EEPROM nv_save_common_config(); er = nv_save_config(rtc); break; case 'R': if(!strncmp(ptr, "RESET", 5)) { // ignore CR or whatever follows // reset everything reset_mcu(); } case 'C': // TEST code // look for "C=<charsetname>" ptr++; if (*ptr == '=') { ptr++; new_charset = cconv_getcharset(ptr); if (new_charset >= 0) { current_charset = new_charset; do_charset(); er = CBM_ERROR_OK; } } break; default: break; } return er; }