⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmd_jffs2.c

📁 u-boot-1.1.6 源码包
💻 C
📖 第 1 页 / 共 4 页
字号:
		if (new_pi->offset <= pi->offset) {			list_add_tail(&part->link, entry);			dev->num_parts++;			if (curr_pi && (pi->offset <= curr_pi->offset)) {				/* we are modyfing partitions for the current				 * device, update current */				current_partnum++;				current_save();			} else {				index_partitions();			}			return 0;		}	}	list_add_tail(&part->link, &dev->parts);	dev->num_parts++;	index_partitions();	return 0;}/** * Add provided partition to the partition list of a given device. * * @param dev device to which partition is added * @param part partition to be added * @return 0 on success, 1 otherwise */static int part_add(struct mtd_device *dev, struct part_info *part){	/* verify alignment and size */	if (part_validate(dev->id, part) != 0)		return 1;	/* partition is ok, add it to the list */	if (part_sort_add(dev, part) != 0)		return 1;	return 0;}/** * Parse one partition definition, allocate memory and return pointer to this * location in retpart. * * @param partdef pointer to the partition definition string i.e. <part-def> * @param ret output pointer to next char after parse completes (output) * @param retpart pointer to the allocated partition (output) * @return 0 on success, 1 otherwise */static int part_parse(const char *const partdef, const char **ret, struct part_info **retpart){	struct part_info *part;	unsigned long size;	unsigned long offset;	const char *name;	int name_len;	unsigned int mask_flags;	const char *p;	p = partdef;	*retpart = NULL;	*ret = NULL;	/* fetch the partition size */	if (*p == '-') {		/* assign all remaining space to this partition */		DEBUGF("'-': remaining size assigned\n");		size = SIZE_REMAINING;		p++;	} else {		size = memsize_parse(p, &p);		if (size < MIN_PART_SIZE) {			printf("partition size too small (%lx)\n", size);			return 1;		}	}	/* check for offset */	offset = OFFSET_NOT_SPECIFIED;	if (*p == '@') {		p++;		offset = memsize_parse(p, &p);	}	/* now look for the name */	if (*p == '(') {		name = ++p;		if ((p = strchr(name, ')')) == NULL) {			printf("no closing ) found in partition name\n");			return 1;		}		name_len = p - name + 1;		if ((name_len - 1) == 0) {			printf("empty partition name\n");			return 1;		}		p++;	} else {		/* 0x00000000@0x00000000 */		name_len = 22;		name = NULL;	}	/* test for options */	mask_flags = 0;	if (strncmp(p, "ro", 2) == 0) {		mask_flags |= MTD_WRITEABLE_CMD;		p += 2;	}	/* check for next partition definition */	if (*p == ',') {		if (size == SIZE_REMAINING) {			*ret = NULL;			printf("no partitions allowed after a fill-up partition\n");			return 1;		}		*ret = ++p;	} else if ((*p == ';') || (*p == '\0')) {		*ret = p;	} else {		printf("unexpected character '%c' at the end of partition\n", *p);		*ret = NULL;		return 1;	}	/*  allocate memory */	part = (struct part_info *)malloc(sizeof(struct part_info) + name_len);	if (!part) {		printf("out of memory\n");		return 1;	}	memset(part, 0, sizeof(struct part_info) + name_len);	part->size = size;	part->offset = offset;	part->mask_flags = mask_flags;	part->name = (char *)(part + 1);	if (name) {		/* copy user provided name */		strncpy(part->name, name, name_len - 1);		part->auto_name = 0;	} else {		/* auto generated name in form of size@offset */		sprintf(part->name, "0x%08lx@0x%08lx", size, offset);		part->auto_name = 1;	}	part->name[name_len - 1] = '\0';	INIT_LIST_HEAD(&part->link);	DEBUGF("+ partition: name %-22s size 0x%08x offset 0x%08x mask flags %d\n",			part->name, part->size,			part->offset, part->mask_flags);	*retpart = part;	return 0;}#endif/* #ifdef CONFIG_JFFS2_CMDLINE *//** * Check device number to be within valid range for given device type. * * @param dev device to validate * @return 0 if device is valid, 1 otherwise */static int device_validate(u8 type, u8 num, u32 *size){	if (type == MTD_DEV_TYPE_NOR) {#if (CONFIG_COMMANDS & CFG_CMD_FLASH)		if (num < CFG_MAX_FLASH_BANKS) {			extern flash_info_t flash_info[];			*size = flash_info[num].size;			return 0;		}		printf("no such FLASH device: %s%d (valid range 0 ... %d\n",				MTD_DEV_TYPE(type), num, CFG_MAX_FLASH_BANKS - 1);#else		printf("support for FLASH devices not present\n");#endif	} else if (type == MTD_DEV_TYPE_NAND) {#if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND)		if (num < CFG_MAX_NAND_DEVICE) {#ifndef CFG_NAND_LEGACY			*size = nand_info[num].size;#else			extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE];			*size = nand_dev_desc[num].totlen;#endif			return 0;		}		printf("no such NAND device: %s%d (valid range 0 ... %d)\n",				MTD_DEV_TYPE(type), num, CFG_MAX_NAND_DEVICE - 1);#else		printf("support for NAND devices not present\n");#endif	}	return 1;}#ifdef CONFIG_JFFS2_CMDLINE/** * Delete all mtd devices from a supplied devices list, free memory allocated for * each device and delete all device partitions. * * @return 0 on success, 1 otherwise */static int device_delall(struct list_head *head){	struct list_head *entry, *n;	struct mtd_device *dev_tmp;	/* clean devices list */	list_for_each_safe(entry, n, head) {		dev_tmp = list_entry(entry, struct mtd_device, link);		list_del(entry);		part_delall(&dev_tmp->parts);		free(dev_tmp);	}	INIT_LIST_HEAD(&devices);	return 0;}/** * If provided device exists it's partitions are deleted, device is removed * from device list and device memory is freed. * * @param dev device to be deleted * @return 0 on success, 1 otherwise */static int device_del(struct mtd_device *dev){	part_delall(&dev->parts);	list_del(&dev->link);	free(dev);	if (dev == current_dev) {		/* we just deleted current device */		if (list_empty(&devices)) {			current_dev = NULL;		} else {			/* reset first partition from first dev from the			 * devices list as current */			current_dev = list_entry(devices.next, struct mtd_device, link);			current_partnum = 0;		}		current_save();		return 0;	}	index_partitions();	return 0;}/** * Search global device list and return pointer to the device of type and num * specified. * * @param type device type * @param num device number * @return NULL if requested device does not exist */static struct mtd_device* device_find(u8 type, u8 num){	struct list_head *entry;	struct mtd_device *dev_tmp;	list_for_each(entry, &devices) {		dev_tmp = list_entry(entry, struct mtd_device, link);		if ((dev_tmp->id->type == type) && (dev_tmp->id->num == num))			return dev_tmp;	}	return NULL;}/** * Add specified device to the global device list. * * @param dev device to be added */static void device_add(struct mtd_device *dev){	u8 current_save_needed = 0;	if (list_empty(&devices)) {		current_dev = dev;		current_partnum = 0;		current_save_needed = 1;	}	list_add_tail(&dev->link, &devices);	if (current_save_needed > 0)		current_save();	else		index_partitions();}/** * Parse device type, name and mtd-id. If syntax is ok allocate memory and * return pointer to the device structure. * * @param mtd_dev pointer to the device definition string i.e. <mtd-dev> * @param ret output pointer to next char after parse completes (output) * @param retdev pointer to the allocated device (output) * @return 0 on success, 1 otherwise */static int device_parse(const char *const mtd_dev, const char **ret, struct mtd_device **retdev){	struct mtd_device *dev;	struct part_info *part;	struct mtdids *id;	const char *mtd_id;	unsigned int mtd_id_len;	const char *p, *pend;	LIST_HEAD(tmp_list);	struct list_head *entry, *n;	u16 num_parts;	u32 offset;	int err = 1;	p = mtd_dev;	*retdev = NULL;	*ret = NULL;	DEBUGF("===device_parse===\n");	/* fetch <mtd-id> */	mtd_id = p;	if (!(p = strchr(mtd_id, ':'))) {		printf("no <mtd-id> identifier\n");		return 1;	}	mtd_id_len = p - mtd_id + 1;	p++;	/* verify if we have a valid device specified */	if ((id = id_find_by_mtd_id(mtd_id, mtd_id_len - 1)) == NULL) {		printf("invalid mtd device '%.*s'\n", mtd_id_len - 1, mtd_id);		return 1;	}	DEBUGF("dev type = %d (%s), dev num = %d, mtd-id = %s\n",			id->type, MTD_DEV_TYPE(id->type),			id->num, id->mtd_id);	pend = strchr(p, ';');	DEBUGF("parsing partitions %.*s\n", (pend ? pend - p : strlen(p)), p);	/* parse partitions */	num_parts = 0;	offset = 0;	if ((dev = device_find(id->type, id->num)) != NULL) {		/* if device already exists start at the end of the last partition */		part = list_entry(dev->parts.prev, struct part_info, link);		offset = part->offset + part->size;	}	while (p && (*p != '\0') && (*p != ';')) {		err = 1;		if ((part_parse(p, &p, &part) != 0) || (!part))			break;		/* calculate offset when not specified */		if (part->offset == OFFSET_NOT_SPECIFIED)			part->offset = offset;		else			offset = part->offset;		/* verify alignment and size */		if (part_validate(id, part) != 0)			break;		offset += part->size;		/* partition is ok, add it to the list */		list_add_tail(&part->link, &tmp_list);		num_parts++;		err = 0;	}	if (err == 1) {		part_delall(&tmp_list);		return 1;	}	if (num_parts == 0) {		printf("no partitions for device %s%d (%s)\n",				MTD_DEV_TYPE(id->type), id->num, id->mtd_id);		return 1;	}	DEBUGF("\ntotal partitions: %d\n", num_parts);	/* check for next device presence */	if (p) {		if (*p == ';') {			*ret = ++p;		} else if (*p == '\0') {			*ret = p;		} else {			printf("unexpected character '%c' at the end of device\n", *p);			*ret = NULL;			return 1;		}	}	/* allocate memory for mtd_device structure */	if ((dev = (struct mtd_device *)malloc(sizeof(struct mtd_device))) == NULL) {		printf("out of memory\n");		return 1;	}	memset(dev, 0, sizeof(struct mtd_device));	dev->id = id;	dev->num_parts = 0; /* part_sort_add increments num_parts */	INIT_LIST_HEAD(&dev->parts);	INIT_LIST_HEAD(&dev->link);	/* move partitions from tmp_list to dev->parts */	list_for_each_safe(entry, n, &tmp_list) {		part = list_entry(entry, struct part_info, link);		list_del(entry);		if (part_sort_add(dev, part) != 0) {			device_del(dev);			return 1;		}	}	*retdev = dev;	DEBUGF("===\n\n");	return 0;}/** * Initialize global device list. * * @return 0 on success, 1 otherwise */static int devices_init(void){	last_parts[0] = '\0';	current_dev = NULL;	current_save();	return device_delall(&devices);}/* * Search global mtdids list and find id of requested type and number. * * @return pointer to the id if it exists, NULL otherwise */static struct mtdids* id_find(u8 type, u8 num){	struct list_head *entry;	struct mtdids *id;	list_for_each(entry, &mtdids) {		id = list_entry(entry, struct mtdids, link);		if ((id->type == type) && (id->num == num))			return id;	}	return NULL;}/** * Search global mtdids list and find id of a requested mtd_id. * * Note: first argument is not null terminated. * * @param mtd_id string containing requested mtd_id * @param mtd_id_len length of supplied mtd_id * @return pointer to the id if it exists, NULL otherwise */static struct mtdids* id_find_by_mtd_id(const char *mtd_id, unsigned int mtd_id_len){	struct list_head *entry;	struct mtdids *id;	DEBUGF("--- id_find_by_mtd_id: '%.*s' (len = %d)\n",			mtd_id_len, mtd_id, mtd_id_len);	list_for_each(entry, &mtdids) {		id = list_entry(entry, struct mtdids, link);		DEBUGF("entry: '%s' (len = %d)\n",				id->mtd_id, strlen(id->mtd_id));		if (mtd_id_len != strlen(id->mtd_id))			continue;		if (strncmp(id->mtd_id, mtd_id, mtd_id_len) == 0)			return id;	}	return NULL;}#endif /* #ifdef CONFIG_JFFS2_CMDLINE *//** * Parse device id string <dev-id> := 'nand'|'nor'<dev-num>, return device * type and number. * * @param id string describing device id * @param ret_id output pointer to next char after parse completes (output) * @param dev_type parsed device type (output) * @param dev_num parsed device number (output) * @return 0 on success, 1 otherwise */int id_parse(const char *id, const char **ret_id, u8 *dev_type, u8 *dev_num){	const char *p = id;	*dev_type = 0;	if (strncmp(p, "nand", 4) == 0) {		*dev_type = MTD_DEV_TYPE_NAND;		p += 4;	} else if (strncmp(p, "nor", 3) == 0) {		*dev_type = MTD_DEV_TYPE_NOR;		p += 3;	} else {		printf("incorrect device type in %s\n", id);		return 1;	}	if (!isdigit(*p)) {		printf("incorrect device number in %s\n", id);		return 1;	}	*dev_num = simple_strtoul(p, (char **)&p, 0);	if (ret_id)		*ret_id = p;	return 0;}#ifdef CONFIG_JFFS2_CMDLINE

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -