diff --git a/drivers/video/fbdev/msm/mhl3/mhl_linux_tx.c b/drivers/video/fbdev/msm/mhl3/mhl_linux_tx.c index 7a1645faa1f0..1514f021414a 100644 --- a/drivers/video/fbdev/msm/mhl3/mhl_linux_tx.c +++ b/drivers/video/fbdev/msm/mhl3/mhl_linux_tx.c @@ -331,7 +331,7 @@ ssize_t send_scratch_pad(struct device *dev, struct device_attribute *attr, * Parse the input string and extract the scratch pad register selection * parameters */ - str = strstr(pinput, "offset="); + str = strnstr(pinput, "offset=", count); if (str != NULL) { str += 7; status = si_strtoul(&str, 0, &offset); @@ -3067,7 +3067,7 @@ void mhl_event_notify(struct mhl_dev_context *dev_context, u32 event, "MHLEVENT=SPAD_CHG length=0x%02x data=", length); count = 0; - while (idx < MAX_EVENT_STRING_LEN) { + while (buf && idx < MAX_EVENT_STRING_LEN) { if (count >= length) break; diff --git a/drivers/video/fbdev/msm/mhl3/mhl_supp.c b/drivers/video/fbdev/msm/mhl3/mhl_supp.c index 133c6f2d411a..7055d8cd758d 100644 --- a/drivers/video/fbdev/msm/mhl3/mhl_supp.c +++ b/drivers/video/fbdev/msm/mhl3/mhl_supp.c @@ -484,12 +484,14 @@ void si_mhl_tx_push_block_transactions(struct mhl_dev_context *dev_context) req->payload->hdr_and_burst_id.tport_hdr.length_remaining = req->sub_payload_size; req->count = payload_size; - /* The driver layer will fill in the rx_unload_ack field */ - mhl_tx_drv_send_block((struct drv_hw_context *) - (&dev_context->drv_context), req); - /* return request to free list */ - return_block_queue_entry(dev_context, req); - + if (req->count < EMSC_PAYLOAD_LEN) { + /* The driver layer will fill */ + /* in the rx_unload_ack field */ + mhl_tx_drv_send_block((struct drv_hw_context *) + (&dev_context->drv_context), req); + /* return request to free list */ + return_block_queue_entry(dev_context, req); + } } if (NULL == dev_context->block_protocol.marshalling_req) { /* now start a new marshalling request */ @@ -1337,7 +1339,7 @@ void si_mhl_tx_drive_states(struct mhl_dev_context *dev_context) next_req; } - } while (ret_val); + } while (ret_val && req); break; case MHL_MSC_MSG: if (MHL_MSC_MSG_RAP == req->msg_data[0]) { diff --git a/drivers/video/fbdev/msm/mhl3/si_8620_drv.c b/drivers/video/fbdev/msm/mhl3/si_8620_drv.c index 1e39d7248c0f..dd71f1becd1e 100644 --- a/drivers/video/fbdev/msm/mhl3/si_8620_drv.c +++ b/drivers/video/fbdev/msm/mhl3/si_8620_drv.c @@ -858,6 +858,11 @@ drain_rfifo: MHL_TX_DBG_ERR("Draining %d bytes from RFIFO\n", data_len); pbit_bucket = kmalloc(data_len, GFP_KERNEL); + if (!pbit_bucket) { + MHL_TX_DBG_ERR("Failed to allocate %d bytes for pbit bucket\n", + data_len); + goto done_emsc; + } if (use_spi) { mhl_tx_read_spi_emsc(hw_context, data_len, pbit_bucket); } else { @@ -1831,8 +1836,10 @@ void mhl_tx_drv_send_block(struct drv_hw_context *hw_context, if (use_spi) { mhl_tx_write_block_spi_emsc(hw_context, req); } else { - mhl_tx_write_reg_block(hw_context, REG_EMSC_XMIT_WRITE_PORT, - req->count, &req->payload->as_bytes[0]); + if (req->count < EMSC_PAYLOAD_LEN) + mhl_tx_write_reg_block(hw_context, + REG_EMSC_XMIT_WRITE_PORT, req->count, + &req->payload->as_bytes[0]); } } @@ -2258,6 +2265,10 @@ uint8_t si_mhl_tx_drv_send_cbus_command(struct drv_hw_context *hw_context, req->burst_offset, req->length); hw_context->hawb_write_pending = true; enable_gen2_write_burst_xmit(hw_context); + if (req->length > CBUS_REQ_MSG_DATA_LEN) { + ret_val = -EINVAL; + break; + } mhl_tx_write_reg_block(hw_context, REG_MDT_XMIT_WRITE_PORT, req->length, req->msg_data); diff --git a/drivers/video/fbdev/msm/mhl3/si_mhl2_edid_3d.c b/drivers/video/fbdev/msm/mhl3/si_mhl2_edid_3d.c index 7a3856b39915..fd6918fbf1ff 100644 --- a/drivers/video/fbdev/msm/mhl3/si_mhl2_edid_3d.c +++ b/drivers/video/fbdev/msm/mhl3/si_mhl2_edid_3d.c @@ -1923,7 +1923,8 @@ static void si_mhl_tx_prune_edid(struct edid_3d_data_t *mhl_edid_3d_data) } } - if (mhl_edid_3d_data->parse_data.p_three_d) { + if (mhl_edid_3d_data->parse_data.p_three_d && + mhl_edid_3d_data->parse_data.p_HDMI_vsdb) { uint8_t num_3D_structure_bytes_pruned = 0; union { union _3D_structure_and_detail_entry_u *p_3D; @@ -4288,7 +4289,10 @@ int si_mhl_tx_get_num_cea_861_extensions(void *context, uint8_t block_number) uint8_t limit_blocks = sizeof(mhl_edid_3d_data->EDID_block_data) / EDID_BLOCK_SIZE; - uint8_t *pb_data = + uint8_t *pb_data; + if (block_number > NUM_VIDEO_DATA_BLOCKS_LIMIT) + return ne_BAD_DATA; + pb_data = &mhl_edid_3d_data->EDID_block_data[EDID_BLOCK_SIZE * block_number]; MHL_TX_EDID_INFO("block number:%d pb_data:%x\n", block_number, pb_data); diff --git a/drivers/video/fbdev/msm/mhl3/si_mhl_tx_hw_drv_api.h b/drivers/video/fbdev/msm/mhl3/si_mhl_tx_hw_drv_api.h index 9bd5327f7143..9782ee2b50d2 100644 --- a/drivers/video/fbdev/msm/mhl3/si_mhl_tx_hw_drv_api.h +++ b/drivers/video/fbdev/msm/mhl3/si_mhl_tx_hw_drv_api.h @@ -16,6 +16,8 @@ #if !defined(SI_MHL_TX_DRV_API_H) #define SI_MHL_TX_DRV_API_H +#define CBUS_REQ_MSG_DATA_LEN 16 +#define EMSC_PAYLOAD_LEN 256 /* * Structure to hold command details from upper layer to CBUS module */ @@ -34,7 +36,7 @@ struct cbus_req { uint8_t reg_data; uint8_t burst_offset; /* register offset */ uint8_t length; /* Only applicable to write burst */ - uint8_t msg_data[16]; /* scratch pad data area. */ + uint8_t msg_data[CBUS_REQ_MSG_DATA_LEN]; /* scratch pad data area. */ const char *function; int line; int sequence; @@ -53,7 +55,7 @@ struct SI_PACK_THIS_STRUCT tport_hdr_and_burst_id_t { }; union SI_PACK_THIS_STRUCT emsc_payload_t { struct SI_PACK_THIS_STRUCT tport_hdr_and_burst_id_t hdr_and_burst_id; - uint8_t as_bytes[256]; + uint8_t as_bytes[EMSC_PAYLOAD_LEN]; }; struct SI_PACK_THIS_STRUCT block_req {