mirror of
https://github.com/linux-msm/qdl.git
synced 2026-02-25 13:12:25 -08:00
Introduce a linked list abstraction
For some reason qdl was written with open-coded linked list operations throughout the implementation, resulting in ugly boiler plate code sprinkled over the code base. Integrate the linked list abstraction used in a few other of our open-source projects to clean up the code. Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
This commit is contained in:
committed by
Bjorn Andersson
parent
6a67b6bd64
commit
ce175f2e27
73
list.h
Normal file
73
list.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (c) 2016, Linaro Ltd.
|
||||
*/
|
||||
#ifndef __LIST_H__
|
||||
#define __LIST_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
struct list_head {
|
||||
struct list_head *prev;
|
||||
struct list_head *next;
|
||||
};
|
||||
|
||||
#define LIST_INIT(list) { &(list), &(list) }
|
||||
|
||||
static inline void list_init(struct list_head *list)
|
||||
{
|
||||
list->prev = list;
|
||||
list->next = list;
|
||||
}
|
||||
|
||||
static inline bool list_empty(struct list_head *list)
|
||||
{
|
||||
return list->next == list;
|
||||
}
|
||||
|
||||
static inline void list_add(struct list_head *list, struct list_head *item)
|
||||
{
|
||||
struct list_head *prev = list->prev;
|
||||
|
||||
item->next = list;
|
||||
item->prev = prev;
|
||||
|
||||
prev->next = item;
|
||||
list->prev = item;
|
||||
}
|
||||
|
||||
static inline void list_del(struct list_head *item)
|
||||
{
|
||||
item->prev->next = item->next;
|
||||
item->next->prev = item->prev;
|
||||
}
|
||||
|
||||
#define list_for_each(item, list) \
|
||||
for (item = (list)->next; item != list; item = item->next)
|
||||
|
||||
#define list_for_each_safe(item, tmp, list) \
|
||||
for (item = (list)->next, tmp = item->next; item != list; item = tmp, tmp = item->next)
|
||||
|
||||
#define list_entry(item, type, member) \
|
||||
container_of(item, type, member)
|
||||
|
||||
#define list_entry_first(list, type, member) \
|
||||
container_of((list)->next, type, member)
|
||||
|
||||
#define list_entry_next(item, member) \
|
||||
container_of((item)->member.next, typeof(*(item)), member)
|
||||
|
||||
#define list_for_each_entry(item, list, member) \
|
||||
for (item = list_entry_first(list, typeof(*(item)), member); \
|
||||
&item->member != list; \
|
||||
item = list_entry_next(item, member))
|
||||
|
||||
#define list_for_each_entry_safe(item, next, list, member) \
|
||||
for (item = list_entry_first(list, typeof(*(item)), member), \
|
||||
next = list_entry_next(item, member); \
|
||||
&item->member != list; \
|
||||
item = next, \
|
||||
next = list_entry_next(item, member)) \
|
||||
|
||||
#endif
|
||||
22
patch.c
22
patch.c
@@ -13,8 +13,7 @@
|
||||
#include "patch.h"
|
||||
#include "qdl.h"
|
||||
|
||||
static struct patch *patches;
|
||||
static struct patch *patches_last;
|
||||
static struct list_head patches = LIST_INIT(patches);
|
||||
|
||||
int patch_load(const char *patch_file)
|
||||
{
|
||||
@@ -59,13 +58,7 @@ int patch_load(const char *patch_file)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (patches) {
|
||||
patches_last->next = patch;
|
||||
patches_last = patch;
|
||||
} else {
|
||||
patches = patch;
|
||||
patches_last = patch;
|
||||
}
|
||||
list_add(&patches, &patch->node);
|
||||
}
|
||||
|
||||
xmlFreeDoc(doc);
|
||||
@@ -80,12 +73,12 @@ int patch_execute(struct qdl_device *qdl, int (*apply)(struct qdl_device *qdl, s
|
||||
unsigned int idx = 0;
|
||||
int ret;
|
||||
|
||||
for (patch = patches; patch; patch = patch->next) {
|
||||
list_for_each_entry(patch, &patches, node) {
|
||||
if (!strcmp(patch->filename, "DISK"))
|
||||
count++;
|
||||
}
|
||||
|
||||
for (patch = patches; patch; patch = patch->next) {
|
||||
list_for_each_entry(patch, &patches, node) {
|
||||
if (strcmp(patch->filename, "DISK"))
|
||||
continue;
|
||||
|
||||
@@ -103,11 +96,10 @@ int patch_execute(struct qdl_device *qdl, int (*apply)(struct qdl_device *qdl, s
|
||||
|
||||
void free_patches(void)
|
||||
{
|
||||
struct patch *patch = patches;
|
||||
struct patch *patch;
|
||||
struct patch *next;
|
||||
|
||||
for (patch = patches; patch; patch = next) {
|
||||
next = patch->next;
|
||||
list_for_each_entry_safe(patch, next, &patches, node) {
|
||||
free((void *)patch->filename);
|
||||
free((void *)patch->start_sector);
|
||||
free((void *)patch->value);
|
||||
@@ -115,5 +107,5 @@ void free_patches(void)
|
||||
free(patch);
|
||||
}
|
||||
|
||||
patches = NULL;
|
||||
list_init(&patches);
|
||||
}
|
||||
|
||||
4
patch.h
4
patch.h
@@ -2,6 +2,8 @@
|
||||
#ifndef __PATCH_H__
|
||||
#define __PATCH_H__
|
||||
|
||||
#include "list.h"
|
||||
|
||||
struct qdl_device;
|
||||
|
||||
struct patch {
|
||||
@@ -14,7 +16,7 @@ struct patch {
|
||||
const char *value;
|
||||
const char *what;
|
||||
|
||||
struct patch *next;
|
||||
struct list_head node;
|
||||
};
|
||||
|
||||
int patch_load(const char *patch_file);
|
||||
|
||||
61
program.c
61
program.c
@@ -20,8 +20,7 @@
|
||||
#include "sparse.h"
|
||||
#include "gpt.h"
|
||||
|
||||
static struct program *programes;
|
||||
static struct program *programes_last;
|
||||
static struct list_head programs = LIST_INIT(programs);
|
||||
|
||||
static int load_erase_tag(xmlNode *node, bool is_nand)
|
||||
{
|
||||
@@ -47,13 +46,7 @@ static int load_erase_tag(xmlNode *node, bool is_nand)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (programes) {
|
||||
programes_last->next = program;
|
||||
programes_last = program;
|
||||
} else {
|
||||
programes = program;
|
||||
programes_last = program;
|
||||
}
|
||||
list_add(&programs, &program->node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -82,14 +75,8 @@ static int program_load_sparse(struct program *program, int fd)
|
||||
if ((off_t)program->sector_size * program->num_sectors ==
|
||||
lseek(fd, 0, SEEK_END)) {
|
||||
program->sparse = false;
|
||||
|
||||
if (programes) {
|
||||
programes_last->next = program;
|
||||
programes_last = program;
|
||||
} else {
|
||||
programes = program;
|
||||
programes_last = program;
|
||||
}
|
||||
list_add(&programs, &program->node);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ux_err("[PROGRAM] Unable to parse sparse header at %s...failed\n",
|
||||
@@ -149,14 +136,7 @@ static int program_load_sparse(struct program *program, int fd)
|
||||
else
|
||||
program_sparse->sparse_fill_value = sparse_fill_value;
|
||||
|
||||
program_sparse->next = NULL;
|
||||
if (programes) {
|
||||
programes_last->next = program_sparse;
|
||||
programes_last = program_sparse;
|
||||
} else {
|
||||
programes = program_sparse;
|
||||
programes_last = program_sparse;
|
||||
}
|
||||
list_add(&programs, &program_sparse->node);
|
||||
}
|
||||
|
||||
start_sector = (unsigned int)strtoul(program->start_sector, NULL, 0);
|
||||
@@ -239,13 +219,7 @@ static int load_program_tag(xmlNode *node, bool is_nand, bool allow_missing, con
|
||||
program->filename = NULL;
|
||||
}
|
||||
|
||||
if (programes) {
|
||||
programes_last->next = program;
|
||||
programes_last = program;
|
||||
} else {
|
||||
programes = program;
|
||||
programes_last = program;
|
||||
}
|
||||
list_add(&programs, &program->node);
|
||||
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
@@ -296,7 +270,7 @@ int program_execute(struct qdl_device *qdl, int (*apply)(struct qdl_device *qdl,
|
||||
int ret;
|
||||
int fd;
|
||||
|
||||
for (program = programes; program; program = program->next) {
|
||||
list_for_each_entry(program, &programs, node) {
|
||||
if (program->is_erase || !program->filename)
|
||||
continue;
|
||||
|
||||
@@ -321,7 +295,7 @@ int erase_execute(struct qdl_device *qdl, int (*apply)(struct qdl_device *qdl, s
|
||||
struct program *program;
|
||||
int ret;
|
||||
|
||||
for (program = programes; program; program = program->next) {
|
||||
list_for_each_entry(program, &programs, node) {
|
||||
if (!program->is_erase)
|
||||
continue;
|
||||
|
||||
@@ -338,7 +312,7 @@ static struct program *program_find_partition(const char *partition)
|
||||
struct program *program;
|
||||
const char *label;
|
||||
|
||||
for (program = programes; program; program = program->next) {
|
||||
list_for_each_entry(program, &programs, node) {
|
||||
label = program->label;
|
||||
if (!label)
|
||||
continue;
|
||||
@@ -412,11 +386,10 @@ int program_is_sec_partition_flashed(void)
|
||||
|
||||
void free_programs(void)
|
||||
{
|
||||
struct program *program = programes;
|
||||
struct program *program;
|
||||
struct program *next;
|
||||
|
||||
for (program = programes; program; program = next) {
|
||||
next = program->next;
|
||||
list_for_each_entry_safe(program, next, &programs, node) {
|
||||
free((void *)program->filename);
|
||||
free((void *)program->label);
|
||||
free((void *)program->start_sector);
|
||||
@@ -424,7 +397,7 @@ void free_programs(void)
|
||||
free(program);
|
||||
}
|
||||
|
||||
programes = NULL;
|
||||
list_init(&programs);
|
||||
}
|
||||
|
||||
int program_cmd_add(const char *address, const char *filename)
|
||||
@@ -457,13 +430,7 @@ int program_cmd_add(const char *address, const char *filename)
|
||||
program->is_erase = false;
|
||||
program->gpt_partition = gpt_partition;
|
||||
|
||||
if (programes) {
|
||||
programes_last->next = program;
|
||||
programes_last = program;
|
||||
} else {
|
||||
programes = program;
|
||||
programes_last = program;
|
||||
}
|
||||
list_add(&programs, &program->node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -475,7 +442,7 @@ int program_resolve_gpt_deferrals(struct qdl_device *qdl)
|
||||
char buf[20];
|
||||
int ret;
|
||||
|
||||
for (program = programes; program; program = program->next) {
|
||||
list_for_each_entry(program, &programs, node) {
|
||||
if (!program->gpt_partition)
|
||||
continue;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "qdl.h"
|
||||
#include "list.h"
|
||||
|
||||
struct program {
|
||||
unsigned int pages_per_block;
|
||||
@@ -28,9 +28,11 @@ struct program {
|
||||
|
||||
const char *gpt_partition;
|
||||
|
||||
struct program *next;
|
||||
struct list_head node;
|
||||
};
|
||||
|
||||
struct qdl_device;
|
||||
|
||||
int program_load(const char *program_file, bool is_nand, bool allow_missing, const char *incdir);
|
||||
int program_execute(struct qdl_device *qdl, int (*apply)(struct qdl_device *qdl, struct program *program, int fd));
|
||||
int erase_execute(struct qdl_device *qdl, int (*apply)(struct qdl_device *qdl, struct program *program));
|
||||
|
||||
24
read.c
24
read.c
@@ -11,13 +11,13 @@
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/tree.h>
|
||||
|
||||
#include "list.h"
|
||||
#include "read.h"
|
||||
#include "qdl.h"
|
||||
#include "oscompat.h"
|
||||
#include "gpt.h"
|
||||
|
||||
static struct read_op *read_ops;
|
||||
static struct read_op *read_ops_last;
|
||||
static struct list_head read_ops = LIST_INIT(read_ops);
|
||||
|
||||
int read_op_load(const char *read_op_file, const char *incdir)
|
||||
{
|
||||
@@ -67,13 +67,7 @@ int read_op_load(const char *read_op_file, const char *incdir)
|
||||
read_op->filename = strdup(tmp);
|
||||
}
|
||||
|
||||
if (read_ops) {
|
||||
read_ops_last->next = read_op;
|
||||
read_ops_last = read_op;
|
||||
} else {
|
||||
read_ops = read_op;
|
||||
read_ops_last = read_op;
|
||||
}
|
||||
list_add(&read_ops, &read_op->node);
|
||||
}
|
||||
|
||||
xmlFreeDoc(doc);
|
||||
@@ -87,7 +81,7 @@ int read_op_execute(struct qdl_device *qdl, int (*apply)(struct qdl_device *qdl,
|
||||
int ret;
|
||||
int fd;
|
||||
|
||||
for (read_op = read_ops; read_op; read_op = read_op->next) {
|
||||
list_for_each_entry(read_op, &read_ops, node) {
|
||||
fd = open(read_op->filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
|
||||
if (fd < 0) {
|
||||
ux_info("unable to open %s...\n", read_op->filename);
|
||||
@@ -133,13 +127,7 @@ int read_cmd_add(const char *address, const char *filename)
|
||||
read_op->start_sector = strdup(buf);
|
||||
read_op->gpt_partition = gpt_partition;
|
||||
|
||||
if (read_ops) {
|
||||
read_ops_last->next = read_op;
|
||||
read_ops_last = read_op;
|
||||
} else {
|
||||
read_ops = read_op;
|
||||
read_ops_last = read_op;
|
||||
}
|
||||
list_add(&read_ops, &read_op->node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -151,7 +139,7 @@ int read_resolve_gpt_deferrals(struct qdl_device *qdl)
|
||||
char buf[20];
|
||||
int ret;
|
||||
|
||||
for (read_op = read_ops; read_op; read_op = read_op->next) {
|
||||
list_for_each_entry(read_op, &read_ops, node) {
|
||||
if (!read_op->gpt_partition)
|
||||
continue;
|
||||
|
||||
|
||||
5
read.h
5
read.h
@@ -4,6 +4,8 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "list.h"
|
||||
|
||||
struct qdl_device;
|
||||
|
||||
struct read_op {
|
||||
@@ -13,7 +15,8 @@ struct read_op {
|
||||
unsigned int num_sectors;
|
||||
const char *start_sector;
|
||||
const char *gpt_partition;
|
||||
struct read_op *next;
|
||||
|
||||
struct list_head node;
|
||||
};
|
||||
|
||||
int read_op_load(const char *read_op_file, const char *incdir);
|
||||
|
||||
23
ufs.c
23
ufs.c
@@ -15,12 +15,12 @@
|
||||
|
||||
#include "ufs.h"
|
||||
#include "qdl.h"
|
||||
#include "list.h"
|
||||
#include "patch.h"
|
||||
|
||||
struct ufs_common *ufs_common_p;
|
||||
struct ufs_epilogue *ufs_epilogue_p;
|
||||
struct ufs_body *ufs_body_p;
|
||||
struct ufs_body *ufs_body_last;
|
||||
static struct list_head ufs_bodies = LIST_INIT(ufs_bodies);
|
||||
|
||||
static const char notice_bconfigdescrlock[] = "\n"
|
||||
"Please pay attention that UFS provisioning is irreversible (OTP) operation unless parameter bConfigDescrLock = 0.\n"
|
||||
@@ -124,6 +124,7 @@ int ufs_load(const char *ufs_file, bool finalize_provisioning)
|
||||
xmlDoc *doc;
|
||||
int retval = 0;
|
||||
struct ufs_body *ufs_body_tmp;
|
||||
struct ufs_body *ufs_body;
|
||||
|
||||
if (ufs_common_p) {
|
||||
ux_err("Only one UFS provisioning XML allowed, \"%s\" ignored\n",
|
||||
@@ -169,13 +170,7 @@ int ufs_load(const char *ufs_file, bool finalize_provisioning)
|
||||
} else if (xmlGetProp(node, (xmlChar *)"LUNum")) {
|
||||
ufs_body_tmp = ufs_parse_body(node);
|
||||
if (ufs_body_tmp) {
|
||||
if (ufs_body_p) {
|
||||
ufs_body_last->next = ufs_body_tmp;
|
||||
ufs_body_last = ufs_body_tmp;
|
||||
} else {
|
||||
ufs_body_p = ufs_body_tmp;
|
||||
ufs_body_last = ufs_body_tmp;
|
||||
}
|
||||
list_add(&ufs_bodies, &ufs_body_tmp->node);
|
||||
} else {
|
||||
ux_err("invalid UFS body tag found in \"%s\"\n",
|
||||
ufs_file);
|
||||
@@ -210,7 +205,7 @@ int ufs_load(const char *ufs_file, bool finalize_provisioning)
|
||||
|
||||
xmlFreeDoc(doc);
|
||||
|
||||
if (!retval && (!ufs_common_p || !ufs_body_p || !ufs_epilogue_p)) {
|
||||
if (!retval && (!ufs_common_p || list_empty(&ufs_bodies) || !ufs_epilogue_p)) {
|
||||
ux_err("incomplete UFS provisioning information in \"%s\"\n", ufs_file);
|
||||
retval = -EINVAL;
|
||||
}
|
||||
@@ -219,8 +214,8 @@ int ufs_load(const char *ufs_file, bool finalize_provisioning)
|
||||
if (ufs_common_p) {
|
||||
free(ufs_common_p);
|
||||
}
|
||||
if (ufs_body_p) {
|
||||
free(ufs_body_p);
|
||||
list_for_each_entry_safe(ufs_body, ufs_body_tmp, &ufs_bodies, node) {
|
||||
free(ufs_body);
|
||||
}
|
||||
if (ufs_epilogue_p) {
|
||||
free(ufs_epilogue_p);
|
||||
@@ -260,7 +255,7 @@ int ufs_provisioning_execute(struct qdl_device *qdl,
|
||||
ret = apply_ufs_common(qdl, ufs_common_p);
|
||||
if (ret)
|
||||
return ret;
|
||||
for (body = ufs_body_p; body; body = body->next) {
|
||||
list_for_each_entry(body, &ufs_bodies, node) {
|
||||
ret = apply_ufs_body(qdl, body);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -275,7 +270,7 @@ int ufs_provisioning_execute(struct qdl_device *qdl,
|
||||
ret = apply_ufs_common(qdl, ufs_common_p);
|
||||
if (ret)
|
||||
return ret;
|
||||
for (body = ufs_body_p; body; body = body->next) {
|
||||
list_for_each_entry(body, &ufs_bodies, node) {
|
||||
ret = apply_ufs_body(qdl, body);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
Reference in New Issue
Block a user