Commit 6a6c4a4d authored by Aric Cyr's avatar Aric Cyr Committed by Alex Deucher

drm/amd/display: dal_ddc_i2c_payloads_create can fail causing panic

[Why]
Since the i2c payload allocation can fail need to check return codes

[How]
Clean up i2c payload allocations and check for errors
Signed-off-by: default avatarAric Cyr <aric.cyr@amd.com>
Reviewed-by: default avatarJoshua Aberback <Joshua.Aberback@amd.com>
Acked-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Acked-by: default avatarHarry Wentland <harry.wentland@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent f739ce57
...@@ -126,22 +126,16 @@ struct aux_payloads { ...@@ -126,22 +126,16 @@ struct aux_payloads {
struct vector payloads; struct vector payloads;
}; };
static struct i2c_payloads *dal_ddc_i2c_payloads_create(struct dc_context *ctx, uint32_t count) static bool dal_ddc_i2c_payloads_create(
struct dc_context *ctx,
struct i2c_payloads *payloads,
uint32_t count)
{ {
struct i2c_payloads *payloads;
payloads = kzalloc(sizeof(struct i2c_payloads), GFP_KERNEL);
if (!payloads)
return NULL;
if (dal_vector_construct( if (dal_vector_construct(
&payloads->payloads, ctx, count, sizeof(struct i2c_payload))) &payloads->payloads, ctx, count, sizeof(struct i2c_payload)))
return payloads; return true;
kfree(payloads);
return NULL;
return false;
} }
static struct i2c_payload *dal_ddc_i2c_payloads_get(struct i2c_payloads *p) static struct i2c_payload *dal_ddc_i2c_payloads_get(struct i2c_payloads *p)
...@@ -154,14 +148,12 @@ static uint32_t dal_ddc_i2c_payloads_get_count(struct i2c_payloads *p) ...@@ -154,14 +148,12 @@ static uint32_t dal_ddc_i2c_payloads_get_count(struct i2c_payloads *p)
return p->payloads.count; return p->payloads.count;
} }
static void dal_ddc_i2c_payloads_destroy(struct i2c_payloads **p) static void dal_ddc_i2c_payloads_destroy(struct i2c_payloads *p)
{ {
if (!p || !*p) if (!p)
return; return;
dal_vector_destruct(&(*p)->payloads);
kfree(*p);
*p = NULL;
dal_vector_destruct(&p->payloads);
} }
#define DDC_MIN(a, b) (((a) < (b)) ? (a) : (b)) #define DDC_MIN(a, b) (((a) < (b)) ? (a) : (b))
...@@ -524,9 +516,13 @@ bool dal_ddc_service_query_ddc_data( ...@@ -524,9 +516,13 @@ bool dal_ddc_service_query_ddc_data(
uint32_t payloads_num = write_payloads + read_payloads; uint32_t payloads_num = write_payloads + read_payloads;
if (write_size > EDID_SEGMENT_SIZE || read_size > EDID_SEGMENT_SIZE) if (write_size > EDID_SEGMENT_SIZE || read_size > EDID_SEGMENT_SIZE)
return false; return false;
if (!payloads_num)
return false;
/*TODO: len of payload data for i2c and aux is uint8!!!!, /*TODO: len of payload data for i2c and aux is uint8!!!!,
* but we want to read 256 over i2c!!!!*/ * but we want to read 256 over i2c!!!!*/
if (dal_ddc_service_is_in_aux_transaction_mode(ddc)) { if (dal_ddc_service_is_in_aux_transaction_mode(ddc)) {
...@@ -557,23 +553,25 @@ bool dal_ddc_service_query_ddc_data( ...@@ -557,23 +553,25 @@ bool dal_ddc_service_query_ddc_data(
ret = dal_ddc_submit_aux_command(ddc, &payload); ret = dal_ddc_submit_aux_command(ddc, &payload);
} }
} else { } else {
struct i2c_payloads *payloads = struct i2c_command command = {0};
dal_ddc_i2c_payloads_create(ddc->ctx, payloads_num); struct i2c_payloads payloads;
if (!dal_ddc_i2c_payloads_create(ddc->ctx, &payloads, payloads_num))
return false;
struct i2c_command command = { command.payloads = dal_ddc_i2c_payloads_get(&payloads);
.payloads = dal_ddc_i2c_payloads_get(payloads), command.number_of_payloads = 0;
.number_of_payloads = 0, command.engine = DDC_I2C_COMMAND_ENGINE;
.engine = DDC_I2C_COMMAND_ENGINE, command.speed = ddc->ctx->dc->caps.i2c_speed_in_khz;
.speed = ddc->ctx->dc->caps.i2c_speed_in_khz };
dal_ddc_i2c_payloads_add( dal_ddc_i2c_payloads_add(
payloads, address, write_size, write_buf, true); &payloads, address, write_size, write_buf, true);
dal_ddc_i2c_payloads_add( dal_ddc_i2c_payloads_add(
payloads, address, read_size, read_buf, false); &payloads, address, read_size, read_buf, false);
command.number_of_payloads = command.number_of_payloads =
dal_ddc_i2c_payloads_get_count(payloads); dal_ddc_i2c_payloads_get_count(&payloads);
ret = dm_helpers_submit_i2c( ret = dm_helpers_submit_i2c(
ddc->ctx, ddc->ctx,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment