On Mon, 15 Jun 2015 02:05:39 +0300 Antony Pavlov <[email protected]> wrote:
Stefan! This patch make it possible to eliminate MASTERS_MAX limit. Could you please comment on this patch? > Signed-off-by: Antony Pavlov <[email protected]> > --- > cli_classic.c | 13 +++--- > flashrom.c | 1 - > list.h | 130 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > programmer.c | 27 ++++++------ > programmer.h | 7 ++-- > 5 files changed, 153 insertions(+), 25 deletions(-) > > diff --git a/cli_classic.c b/cli_classic.c > index a2c2014..06ae454 100644 > --- a/cli_classic.c > +++ b/cli_classic.c > @@ -96,7 +96,7 @@ int main(int argc, char *argv[]) > struct flashctx flashes[8] = {{0}}; > struct flashctx *fill_flash; > const char *name; > - int namelen, opt, i, j; > + int namelen, opt, i; > int startchip = -1, chipcount = 0, option_index = 0, force = 0; > #if CONFIG_PRINT_WIKI == 1 > int list_supported_wiki = 0; > @@ -134,6 +134,7 @@ int main(int argc, char *argv[]) > #endif /* !STANDALONE */ > char *tempstr = NULL; > char *pparam = NULL; > + struct registered_master *master; > > print_version(); > print_banner(); > @@ -425,10 +426,10 @@ int main(int argc, char *argv[]) > msg_pdbg("The following protocols are supported: %s.\n", tempstr); > free(tempstr); > > - for (j = 0; j < registered_master_count; j++) { > + list_for_each_entry(master, ®istered_masters, node) { > startchip = 0; > while (chipcount < ARRAY_SIZE(flashes)) { > - startchip = probe_flash(®istered_masters[j], > startchip, &flashes[chipcount], 0); > + startchip = probe_flash(master, startchip, > &flashes[chipcount], 0); > if (startchip == -1) > break; > chipcount++; > @@ -455,8 +456,7 @@ int main(int argc, char *argv[]) > int compatible_masters = 0; > msg_cinfo("Force read (-f -r -c) requested, pretending > the chip is there:\n"); > /* This loop just counts compatible controllers. */ > - for (j = 0; j < registered_master_count; j++) { > - mst = ®istered_masters[j]; > + list_for_each_entry(mst, ®istered_masters, node) { > /* chip is still set from the chip_to_probe > earlier in this function. */ > if (mst->buses_supported & chip->bustype) > compatible_masters++; > @@ -469,8 +469,7 @@ int main(int argc, char *argv[]) > if (compatible_masters > 1) > msg_cinfo("More than one compatible controller > found for the requested flash " > "chip, using the first one.\n"); > - for (j = 0; j < registered_master_count; j++) { > - mst = ®istered_masters[j]; > + list_for_each_entry(mst, ®istered_masters, node) { > startchip = probe_flash(mst, 0, &flashes[0], 1); > if (startchip != -1) > break; > diff --git a/flashrom.c b/flashrom.c > index a389cb2..bd770c2 100644 > --- a/flashrom.c > +++ b/flashrom.c > @@ -494,7 +494,6 @@ int programmer_shutdown(void) > } > > programmer_param = NULL; > - registered_master_count = 0; > > return ret; > } > diff --git a/list.h b/list.h > new file mode 100644 > index 0000000..7567742 > --- /dev/null > +++ b/list.h > @@ -0,0 +1,130 @@ > +#ifndef LIST_H > +#define LIST_H > + > +/* > + * Copied from include/linux/... > + */ > + > +#undef offsetof > +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) > + > +/** > + * container_of - cast a member of a structure out to the containing > structure > + * @ptr: the pointer to the member. > + * @type: the type of the container struct this is embedded in. > + * @member: the name of the member within the struct. > + * > + */ > +#define container_of(ptr, type, member) ({ \ > + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ > + (type *)( (char *)__mptr - offsetof(type,member) );}) > + > + > +struct list_head { > + struct list_head *next, *prev; > +}; > + > +#define LIST_HEAD_INIT(name) { &(name), &(name) } > + > +#define LIST_HEAD(name) \ > + struct list_head name = LIST_HEAD_INIT(name) > + > +/** > + * list_entry - get the struct for this entry > + * @ptr: the &struct list_head pointer. > + * @type: the type of the struct this is embedded in. > + * @member: the name of the list_head within the struct. > + */ > +#define list_entry(ptr, type, member) \ > + container_of(ptr, type, member) > + > +/** > + * list_for_each_entry - iterate over list of given type > + * @pos: the type * to use as a loop cursor. > + * @head: the head for your list. > + * @member: the name of the list_head within the struct. > + */ > +#define list_for_each_entry(pos, head, member) > \ > + for (pos = list_entry((head)->next, typeof(*pos), member); \ > + &pos->member != (head); \ > + pos = list_entry(pos->member.next, typeof(*pos), member)) > + > +/** > + * list_for_each_entry_safe - iterate over list of given type safe against > removal of list entry > + * @pos: the type * to use as a loop cursor. > + * @n: another type * to use as temporary storage > + * @head: the head for your list. > + * @member: the name of the list_head within the struct. > + */ > +#define list_for_each_entry_safe(pos, n, head, member) > \ > + for (pos = list_entry((head)->next, typeof(*pos), member), \ > + n = list_entry(pos->member.next, typeof(*pos), member); \ > + &pos->member != (head); \ > + pos = n, n = list_entry(n->member.next, typeof(*n), member)) > + > +/** > + * list_empty - tests whether a list is empty > + * @head: the list to test. > + */ > +static inline int list_empty(const struct list_head *head) > +{ > + return head->next == head; > +} > + > +/* > + * Insert a new entry between two known consecutive entries. > + * > + * This is only for internal list manipulation where we know > + * the prev/next entries already! > + */ > +static inline void __list_add(struct list_head *_new, > + struct list_head *prev, > + struct list_head *next) > +{ > + next->prev = _new; > + _new->next = next; > + _new->prev = prev; > + prev->next = _new; > +} > + > +/** > + * list_add_tail - add a new entry > + * @new: new entry to be added > + * @head: list head to add it before > + * > + * Insert a new entry before the specified head. > + * This is useful for implementing queues. > + */ > +static inline void list_add_tail(struct list_head *_new, struct list_head > *head) > +{ > + __list_add(_new, head->prev, head); > +} > + > +/* > + * Delete a list entry by making the prev/next entries > + * point to each other. > + * > + * This is only for internal list manipulation where we know > + * the prev/next entries already! > + */ > +static inline void __list_del(struct list_head *prev, struct list_head *next) > +{ > + next->prev = prev; > + prev->next = next; > +} > + > +#define LIST_POISON1 ((void *) 0x00100100) > +#define LIST_POISON2 ((void *) 0x00200200) > +/** > + * list_del - deletes entry from list. > + * @entry: the element to delete from the list. > + * Note: list_empty() on entry does not return true after this, the entry is > + * in an undefined state. > + */ > +static inline void list_del(struct list_head *entry) > +{ > + __list_del(entry->prev, entry->next); > + entry->next = (struct list_head*)LIST_POISON1; > + entry->prev = (struct list_head*)LIST_POISON2; > +} > +#endif > diff --git a/programmer.c b/programmer.c > index 1b27c3c..2a5df92 100644 > --- a/programmer.c > +++ b/programmer.c > @@ -18,6 +18,8 @@ > * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA > */ > > +#include <malloc.h> > +#include <string.h> > #include "flash.h" > #include "programmer.h" > > @@ -114,31 +116,28 @@ int register_par_master(const struct par_master *mst, > } > > /* The limit of 4 is totally arbitrary. */ > -#define MASTERS_MAX 4 > -struct registered_master registered_masters[MASTERS_MAX]; > -int registered_master_count = 0; > +LIST_HEAD(registered_masters); > > /* This function copies the struct registered_master parameter. */ > -int register_master(const struct registered_master *mst) > +int register_master(struct registered_master *mst) > { > - if (registered_master_count >= MASTERS_MAX) { > - msg_perr("Tried to register more than %i master " > - "interfaces.\n", MASTERS_MAX); > - return ERROR_FLASHROM_LIMIT; > - } > - registered_masters[registered_master_count] = *mst; > - registered_master_count++; > + struct registered_master *t; > + > + t = malloc(sizeof(struct registered_master)); > + memcpy(t, mst, sizeof(struct registered_master)); > + list_add_tail(&t->node, ®istered_masters); > > return 0; > } > > enum chipbustype get_buses_supported(void) > { > - int i; > + struct registered_master *mst; > enum chipbustype ret = BUS_NONE; > > - for (i = 0; i < registered_master_count; i++) > - ret |= registered_masters[i].buses_supported; > + list_for_each_entry(mst, ®istered_masters, node) { > + ret |= mst->buses_supported; > + } > > return ret; > } > diff --git a/programmer.h b/programmer.h > index 913522b..54d5634 100644 > --- a/programmer.h > +++ b/programmer.h > @@ -25,6 +25,7 @@ > #define __PROGRAMMER_H__ 1 > > #include "flash.h" /* for chipaddr and flashctx */ > +#include "list.h" > > enum programmer { > #if CONFIG_INTERNAL == 1 > @@ -691,6 +692,7 @@ struct par_master { > }; > int register_par_master(const struct par_master *mst, const enum chipbustype > buses); > struct registered_master { > + struct list_head node; > enum chipbustype buses_supported; > union { > struct par_master par; > @@ -698,9 +700,8 @@ struct registered_master { > struct opaque_master opaque; > }; > }; > -extern struct registered_master registered_masters[]; > -extern int registered_master_count; > -int register_master(const struct registered_master *mst); > +extern struct list_head registered_masters; > +int register_master(struct registered_master *mst); > > /* serprog.c */ > #if CONFIG_SERPROG == 1 > -- > 2.1.4 > -- -- Best regards, Antony Pavlov _______________________________________________ flashrom mailing list [email protected] http://www.flashrom.org/mailman/listinfo/flashrom
