Loading drivers/char/diag/diagchar.h +1 −0 Original line number Diff line number Diff line Loading @@ -578,6 +578,7 @@ struct diagchar_dev { unsigned char *buf_feature_mask_update; uint8_t hdlc_disabled; struct mutex hdlc_disable_mutex; struct mutex hdlc_recovery_mutex; struct timer_list hdlc_reset_timer; struct mutex diag_hdlc_mutex; unsigned char *hdlc_buf; Loading drivers/char/diag/diagchar_core.c +1 −0 Original line number Diff line number Diff line Loading @@ -3624,6 +3624,7 @@ static int __init diagchar_init(void) mutex_init(&driver->delayed_rsp_mutex); mutex_init(&apps_data_mutex); mutex_init(&driver->msg_mask_lock); mutex_init(&driver->hdlc_recovery_mutex); for (i = 0; i < NUM_PERIPHERALS; i++) mutex_init(&driver->diagfwd_channel_mutex[i]); init_waitqueue_head(&driver->wait_q); Loading drivers/char/diag/diagfwd.c +33 −9 Original line number Diff line number Diff line Loading @@ -1405,7 +1405,9 @@ static void diag_hdlc_start_recovery(unsigned char *buf, int len, if (start_ptr) { /* Discard any partial packet reads */ mutex_lock(&driver->hdlc_recovery_mutex); driver->incoming_pkt.processing = 0; mutex_unlock(&driver->hdlc_recovery_mutex); diag_process_non_hdlc_pkt(start_ptr, len - i, info); } } Loading @@ -1419,18 +1421,24 @@ void diag_process_non_hdlc_pkt(unsigned char *buf, int len, const uint32_t header_len = sizeof(struct diag_pkt_frame_t); struct diag_pkt_frame_t *actual_pkt = NULL; unsigned char *data_ptr = NULL; struct diag_partial_pkt_t *partial_pkt = &driver->incoming_pkt; struct diag_partial_pkt_t *partial_pkt = NULL; if (!buf || len <= 0) mutex_lock(&driver->hdlc_recovery_mutex); if (!buf || len <= 0) { mutex_unlock(&driver->hdlc_recovery_mutex); return; if (!partial_pkt->processing) } partial_pkt = &driver->incoming_pkt; if (!partial_pkt->processing) { mutex_unlock(&driver->hdlc_recovery_mutex); goto start; } if (partial_pkt->remaining > len) { if ((partial_pkt->read_len + len) > partial_pkt->capacity) { pr_err("diag: Invalid length %d, %d received in %s\n", partial_pkt->read_len, len, __func__); mutex_unlock(&driver->hdlc_recovery_mutex); goto end; } memcpy(partial_pkt->data + partial_pkt->read_len, buf, len); Loading @@ -1444,6 +1452,7 @@ void diag_process_non_hdlc_pkt(unsigned char *buf, int len, pr_err("diag: Invalid length during partial read %d, %d received in %s\n", partial_pkt->read_len, partial_pkt->remaining, __func__); mutex_unlock(&driver->hdlc_recovery_mutex); goto end; } memcpy(partial_pkt->data + partial_pkt->read_len, buf, Loading @@ -1457,20 +1466,27 @@ void diag_process_non_hdlc_pkt(unsigned char *buf, int len, if (partial_pkt->remaining == 0) { actual_pkt = (struct diag_pkt_frame_t *)(partial_pkt->data); data_ptr = partial_pkt->data + header_len; if (*(uint8_t *)(data_ptr + actual_pkt->length) != CONTROL_CHAR) if (*(uint8_t *)(data_ptr + actual_pkt->length) != CONTROL_CHAR) { mutex_unlock(&driver->hdlc_recovery_mutex); diag_hdlc_start_recovery(buf, len, info); mutex_lock(&driver->hdlc_recovery_mutex); } err = diag_process_apps_pkt(data_ptr, actual_pkt->length, info); if (err) { pr_err("diag: In %s, unable to process incoming data packet, err: %d\n", __func__, err); mutex_unlock(&driver->hdlc_recovery_mutex); goto end; } partial_pkt->read_len = 0; partial_pkt->total_len = 0; partial_pkt->processing = 0; mutex_unlock(&driver->hdlc_recovery_mutex); goto start; } mutex_unlock(&driver->hdlc_recovery_mutex); goto end; start: Loading @@ -1483,14 +1499,14 @@ start: diag_send_error_rsp(buf, len, info); goto end; } mutex_lock(&driver->hdlc_recovery_mutex); if (pkt_len + header_len > partial_pkt->capacity) { pr_err("diag: In %s, incoming data is too large for the request buffer %d\n", __func__, pkt_len); mutex_unlock(&driver->hdlc_recovery_mutex); diag_hdlc_start_recovery(buf, len, info); break; } if ((pkt_len + header_len) > (len - read_bytes)) { partial_pkt->read_len = len - read_bytes; partial_pkt->total_len = pkt_len + header_len; Loading @@ -1498,19 +1514,27 @@ start: partial_pkt->read_len; partial_pkt->processing = 1; memcpy(partial_pkt->data, buf, partial_pkt->read_len); mutex_unlock(&driver->hdlc_recovery_mutex); break; } data_ptr = buf + header_len; if (*(uint8_t *)(data_ptr + actual_pkt->length) != CONTROL_CHAR) if (*(uint8_t *)(data_ptr + actual_pkt->length) != CONTROL_CHAR) { mutex_unlock(&driver->hdlc_recovery_mutex); diag_hdlc_start_recovery(buf, len, info); mutex_lock(&driver->hdlc_recovery_mutex); } else hdlc_reset = 0; err = diag_process_apps_pkt(data_ptr, actual_pkt->length, info); if (err) if (err) { mutex_unlock(&driver->hdlc_recovery_mutex); break; } read_bytes += header_len + pkt_len + 1; buf += header_len + pkt_len + 1; /* advance to next pkt */ mutex_unlock(&driver->hdlc_recovery_mutex); } end: return; Loading Loading
drivers/char/diag/diagchar.h +1 −0 Original line number Diff line number Diff line Loading @@ -578,6 +578,7 @@ struct diagchar_dev { unsigned char *buf_feature_mask_update; uint8_t hdlc_disabled; struct mutex hdlc_disable_mutex; struct mutex hdlc_recovery_mutex; struct timer_list hdlc_reset_timer; struct mutex diag_hdlc_mutex; unsigned char *hdlc_buf; Loading
drivers/char/diag/diagchar_core.c +1 −0 Original line number Diff line number Diff line Loading @@ -3624,6 +3624,7 @@ static int __init diagchar_init(void) mutex_init(&driver->delayed_rsp_mutex); mutex_init(&apps_data_mutex); mutex_init(&driver->msg_mask_lock); mutex_init(&driver->hdlc_recovery_mutex); for (i = 0; i < NUM_PERIPHERALS; i++) mutex_init(&driver->diagfwd_channel_mutex[i]); init_waitqueue_head(&driver->wait_q); Loading
drivers/char/diag/diagfwd.c +33 −9 Original line number Diff line number Diff line Loading @@ -1405,7 +1405,9 @@ static void diag_hdlc_start_recovery(unsigned char *buf, int len, if (start_ptr) { /* Discard any partial packet reads */ mutex_lock(&driver->hdlc_recovery_mutex); driver->incoming_pkt.processing = 0; mutex_unlock(&driver->hdlc_recovery_mutex); diag_process_non_hdlc_pkt(start_ptr, len - i, info); } } Loading @@ -1419,18 +1421,24 @@ void diag_process_non_hdlc_pkt(unsigned char *buf, int len, const uint32_t header_len = sizeof(struct diag_pkt_frame_t); struct diag_pkt_frame_t *actual_pkt = NULL; unsigned char *data_ptr = NULL; struct diag_partial_pkt_t *partial_pkt = &driver->incoming_pkt; struct diag_partial_pkt_t *partial_pkt = NULL; if (!buf || len <= 0) mutex_lock(&driver->hdlc_recovery_mutex); if (!buf || len <= 0) { mutex_unlock(&driver->hdlc_recovery_mutex); return; if (!partial_pkt->processing) } partial_pkt = &driver->incoming_pkt; if (!partial_pkt->processing) { mutex_unlock(&driver->hdlc_recovery_mutex); goto start; } if (partial_pkt->remaining > len) { if ((partial_pkt->read_len + len) > partial_pkt->capacity) { pr_err("diag: Invalid length %d, %d received in %s\n", partial_pkt->read_len, len, __func__); mutex_unlock(&driver->hdlc_recovery_mutex); goto end; } memcpy(partial_pkt->data + partial_pkt->read_len, buf, len); Loading @@ -1444,6 +1452,7 @@ void diag_process_non_hdlc_pkt(unsigned char *buf, int len, pr_err("diag: Invalid length during partial read %d, %d received in %s\n", partial_pkt->read_len, partial_pkt->remaining, __func__); mutex_unlock(&driver->hdlc_recovery_mutex); goto end; } memcpy(partial_pkt->data + partial_pkt->read_len, buf, Loading @@ -1457,20 +1466,27 @@ void diag_process_non_hdlc_pkt(unsigned char *buf, int len, if (partial_pkt->remaining == 0) { actual_pkt = (struct diag_pkt_frame_t *)(partial_pkt->data); data_ptr = partial_pkt->data + header_len; if (*(uint8_t *)(data_ptr + actual_pkt->length) != CONTROL_CHAR) if (*(uint8_t *)(data_ptr + actual_pkt->length) != CONTROL_CHAR) { mutex_unlock(&driver->hdlc_recovery_mutex); diag_hdlc_start_recovery(buf, len, info); mutex_lock(&driver->hdlc_recovery_mutex); } err = diag_process_apps_pkt(data_ptr, actual_pkt->length, info); if (err) { pr_err("diag: In %s, unable to process incoming data packet, err: %d\n", __func__, err); mutex_unlock(&driver->hdlc_recovery_mutex); goto end; } partial_pkt->read_len = 0; partial_pkt->total_len = 0; partial_pkt->processing = 0; mutex_unlock(&driver->hdlc_recovery_mutex); goto start; } mutex_unlock(&driver->hdlc_recovery_mutex); goto end; start: Loading @@ -1483,14 +1499,14 @@ start: diag_send_error_rsp(buf, len, info); goto end; } mutex_lock(&driver->hdlc_recovery_mutex); if (pkt_len + header_len > partial_pkt->capacity) { pr_err("diag: In %s, incoming data is too large for the request buffer %d\n", __func__, pkt_len); mutex_unlock(&driver->hdlc_recovery_mutex); diag_hdlc_start_recovery(buf, len, info); break; } if ((pkt_len + header_len) > (len - read_bytes)) { partial_pkt->read_len = len - read_bytes; partial_pkt->total_len = pkt_len + header_len; Loading @@ -1498,19 +1514,27 @@ start: partial_pkt->read_len; partial_pkt->processing = 1; memcpy(partial_pkt->data, buf, partial_pkt->read_len); mutex_unlock(&driver->hdlc_recovery_mutex); break; } data_ptr = buf + header_len; if (*(uint8_t *)(data_ptr + actual_pkt->length) != CONTROL_CHAR) if (*(uint8_t *)(data_ptr + actual_pkt->length) != CONTROL_CHAR) { mutex_unlock(&driver->hdlc_recovery_mutex); diag_hdlc_start_recovery(buf, len, info); mutex_lock(&driver->hdlc_recovery_mutex); } else hdlc_reset = 0; err = diag_process_apps_pkt(data_ptr, actual_pkt->length, info); if (err) if (err) { mutex_unlock(&driver->hdlc_recovery_mutex); break; } read_bytes += header_len + pkt_len + 1; buf += header_len + pkt_len + 1; /* advance to next pkt */ mutex_unlock(&driver->hdlc_recovery_mutex); } end: return; Loading