Loading drivers/char/diag/diag_dci.c +8 −22 Original line number Diff line number Diff line Loading @@ -2868,7 +2868,8 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry) int diag_dci_write_proc(int peripheral, int pkt_type, char *buf, int len) { struct diag_smd_info *smd_info = NULL; int wr_size = 0, retry = 0, err = -EAGAIN, timer = 0, i; int i; int err = 0; if (!buf || (peripheral < 0 || peripheral > NUM_SMD_DCI_CHANNELS) || len < 0) { Loading Loading @@ -2897,28 +2898,13 @@ int diag_dci_write_proc(int peripheral, int pkt_type, char *buf, int len) if (!smd_info || !smd_info->ch) return -EINVAL; while (retry < 3) { mutex_lock(&smd_info->smd_ch_mutex); wr_size = smd_write(smd_info->ch, buf, len); if (wr_size == len) { pr_debug("diag: successfully wrote pkt_type %d of len %d to %d in trial %d", pkt_type, len, peripheral, (retry+1)); err = DIAG_DCI_NO_ERROR; mutex_unlock(&smd_info->smd_ch_mutex); break; err = diag_smd_write(smd_info, buf, len); if (err) { pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, len: %d, err: %d\n", __func__, smd_info->peripheral, smd_info->type, len, err); } pr_debug("diag: cannot write pkt_type %d of len %d to %d in trial %d", pkt_type, len, peripheral, (retry+1)); retry++; mutex_unlock(&smd_info->smd_ch_mutex); /* * Sleep for sometime before retrying. The delay of 2000 was * determined empirically as best value to use. */ for (timer = 0; timer < 5; timer++) usleep(2000); } return err; } Loading drivers/char/diag/diag_masks.c +32 −84 Original line number Diff line number Diff line Loading @@ -345,8 +345,8 @@ void diag_send_log_mask_update(struct diag_smd_info *smd_info, int equip_id) struct diag_log_mask_t *log_item = NULL; struct diag_ctrl_log_mask ctrl_pkt; uint32_t log_mask_size = 0; int wr_size = -ENOMEM, retry_count = 0; int i, header_size, send_once = 0; int err = 0; if (!smd_info) { pr_err("diag: In %s, null smd info pointer\n", Loading Loading @@ -396,26 +396,13 @@ void diag_send_log_mask_update(struct diag_smd_info *smd_info, int equip_id) log_mask_size); } if (smd_info->ch) { while (retry_count < 3) { mutex_lock(&smd_info->smd_ch_mutex); wr_size = smd_write(smd_info->ch, buf, err = diag_smd_write(smd_info, buf, header_size + log_mask_size); mutex_unlock(&smd_info->smd_ch_mutex); if (wr_size == -ENOMEM) { retry_count++; usleep_range(10000, 10100); } else break; if (err) { pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, len: %d, err: %d\n", __func__, smd_info->peripheral, smd_info->type, header_size + log_mask_size, err); } if (wr_size != header_size + log_mask_size) pr_err("diag: log mask update failed %d, tried %d", wr_size, header_size + log_mask_size); else pr_debug("diag: updated log equip ID %d,len %d\n", i, log_mask_size); } else pr_err("diag: ch not valid for log update\n"); if (send_once) break; } Loading @@ -427,7 +414,7 @@ void diag_send_event_mask_update(struct diag_smd_info *smd_info, int num_bytes) { void *buf = driver->buf_event_mask_update; int header_size = sizeof(struct diag_ctrl_event_mask); int wr_size = -ENOMEM, retry_count = 0; int err = 0; if (!smd_info) { pr_err("diag: In %s, null smd info pointer\n", Loading Loading @@ -473,23 +460,13 @@ void diag_send_event_mask_update(struct diag_smd_info *smd_info, int num_bytes) return; } memcpy(buf, driver->event_mask, header_size); if (smd_info->ch) { while (retry_count < 3) { mutex_lock(&smd_info->smd_ch_mutex); wr_size = smd_write(smd_info->ch, buf, header_size + num_bytes); mutex_unlock(&smd_info->smd_ch_mutex); if (wr_size == -ENOMEM) { retry_count++; usleep_range(10000, 10100); } else break; err = diag_smd_write(smd_info, buf, header_size + num_bytes); if (err) { pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, len: %d, err: %d\n", __func__, smd_info->peripheral, smd_info->type, header_size + num_bytes, err); } if (wr_size != header_size + num_bytes) pr_err("diag: error writing event mask %d, tried %d\n", wr_size, header_size + num_bytes); } else pr_err("diag: ch not valid for event update\n"); mutex_unlock(&driver->diag_cntl_mutex); } Loading @@ -498,9 +475,11 @@ void diag_send_msg_mask_update(struct diag_smd_info *smd_info, int proc) { void *buf = driver->buf_msg_mask_update; int first, last, actual_last, size = -ENOMEM, retry_count = 0; int first, last, actual_last; int header_size = sizeof(struct diag_ctrl_msg_mask); uint8_t *ptr = driver->msg_masks; int err = 0; int write_len = 0; if (!smd_info) { pr_err("diag: In %s, null smd info pointer\n", Loading Loading @@ -566,29 +545,13 @@ void diag_send_msg_mask_update(struct diag_smd_info *smd_info, driver->msg_mask->ssid_first = first; driver->msg_mask->ssid_last = actual_last; memcpy(buf, driver->msg_mask, header_size); if (smd_info->ch) { while (retry_count < 3) { mutex_lock(&smd_info->smd_ch_mutex); size = smd_write(smd_info->ch, buf, header_size + 4*(driver->msg_mask->msg_mask_size)); mutex_unlock(&smd_info->smd_ch_mutex); if (size == -ENOMEM) { retry_count++; usleep_range(10000, 10100); } else break; write_len = header_size + 4 * driver->msg_mask->msg_mask_size; err = diag_smd_write(smd_info, buf, write_len); if (err) { pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, len: %d, err: %d\n", __func__, smd_info->peripheral, smd_info->type, write_len, err); } if (size != header_size + 4*(driver->msg_mask->msg_mask_size)) pr_err("diag: proc %d, msg mask update fail %d, tried %d\n", proc, size, (header_size + 4*(driver->msg_mask->msg_mask_size))); else pr_debug("diag: sending mask update for ssid first %d, last %d on PROC %d\n", first, actual_last, proc); } else pr_err("diag: proc %d, ch invalid msg mask update\n", proc); ptr += MAX_SSID_PER_RANGE*4; } mutex_unlock(&driver->diag_cntl_mutex); Loading @@ -598,9 +561,9 @@ void diag_send_feature_mask_update(struct diag_smd_info *smd_info) { void *buf = driver->buf_feature_mask_update; int header_size = sizeof(struct diag_ctrl_feature_mask); int wr_size = -ENOMEM, retry_count = 0; uint8_t feature_bytes[FEATURE_MASK_LEN_BYTES] = {0, 0}; int total_len = 0; int err = 0; if (!smd_info) { pr_err("diag: In %s, null smd info pointer\n", Loading Loading @@ -630,27 +593,12 @@ void diag_send_feature_mask_update(struct diag_smd_info *smd_info) memcpy(buf+header_size, &feature_bytes, FEATURE_MASK_LEN_BYTES); total_len = header_size + FEATURE_MASK_LEN_BYTES; while (retry_count < 3) { mutex_lock(&smd_info->smd_ch_mutex); wr_size = smd_write(smd_info->ch, buf, total_len); mutex_unlock(&smd_info->smd_ch_mutex); if (wr_size == -ENOMEM) { retry_count++; /* * The smd channel is full. Delay while * smd processes existing data and smd * has memory become available. The delay * of 10000 was determined empirically as * best value to use. */ usleep_range(10000, 10100); } else break; err = diag_smd_write(smd_info, buf, total_len); if (err) { pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, len: %d, err: %d\n", __func__, smd_info->peripheral, smd_info->type, total_len, err); } if (wr_size != total_len) pr_err("diag: In %s, peripheral %d fail feature update, size: %d, tried: %d", __func__, smd_info->peripheral, wr_size, total_len); mutex_unlock(&driver->diag_cntl_mutex); } Loading drivers/char/diag/diagfwd.c +57 −22 Original line number Diff line number Diff line Loading @@ -1060,6 +1060,7 @@ int diag_send_data(struct diag_master_table entry, unsigned char *buf, int len, int type) { int success = 1; int err = 0; driver->pkt_length = len; /* If the process_id corresponds to an apps process */ Loading @@ -1086,16 +1087,11 @@ int diag_send_data(struct diag_master_table entry, unsigned char *buf, index < NUM_SMD_CMD_CHANNELS) ? &driver->smd_cmd[index] : &driver->smd_data[index]; if (smd_info->ch) { mutex_lock(&smd_info->smd_ch_mutex); smd_write(smd_info->ch, buf, len); mutex_unlock(&smd_info->smd_ch_mutex); } else { pr_err("diag: In %s, smd channel %d not open, peripheral: %d, type: %d\n", __func__, index, smd_info->peripheral, smd_info->type); err = diag_smd_write(smd_info, buf, len); if (err) { pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, err: %d\n", __func__, smd_info->peripheral, smd_info->type, err); } } else { pr_alert("diag: In %s, incorrect channel: %d", Loading Loading @@ -1716,6 +1712,7 @@ void diag_process_hdlc(void *data, unsigned len) { struct diag_hdlc_decode_type hdlc; int ret, type = 0, crc_chk = 0; int err = 0; mutex_lock(&driver->diag_hdlc_mutex); Loading Loading @@ -1777,14 +1774,13 @@ void diag_process_hdlc(void *data, unsigned len) if (chk_apps_only()) { diag_send_error_rsp(hdlc.dest_idx); } else { /* APQ 8060, Let Q6 respond */ if (driver->smd_data[LPASS_DATA].ch) { mutex_lock(&driver->smd_data[LPASS_DATA]. smd_ch_mutex); smd_write(driver->smd_data[LPASS_DATA].ch, err = diag_smd_write(&driver->smd_data[LPASS_DATA], driver->hdlc_buf, hdlc.dest_idx - 3); mutex_unlock(&driver->smd_data[LPASS_DATA]. smd_ch_mutex); if (err) { pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, err: %d\n", __func__, LPASS_DATA, SMD_DATA_TYPE, err); } } type = 0; Loading @@ -1800,10 +1796,12 @@ void diag_process_hdlc(void *data, unsigned len) if ((driver->smd_data[MODEM_DATA].ch) && (ret) && (type) && (hdlc.dest_idx > 3)) { APPEND_DEBUG('g'); mutex_lock(&driver->smd_data[MODEM_DATA].smd_ch_mutex); smd_write(driver->smd_data[MODEM_DATA].ch, err = diag_smd_write(&driver->smd_data[MODEM_DATA], driver->hdlc_buf, hdlc.dest_idx - 3); mutex_unlock(&driver->smd_data[MODEM_DATA].smd_ch_mutex); if (err) { pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, err: %d\n", __func__, MODEM_DATA, SMD_DATA_TYPE, err); } APPEND_DEBUG('h'); #ifdef DIAG_DEBUG printk(KERN_INFO "writing data to SMD, pkt length %d\n", len); Loading Loading @@ -2490,6 +2488,43 @@ err: return -ENOMEM; } int diag_smd_write(struct diag_smd_info *smd_info, void *buf, int len) { int write_len = 0; int retry_count = 0; int max_retries = 3; if (!smd_info || !buf || len <= 0) { pr_err_ratelimited("diag: In %s, invalid params, smd_info: %p, buf: %p, len: %d\n", __func__, smd_info, buf, len); return -EINVAL; } if (!smd_info->ch) return -ENODEV; do { mutex_lock(&smd_info->smd_ch_mutex); write_len = smd_write(smd_info->ch, buf, len); mutex_unlock(&smd_info->smd_ch_mutex); if (write_len == len) break; /* * The channel maybe busy - the FIFO can be full. Retry after * sometime. The value of 10000 was chosen emprically as the * optimal value for the peripherals to read data from the SMD * channel. */ usleep_range(10000, 10100); retry_count++; } while (retry_count < max_retries); if (write_len != len) return -ENOMEM; return 0; } int diagfwd_init(void) { int ret; Loading drivers/char/diag/diagfwd.h +1 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ int diagfwd_init(void); void diagfwd_exit(void); int diag_smd_write(struct diag_smd_info *smd_info, void *buf, int len); void diag_process_hdlc(void *data, unsigned len); void diag_smd_send_req(struct diag_smd_info *smd_info); void diag_usb_legacy_notifier(void *, unsigned, struct diag_request *); Loading drivers/char/diag/diagfwd_cntl.c +15 −57 Original line number Diff line number Diff line Loading @@ -493,8 +493,8 @@ void diag_send_diag_mode_update_by_smd(struct diag_smd_info *smd_info, { char buf[sizeof(struct diag_ctrl_msg_diagmode)]; int msg_size = sizeof(struct diag_ctrl_msg_diagmode); int wr_size = -ENOMEM, retry_count = 0, timer; struct diag_smd_info *data = NULL; int err = 0; if (!smd_info || smd_info->type != SMD_CNTL_TYPE) { pr_err("diag: In %s, invalid channel info, smd_info: %p type: %d\n", Loading @@ -517,37 +517,13 @@ void diag_send_diag_mode_update_by_smd(struct diag_smd_info *smd_info, diag_create_diag_mode_ctrl_pkt(buf, real_time); mutex_lock(&driver->diag_cntl_mutex); if (smd_info->ch) { while (retry_count < 3) { mutex_lock(&smd_info->smd_ch_mutex); wr_size = smd_write(smd_info->ch, buf, msg_size); mutex_unlock(&smd_info->smd_ch_mutex); if (wr_size == -ENOMEM) { /* * The smd channel is full. Delay while * smd processes existing data and smd * has memory become available. The delay * of 2000 was determined empirically as * best value to use. */ retry_count++; for (timer = 0; timer < 5; timer++) udelay(2000); err = diag_smd_write(smd_info, buf, msg_size); if (err) { pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, len: %d, err: %d\n", __func__, smd_info->peripheral, smd_info->type, msg_size, err); } else { data = &driver->smd_data[smd_info->peripheral]; driver->real_time_mode[DIAG_LOCAL_PROC] = real_time; break; } } if (wr_size != msg_size) pr_err("diag: proc %d fail feature update %d, tried %d", smd_info->peripheral, wr_size, msg_size); } else { pr_err("diag: ch invalid, feature update on proc %d\n", smd_info->peripheral); driver->real_time_mode[DIAG_LOCAL_PROC] = real_time; } mutex_unlock(&driver->diag_cntl_mutex); Loading @@ -558,9 +534,8 @@ int diag_send_stm_state(struct diag_smd_info *smd_info, { struct diag_ctrl_msg_stm stm_msg; int msg_size = sizeof(struct diag_ctrl_msg_stm); int retry_count = 0; int wr_size = 0; int success = 0; int err = 0; if (!smd_info || (smd_info->type != SMD_CNTL_TYPE) || (driver->peripheral_supports_stm[smd_info->peripheral] == Loading @@ -573,30 +548,13 @@ int diag_send_stm_state(struct diag_smd_info *smd_info, stm_msg.ctrl_pkt_data_len = 5; stm_msg.version = 1; stm_msg.control_data = stm_control_data; while (retry_count < 3) { mutex_lock(&smd_info->smd_ch_mutex); wr_size = smd_write(smd_info->ch, &stm_msg, msg_size); mutex_unlock(&smd_info->smd_ch_mutex); if (wr_size == -ENOMEM) { /* * The smd channel is full. Delay while * smd processes existing data and smd * has memory become available. The delay * of 10000 was determined empirically as * best value to use. */ retry_count++; usleep_range(10000, 10000); err = diag_smd_write(smd_info, &stm_msg, msg_size); if (err) { pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, len: %d, err: %d\n", __func__, smd_info->peripheral, smd_info->type, msg_size, err); } else { success = 1; break; } } if (wr_size != msg_size) { pr_err("diag: In %s, proc %d fail STM update %d, tried %d", __func__, smd_info->peripheral, wr_size, msg_size); success = 0; } } else { pr_err("diag: In %s, ch invalid, STM update on proc %d\n", Loading Loading
drivers/char/diag/diag_dci.c +8 −22 Original line number Diff line number Diff line Loading @@ -2868,7 +2868,8 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry) int diag_dci_write_proc(int peripheral, int pkt_type, char *buf, int len) { struct diag_smd_info *smd_info = NULL; int wr_size = 0, retry = 0, err = -EAGAIN, timer = 0, i; int i; int err = 0; if (!buf || (peripheral < 0 || peripheral > NUM_SMD_DCI_CHANNELS) || len < 0) { Loading Loading @@ -2897,28 +2898,13 @@ int diag_dci_write_proc(int peripheral, int pkt_type, char *buf, int len) if (!smd_info || !smd_info->ch) return -EINVAL; while (retry < 3) { mutex_lock(&smd_info->smd_ch_mutex); wr_size = smd_write(smd_info->ch, buf, len); if (wr_size == len) { pr_debug("diag: successfully wrote pkt_type %d of len %d to %d in trial %d", pkt_type, len, peripheral, (retry+1)); err = DIAG_DCI_NO_ERROR; mutex_unlock(&smd_info->smd_ch_mutex); break; err = diag_smd_write(smd_info, buf, len); if (err) { pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, len: %d, err: %d\n", __func__, smd_info->peripheral, smd_info->type, len, err); } pr_debug("diag: cannot write pkt_type %d of len %d to %d in trial %d", pkt_type, len, peripheral, (retry+1)); retry++; mutex_unlock(&smd_info->smd_ch_mutex); /* * Sleep for sometime before retrying. The delay of 2000 was * determined empirically as best value to use. */ for (timer = 0; timer < 5; timer++) usleep(2000); } return err; } Loading
drivers/char/diag/diag_masks.c +32 −84 Original line number Diff line number Diff line Loading @@ -345,8 +345,8 @@ void diag_send_log_mask_update(struct diag_smd_info *smd_info, int equip_id) struct diag_log_mask_t *log_item = NULL; struct diag_ctrl_log_mask ctrl_pkt; uint32_t log_mask_size = 0; int wr_size = -ENOMEM, retry_count = 0; int i, header_size, send_once = 0; int err = 0; if (!smd_info) { pr_err("diag: In %s, null smd info pointer\n", Loading Loading @@ -396,26 +396,13 @@ void diag_send_log_mask_update(struct diag_smd_info *smd_info, int equip_id) log_mask_size); } if (smd_info->ch) { while (retry_count < 3) { mutex_lock(&smd_info->smd_ch_mutex); wr_size = smd_write(smd_info->ch, buf, err = diag_smd_write(smd_info, buf, header_size + log_mask_size); mutex_unlock(&smd_info->smd_ch_mutex); if (wr_size == -ENOMEM) { retry_count++; usleep_range(10000, 10100); } else break; if (err) { pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, len: %d, err: %d\n", __func__, smd_info->peripheral, smd_info->type, header_size + log_mask_size, err); } if (wr_size != header_size + log_mask_size) pr_err("diag: log mask update failed %d, tried %d", wr_size, header_size + log_mask_size); else pr_debug("diag: updated log equip ID %d,len %d\n", i, log_mask_size); } else pr_err("diag: ch not valid for log update\n"); if (send_once) break; } Loading @@ -427,7 +414,7 @@ void diag_send_event_mask_update(struct diag_smd_info *smd_info, int num_bytes) { void *buf = driver->buf_event_mask_update; int header_size = sizeof(struct diag_ctrl_event_mask); int wr_size = -ENOMEM, retry_count = 0; int err = 0; if (!smd_info) { pr_err("diag: In %s, null smd info pointer\n", Loading Loading @@ -473,23 +460,13 @@ void diag_send_event_mask_update(struct diag_smd_info *smd_info, int num_bytes) return; } memcpy(buf, driver->event_mask, header_size); if (smd_info->ch) { while (retry_count < 3) { mutex_lock(&smd_info->smd_ch_mutex); wr_size = smd_write(smd_info->ch, buf, header_size + num_bytes); mutex_unlock(&smd_info->smd_ch_mutex); if (wr_size == -ENOMEM) { retry_count++; usleep_range(10000, 10100); } else break; err = diag_smd_write(smd_info, buf, header_size + num_bytes); if (err) { pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, len: %d, err: %d\n", __func__, smd_info->peripheral, smd_info->type, header_size + num_bytes, err); } if (wr_size != header_size + num_bytes) pr_err("diag: error writing event mask %d, tried %d\n", wr_size, header_size + num_bytes); } else pr_err("diag: ch not valid for event update\n"); mutex_unlock(&driver->diag_cntl_mutex); } Loading @@ -498,9 +475,11 @@ void diag_send_msg_mask_update(struct diag_smd_info *smd_info, int proc) { void *buf = driver->buf_msg_mask_update; int first, last, actual_last, size = -ENOMEM, retry_count = 0; int first, last, actual_last; int header_size = sizeof(struct diag_ctrl_msg_mask); uint8_t *ptr = driver->msg_masks; int err = 0; int write_len = 0; if (!smd_info) { pr_err("diag: In %s, null smd info pointer\n", Loading Loading @@ -566,29 +545,13 @@ void diag_send_msg_mask_update(struct diag_smd_info *smd_info, driver->msg_mask->ssid_first = first; driver->msg_mask->ssid_last = actual_last; memcpy(buf, driver->msg_mask, header_size); if (smd_info->ch) { while (retry_count < 3) { mutex_lock(&smd_info->smd_ch_mutex); size = smd_write(smd_info->ch, buf, header_size + 4*(driver->msg_mask->msg_mask_size)); mutex_unlock(&smd_info->smd_ch_mutex); if (size == -ENOMEM) { retry_count++; usleep_range(10000, 10100); } else break; write_len = header_size + 4 * driver->msg_mask->msg_mask_size; err = diag_smd_write(smd_info, buf, write_len); if (err) { pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, len: %d, err: %d\n", __func__, smd_info->peripheral, smd_info->type, write_len, err); } if (size != header_size + 4*(driver->msg_mask->msg_mask_size)) pr_err("diag: proc %d, msg mask update fail %d, tried %d\n", proc, size, (header_size + 4*(driver->msg_mask->msg_mask_size))); else pr_debug("diag: sending mask update for ssid first %d, last %d on PROC %d\n", first, actual_last, proc); } else pr_err("diag: proc %d, ch invalid msg mask update\n", proc); ptr += MAX_SSID_PER_RANGE*4; } mutex_unlock(&driver->diag_cntl_mutex); Loading @@ -598,9 +561,9 @@ void diag_send_feature_mask_update(struct diag_smd_info *smd_info) { void *buf = driver->buf_feature_mask_update; int header_size = sizeof(struct diag_ctrl_feature_mask); int wr_size = -ENOMEM, retry_count = 0; uint8_t feature_bytes[FEATURE_MASK_LEN_BYTES] = {0, 0}; int total_len = 0; int err = 0; if (!smd_info) { pr_err("diag: In %s, null smd info pointer\n", Loading Loading @@ -630,27 +593,12 @@ void diag_send_feature_mask_update(struct diag_smd_info *smd_info) memcpy(buf+header_size, &feature_bytes, FEATURE_MASK_LEN_BYTES); total_len = header_size + FEATURE_MASK_LEN_BYTES; while (retry_count < 3) { mutex_lock(&smd_info->smd_ch_mutex); wr_size = smd_write(smd_info->ch, buf, total_len); mutex_unlock(&smd_info->smd_ch_mutex); if (wr_size == -ENOMEM) { retry_count++; /* * The smd channel is full. Delay while * smd processes existing data and smd * has memory become available. The delay * of 10000 was determined empirically as * best value to use. */ usleep_range(10000, 10100); } else break; err = diag_smd_write(smd_info, buf, total_len); if (err) { pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, len: %d, err: %d\n", __func__, smd_info->peripheral, smd_info->type, total_len, err); } if (wr_size != total_len) pr_err("diag: In %s, peripheral %d fail feature update, size: %d, tried: %d", __func__, smd_info->peripheral, wr_size, total_len); mutex_unlock(&driver->diag_cntl_mutex); } Loading
drivers/char/diag/diagfwd.c +57 −22 Original line number Diff line number Diff line Loading @@ -1060,6 +1060,7 @@ int diag_send_data(struct diag_master_table entry, unsigned char *buf, int len, int type) { int success = 1; int err = 0; driver->pkt_length = len; /* If the process_id corresponds to an apps process */ Loading @@ -1086,16 +1087,11 @@ int diag_send_data(struct diag_master_table entry, unsigned char *buf, index < NUM_SMD_CMD_CHANNELS) ? &driver->smd_cmd[index] : &driver->smd_data[index]; if (smd_info->ch) { mutex_lock(&smd_info->smd_ch_mutex); smd_write(smd_info->ch, buf, len); mutex_unlock(&smd_info->smd_ch_mutex); } else { pr_err("diag: In %s, smd channel %d not open, peripheral: %d, type: %d\n", __func__, index, smd_info->peripheral, smd_info->type); err = diag_smd_write(smd_info, buf, len); if (err) { pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, err: %d\n", __func__, smd_info->peripheral, smd_info->type, err); } } else { pr_alert("diag: In %s, incorrect channel: %d", Loading Loading @@ -1716,6 +1712,7 @@ void diag_process_hdlc(void *data, unsigned len) { struct diag_hdlc_decode_type hdlc; int ret, type = 0, crc_chk = 0; int err = 0; mutex_lock(&driver->diag_hdlc_mutex); Loading Loading @@ -1777,14 +1774,13 @@ void diag_process_hdlc(void *data, unsigned len) if (chk_apps_only()) { diag_send_error_rsp(hdlc.dest_idx); } else { /* APQ 8060, Let Q6 respond */ if (driver->smd_data[LPASS_DATA].ch) { mutex_lock(&driver->smd_data[LPASS_DATA]. smd_ch_mutex); smd_write(driver->smd_data[LPASS_DATA].ch, err = diag_smd_write(&driver->smd_data[LPASS_DATA], driver->hdlc_buf, hdlc.dest_idx - 3); mutex_unlock(&driver->smd_data[LPASS_DATA]. smd_ch_mutex); if (err) { pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, err: %d\n", __func__, LPASS_DATA, SMD_DATA_TYPE, err); } } type = 0; Loading @@ -1800,10 +1796,12 @@ void diag_process_hdlc(void *data, unsigned len) if ((driver->smd_data[MODEM_DATA].ch) && (ret) && (type) && (hdlc.dest_idx > 3)) { APPEND_DEBUG('g'); mutex_lock(&driver->smd_data[MODEM_DATA].smd_ch_mutex); smd_write(driver->smd_data[MODEM_DATA].ch, err = diag_smd_write(&driver->smd_data[MODEM_DATA], driver->hdlc_buf, hdlc.dest_idx - 3); mutex_unlock(&driver->smd_data[MODEM_DATA].smd_ch_mutex); if (err) { pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, err: %d\n", __func__, MODEM_DATA, SMD_DATA_TYPE, err); } APPEND_DEBUG('h'); #ifdef DIAG_DEBUG printk(KERN_INFO "writing data to SMD, pkt length %d\n", len); Loading Loading @@ -2490,6 +2488,43 @@ err: return -ENOMEM; } int diag_smd_write(struct diag_smd_info *smd_info, void *buf, int len) { int write_len = 0; int retry_count = 0; int max_retries = 3; if (!smd_info || !buf || len <= 0) { pr_err_ratelimited("diag: In %s, invalid params, smd_info: %p, buf: %p, len: %d\n", __func__, smd_info, buf, len); return -EINVAL; } if (!smd_info->ch) return -ENODEV; do { mutex_lock(&smd_info->smd_ch_mutex); write_len = smd_write(smd_info->ch, buf, len); mutex_unlock(&smd_info->smd_ch_mutex); if (write_len == len) break; /* * The channel maybe busy - the FIFO can be full. Retry after * sometime. The value of 10000 was chosen emprically as the * optimal value for the peripherals to read data from the SMD * channel. */ usleep_range(10000, 10100); retry_count++; } while (retry_count < max_retries); if (write_len != len) return -ENOMEM; return 0; } int diagfwd_init(void) { int ret; Loading
drivers/char/diag/diagfwd.h +1 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ int diagfwd_init(void); void diagfwd_exit(void); int diag_smd_write(struct diag_smd_info *smd_info, void *buf, int len); void diag_process_hdlc(void *data, unsigned len); void diag_smd_send_req(struct diag_smd_info *smd_info); void diag_usb_legacy_notifier(void *, unsigned, struct diag_request *); Loading
drivers/char/diag/diagfwd_cntl.c +15 −57 Original line number Diff line number Diff line Loading @@ -493,8 +493,8 @@ void diag_send_diag_mode_update_by_smd(struct diag_smd_info *smd_info, { char buf[sizeof(struct diag_ctrl_msg_diagmode)]; int msg_size = sizeof(struct diag_ctrl_msg_diagmode); int wr_size = -ENOMEM, retry_count = 0, timer; struct diag_smd_info *data = NULL; int err = 0; if (!smd_info || smd_info->type != SMD_CNTL_TYPE) { pr_err("diag: In %s, invalid channel info, smd_info: %p type: %d\n", Loading @@ -517,37 +517,13 @@ void diag_send_diag_mode_update_by_smd(struct diag_smd_info *smd_info, diag_create_diag_mode_ctrl_pkt(buf, real_time); mutex_lock(&driver->diag_cntl_mutex); if (smd_info->ch) { while (retry_count < 3) { mutex_lock(&smd_info->smd_ch_mutex); wr_size = smd_write(smd_info->ch, buf, msg_size); mutex_unlock(&smd_info->smd_ch_mutex); if (wr_size == -ENOMEM) { /* * The smd channel is full. Delay while * smd processes existing data and smd * has memory become available. The delay * of 2000 was determined empirically as * best value to use. */ retry_count++; for (timer = 0; timer < 5; timer++) udelay(2000); err = diag_smd_write(smd_info, buf, msg_size); if (err) { pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, len: %d, err: %d\n", __func__, smd_info->peripheral, smd_info->type, msg_size, err); } else { data = &driver->smd_data[smd_info->peripheral]; driver->real_time_mode[DIAG_LOCAL_PROC] = real_time; break; } } if (wr_size != msg_size) pr_err("diag: proc %d fail feature update %d, tried %d", smd_info->peripheral, wr_size, msg_size); } else { pr_err("diag: ch invalid, feature update on proc %d\n", smd_info->peripheral); driver->real_time_mode[DIAG_LOCAL_PROC] = real_time; } mutex_unlock(&driver->diag_cntl_mutex); Loading @@ -558,9 +534,8 @@ int diag_send_stm_state(struct diag_smd_info *smd_info, { struct diag_ctrl_msg_stm stm_msg; int msg_size = sizeof(struct diag_ctrl_msg_stm); int retry_count = 0; int wr_size = 0; int success = 0; int err = 0; if (!smd_info || (smd_info->type != SMD_CNTL_TYPE) || (driver->peripheral_supports_stm[smd_info->peripheral] == Loading @@ -573,30 +548,13 @@ int diag_send_stm_state(struct diag_smd_info *smd_info, stm_msg.ctrl_pkt_data_len = 5; stm_msg.version = 1; stm_msg.control_data = stm_control_data; while (retry_count < 3) { mutex_lock(&smd_info->smd_ch_mutex); wr_size = smd_write(smd_info->ch, &stm_msg, msg_size); mutex_unlock(&smd_info->smd_ch_mutex); if (wr_size == -ENOMEM) { /* * The smd channel is full. Delay while * smd processes existing data and smd * has memory become available. The delay * of 10000 was determined empirically as * best value to use. */ retry_count++; usleep_range(10000, 10000); err = diag_smd_write(smd_info, &stm_msg, msg_size); if (err) { pr_err("diag: In %s, unable to write to smd, peripheral: %d, type: %d, len: %d, err: %d\n", __func__, smd_info->peripheral, smd_info->type, msg_size, err); } else { success = 1; break; } } if (wr_size != msg_size) { pr_err("diag: In %s, proc %d fail STM update %d, tried %d", __func__, smd_info->peripheral, wr_size, msg_size); success = 0; } } else { pr_err("diag: In %s, ch invalid, STM update on proc %d\n", Loading