in btt.c [624:720]
static int log_set_indices(struct arena_info *arena)
{
bool idx_set = false, initial_state = true;
int ret, log_index[2] = {-1, -1};
u32 i, j, next_idx = 0;
struct log_group log;
u32 pad_count = 0;
for (i = 0; i < arena->nfree; i++) {
ret = btt_log_group_read(arena, i, &log);
if (ret < 0)
return ret;
for (j = 0; j < 4; j++) {
if (!idx_set) {
if (ent_is_padding(&log.ent[j])) {
pad_count++;
continue;
} else {
/* Skip if index has been recorded */
if ((next_idx == 1) &&
(j == log_index[0]))
continue;
/* valid entry, record index */
log_index[next_idx] = j;
next_idx++;
}
if (next_idx == 2) {
/* two valid entries found */
idx_set = true;
} else if (next_idx > 2) {
/* too many valid indices */
return -ENXIO;
}
} else {
/*
* once the indices have been set, just verify
* that all subsequent log groups are either in
* their initial state or follow the same
* indices.
*/
if (j == log_index[0]) {
/* entry must be 'valid' */
if (ent_is_padding(&log.ent[j]))
return -ENXIO;
} else if (j == log_index[1]) {
;
/*
* log_index[1] can be padding if the
* lane never got used and it is still
* in the initial state (three 'padding'
* entries)
*/
} else {
/* entry must be invalid (padding) */
if (!ent_is_padding(&log.ent[j]))
return -ENXIO;
}
}
}
/*
* If any of the log_groups have more than one valid,
* non-padding entry, then the we are no longer in the
* initial_state
*/
if (pad_count < 3)
initial_state = false;
pad_count = 0;
}
if (!initial_state && !idx_set)
return -ENXIO;
/*
* If all the entries in the log were in the initial state,
* assume new padding scheme
*/
if (initial_state)
log_index[1] = 1;
/*
* Only allow the known permutations of log/padding indices,
* i.e. (0, 1), and (0, 2)
*/
if ((log_index[0] == 0) && ((log_index[1] == 1) || (log_index[1] == 2)))
; /* known index possibilities */
else {
dev_err(to_dev(arena), "Found an unknown padding scheme\n");
return -ENXIO;
}
arena->log_index[0] = log_index[0];
arena->log_index[1] = log_index[1];
dev_dbg(to_dev(arena), "log_index_0 = %d\n", log_index[0]);
dev_dbg(to_dev(arena), "log_index_1 = %d\n", log_index[1]);
return 0;
}