drivers/mtd/parsers/afs.c

Source file repositories/reference/linux-study-clean/drivers/mtd/parsers/afs.c

File Facts

System
Linux kernel
Corpus path
drivers/mtd/parsers/afs.c
Extension
.c
Size
9332 bytes
Lines
396
Domain
Driver Families
Bucket
drivers/mtd
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct footer_v1 {
	u32 image_info_base;	/* Address of first word of ImageFooter  */
	u32 image_start;	/* Start of area reserved by this footer */
	u32 signature;		/* 'Magic' number proves it's a footer   */
	u32 type;		/* Area type: ARM Image, SIB, customer   */
	u32 checksum;		/* Just this structure                   */
};

struct image_info_v1 {
	u32 bootFlags;		/* Boot flags, compression etc.          */
	u32 imageNumber;	/* Unique number, selects for boot etc.  */
	u32 loadAddress;	/* Address program should be loaded to   */
	u32 length;		/* Actual size of image                  */
	u32 address;		/* Image is executed from here           */
	char name[16];		/* Null terminated                       */
	u32 headerBase;		/* Flash Address of any stripped header  */
	u32 header_length;	/* Length of header in memory            */
	u32 headerType;		/* AIF, RLF, s-record etc.               */
	u32 checksum;		/* Image checksum (inc. this struct)     */
};

static u32 word_sum(void *words, int num)
{
	u32 *p = words;
	u32 sum = 0;

	while (num--)
		sum += *p++;

	return sum;
}

static u32 word_sum_v2(u32 *p, u32 num)
{
	u32 sum = 0;
	int i;

	for (i = 0; i < num; i++) {
		u32 val;

		val = p[i];
		if (val > ~sum)
			sum++;
		sum += val;
	}
	return ~sum;
}

static bool afs_is_v1(struct mtd_info *mtd, u_int off)
{
	/* The magic is 12 bytes from the end of the erase block */
	u_int ptr = off + mtd->erasesize - 12;
	u32 magic;
	size_t sz;
	int ret;

	ret = mtd_read(mtd, ptr, 4, &sz, (u_char *)&magic);
	if (ret < 0) {
		printk(KERN_ERR "AFS: mtd read failed at 0x%x: %d\n",
		       ptr, ret);
		return false;
	}
	if (ret >= 0 && sz != 4)
		return false;

	return (magic == AFSV1_FOOTER_MAGIC);
}

static bool afs_is_v2(struct mtd_info *mtd, u_int off)
{
	/* The magic is the 8 last bytes of the erase block */
	u_int ptr = off + mtd->erasesize - 8;
	u32 foot[2];
	size_t sz;
	int ret;

	ret = mtd_read(mtd, ptr, 8, &sz, (u_char *)foot);
	if (ret < 0) {
		printk(KERN_ERR "AFS: mtd read failed at 0x%x: %d\n",
		       ptr, ret);
		return false;
	}
	if (ret >= 0 && sz != 8)
		return false;

	return (foot[0] == AFSV2_FOOTER_MAGIC1 &&
		foot[1] == AFSV2_FOOTER_MAGIC2);
}

static int afs_parse_v1_partition(struct mtd_info *mtd,

Annotation

Implementation Notes