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: Aric Cyr <aric.cyr@amd.com> Reviewed-by: Joshua Aberback <Joshua.Aberback@amd.com> Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com> Acked-by: Harry Wentland <harry.wentland@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
f739ce5768
commit
6a6c4a4d45
@ -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)
|
|||||||
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(
|
|||||||
|
|
||||||
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(
|
|||||||
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;
|
||||||
|
|
||||||
struct i2c_command command = {
|
if (!dal_ddc_i2c_payloads_create(ddc->ctx, &payloads, payloads_num))
|
||||||
.payloads = dal_ddc_i2c_payloads_get(payloads),
|
return false;
|
||||||
.number_of_payloads = 0,
|
|
||||||
.engine = DDC_I2C_COMMAND_ENGINE,
|
command.payloads = dal_ddc_i2c_payloads_get(&payloads);
|
||||||
.speed = ddc->ctx->dc->caps.i2c_speed_in_khz };
|
command.number_of_payloads = 0;
|
||||||
|
command.engine = DDC_I2C_COMMAND_ENGINE;
|
||||||
|
command.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,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user