diff options
Diffstat (limited to 'ubi-utils/src/eb_chain.c')
-rw-r--r-- | ubi-utils/src/eb_chain.c | 281 |
1 files changed, 0 insertions, 281 deletions
diff --git a/ubi-utils/src/eb_chain.c b/ubi-utils/src/eb_chain.c deleted file mode 100644 index da5c2e3..0000000 --- a/ubi-utils/src/eb_chain.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright (c) International Business Machines Corp., 2006, 2007 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - * Author: Drake Dowsett, dowsett@de.ibm.com - * Contact: Andreas Arnez, arnez@de.ibm.com - */ - -/* see eb_chain.h */ - -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <mtd_swab.h> -#include "unubi_analyze.h" -#include "crc32.h" - -#define COPY(dst, src) \ - do { \ - dst = malloc(sizeof(*dst)); \ - if (dst == NULL) \ - return -ENOMEM; \ - memcpy(dst, src, sizeof(*dst)); \ - } while (0) - - -/** - * inserts an eb_info into the chain starting at head, then searching - * linearly for the correct position; - * new should contain valid vid and ec headers and the data_crc should - * already have been checked before insertion, otherwise the chain - * could be have un an undesired manner; - * returns -ENOMEM if alloc fails, otherwise SHOULD always return 0, - * if not, the code reached the last line and returned -EAGAIN, - * meaning there is a bug or a case not being handled here; - **/ -int -eb_chain_insert(struct eb_info **head, struct eb_info *new) -{ - uint32_t vol, num, ver; - uint32_t new_vol, new_num, new_ver; - struct eb_info *prev, *cur, *hist, *ins; - struct eb_info **prev_ptr; - - if ((head == NULL) || (new == NULL)) - return 0; - - if (*head == NULL) { - COPY(*head, new); - (*head)->next = NULL; - return 0; - } - - new_vol = be32_to_cpu(new->vid.vol_id); - new_num = be32_to_cpu(new->vid.lnum); - new_ver = be32_to_cpu(new->vid.leb_ver); - - /** TRAVERSE HORIZONTALY **/ - - cur = *head; - prev = NULL; - - /* traverse until vol_id/lnum align */ - vol = be32_to_cpu(cur->vid.vol_id); - num = be32_to_cpu(cur->vid.lnum); - while ((new_vol > vol) || ((new_vol == vol) && (new_num > num))) { - /* insert new at end of chain */ - if (cur->next == NULL) { - COPY(ins, new); - ins->next = NULL; - cur->next = ins; - return 0; - } - - prev = cur; - cur = cur->next; - vol = be32_to_cpu(cur->vid.vol_id); - num = be32_to_cpu(cur->vid.lnum); - } - - if (prev == NULL) - prev_ptr = head; - else - prev_ptr = &(prev->next); - - /* insert new into the middle of chain */ - if ((new_vol != vol) || (new_num != num)) { - COPY(ins, new); - ins->next = cur; - *prev_ptr = ins; - return 0; - } - - /** TRAVERSE VERTICALY **/ - - hist = cur; - prev = NULL; - - /* traverse until versions align */ - ver = be32_to_cpu(cur->vid.leb_ver); - while (new_ver < ver) { - /* insert new at bottom of history */ - if (hist->older == NULL) { - COPY(ins, new); - ins->next = NULL; - ins->older = NULL; - hist->older = ins; - return 0; - } - - prev = hist; - hist = hist->older; - ver = be32_to_cpu(hist->vid.leb_ver); - } - - if (prev == NULL) { - /* replace active version */ - COPY(ins, new); - ins->next = hist->next; - *prev_ptr = ins; - - /* place cur in vertical histroy */ - ins->older = hist; - hist->next = NULL; - return 0; - } - - /* insert between versions, beneath active version */ - COPY(ins, new); - ins->next = NULL; - ins->older = prev->older; - prev->older = ins; - return 0; -} - - -/** - * sets the pointer at pos to the position of the first entry in the chain - * with of vol_id and, if given, with the same lnum as *lnum; - * if there is no entry in the chain, then *pos is NULL on return; - * always returns 0; - **/ -int -eb_chain_position(struct eb_info **head, uint32_t vol_id, uint32_t *lnum, - struct eb_info **pos) -{ - uint32_t vol, num; - struct eb_info *cur; - - if ((head == NULL) || (*head == NULL) || (pos == NULL)) - return 0; - - *pos = NULL; - - cur = *head; - while (cur != NULL) { - vol = be32_to_cpu(cur->vid.vol_id); - num = be32_to_cpu(cur->vid.lnum); - - if ((vol_id == vol) && ((lnum == NULL) || (*lnum == num))) { - *pos = cur; - return 0; - } - - cur = cur->next; - } - - return 0; -} - - -/** - * prints to stream, the vol_id, lnum and leb_ver for each entry in the - * chain, starting at head; - * this is intended for debuging purposes; - * always returns 0; - * - * FIXME I do not like the double list traversion ... - **/ -int -eb_chain_print(FILE* stream, struct eb_info *head) -{ - struct eb_info *cur; - - if (stream == NULL) - stream = stdout; - - if (head == NULL) { - fprintf(stream, "EMPTY\n"); - return 0; - } - /* 012345678012345678012345678012301230123 0123 01234567 0123457 01234567*/ - fprintf(stream, "VOL_ID LNUM LEB_VER EC VID DAT PBLK PADDR DSIZE EC\n"); - cur = head; - while (cur != NULL) { - struct eb_info *hist; - - fprintf(stream, "%08x %-8u %08x %-4s%-4s", - be32_to_cpu(cur->vid.vol_id), - be32_to_cpu(cur->vid.lnum), - be32_to_cpu(cur->vid.leb_ver), - cur->ec_crc_ok ? "ok":"bad", - cur->vid_crc_ok ? "ok":"bad"); - if (cur->vid.vol_type == UBI_VID_STATIC) - fprintf(stream, "%-4s", cur->data_crc_ok ? "ok":"bad"); - else fprintf(stream, "%-4s", cur->data_crc_ok ? "ok":"ign"); - fprintf(stream, " %-4d %08x %-8u %-8llu\n", cur->phys_block, - cur->phys_addr, be32_to_cpu(cur->vid.data_size), - (unsigned long long)be64_to_cpu(cur->ec.ec)); - - hist = cur->older; - while (hist != NULL) { - fprintf(stream, "%08x %-8u %08x %-4s%-4s", - be32_to_cpu(hist->vid.vol_id), - be32_to_cpu(hist->vid.lnum), - be32_to_cpu(hist->vid.leb_ver), - hist->ec_crc_ok ? "ok":"bad", - hist->vid_crc_ok ? "ok":"bad"); - if (hist->vid.vol_type == UBI_VID_STATIC) - fprintf(stream, "%-4s", hist->data_crc_ok ? "ok":"bad"); - else fprintf(stream, "%-4s", hist->data_crc_ok ? "ok":"ign"); - fprintf(stream, " %-4d %08x %-8u %-8llu (*)\n", - hist->phys_block, hist->phys_addr, - be32_to_cpu(hist->vid.data_size), - (unsigned long long)be64_to_cpu(hist->ec.ec)); - - hist = hist->older; - } - cur = cur->next; - } - - return 0; -} - - -/** - * frees the memory of the entire chain, starting at head; - * head will be NULL on return; - * always returns 0; - **/ -int -eb_chain_destroy(struct eb_info **head) -{ - if (head == NULL) - return 0; - - while (*head != NULL) { - struct eb_info *cur; - struct eb_info *hist; - - cur = *head; - *head = (*head)->next; - - hist = cur->older; - while (hist != NULL) { - struct eb_info *temp; - - temp = hist; - hist = hist->older; - free(temp); - } - free(cur); - } - return 0; -} - |