Example #1
0
static int unpack_and_verify(struct DM_PARTITION_INFO_PACKET_x *packet, 
            pt_resident *new_part, int *changed, int *pt_change_tb)
{
    int err = 0;
    int i;

    //copy new part
	for (i = 0; i < PART_NUM; i++) {
		memcpy(new_part[i].name, packet->part_info[i].part_name, MAX_PARTITION_NAME_LEN);
		new_part[i].part_id = packet->part_info[i].part_id;
		new_part[i].offset = packet->part_info[i].start_addr;
		new_part[i].size = packet->part_info[i].part_len;
		new_part[i].mask_flags = 0;
		pmt_info("[SD_UPGRADE]new_pt %s size %llx \n", new_part[i].name, new_part[i].size);
	}

    //compare new part and lastest part.
	for (i = 0; i < PART_NUM; i++) {
		if (new_part[i].size != last_part[i].size
            || new_part[i].part_id != last_part[i].part_id 
            || new_part[i].offset != last_part[i].offset) {
			pmt_info("[SD_UPGRADE]new_pt %d size changed from %llx to %llx\n", i, last_part[i].size, new_part[i].size);
			*changed = 1;
			pt_change_tb[i] = 1;
			if ((packet->part_info[i].dl_selected == 0)
                && (packet->part_info[i].visible == 1)) {
				pmt_err("[SD_UPGRADE]please download all image\n");
				err = -EINVAL;
                break;
			}
		}
	}

    return err;
}
Example #2
0
int init_pmt(void)
{
	int err;
    int i;

#ifdef CONFIG_PMT_ENABLE
    pmt_info("[%s]start...(CONFIG_PMT_ENABLE=y)\n", __func__);
#else
    pmt_info("[%s]start...(CONFIG_PMT_ENABLE=n)\n", __func__);
#endif

	if (pmt_done) {
		pmt_info("[%s]skip since init already\n", __func__);
		return 0;
	}

    init_storage_info();

    init_pmt_region();

	last_part = kzalloc(PART_NUM * sizeof(pt_resident), GFP_KERNEL);
	if (!last_part) {
		err = -ENOMEM;
		pmt_err("[%s]fail to malloc last_part\n", __func__);
		goto fail_malloc;
	}

    memset(&pi, 0, sizeof(pt_info));

    err = load_pmt();
    if (err) { 
       pmt_err("[%s]No pmt found and use default part info\n", __func__);
    } else {
        for (i = 0; i < PART_NUM; i++) {  
			PartInfo[i].start_address = last_part[i].offset;
			PartInfo[i].size = last_part[i].size;
        }
    }

    for (i = 0; i < PART_NUM; i++) {  
        pmt_info("Partition[%2d](%-16s) - start(0x%16llx) - size(0x%16llx)\n",
                i, PartInfo[i].name, PartInfo[i].start_address, PartInfo[i].size);
    }

	pmt_done = 1;
	err = 0;

fail_malloc: 
	return err;
}
Example #3
0
static int update_disk_info(pt_resident *new_part, int *pt_change_tb)
{
    int err = 0;
    int i;
    int px;
    unsigned long long start;
    unsigned long long size;


	for (i = 0; i < PART_NUM; i++) {
		if (pt_change_tb[i] == 1 && PartInfo[i].partition_idx != 0) {
            px = PartInfo[i].partition_idx;
            start = new_part[i].offset;
            size = new_part[i].size;
			pmt_info("update p %d %llx %llx\n", px, start, size);
			err = __update_disk_info(px, (u32)(start / 512), (u32)(size/512));
			if (err) {
                err = -1;
				pmt_err("[SD_UPGRADE]update part device offset and size fail\n");
                break;
			}
		}
	}

    return err;
}
Example #4
0
static int __update_disk_info(unsigned int px, unsigned int start, unsigned int size)
{
    int found;
    struct disk_part_iter piter;
	struct hd_struct *part;
	struct gendisk *disk;
	struct storage_info s_info = {0};

	BUG_ON(!msdc_get_info(EMMC_CARD_BOOT, DISK_INFO, &s_info));
	disk = s_info.disk;

    found = 0;

    disk_part_iter_init(&piter, disk, 0);

    while ((part = disk_part_iter_next(&piter))) {
        if (px != 0 && px == part->partno) {
            found = 1;
            pmt_info("[update_disk_info]px = %d size %llx -> %x offset %llx -> %x\n",
                    px, part->nr_sects, size, part->start_sect, start);
            part->start_sect = start;
            part->nr_sects = size;
            break;
        }
    }

    disk_part_iter_exit(&piter);

    return !found;
}
Example #5
0
static int update_msdos_partition(pt_resident *new_part, int *pt_change_tb)
{
    int err = 0;
    int i;
    int px;
    unsigned long long start;
    unsigned long long size;

	for (i = 0; i < PART_NUM; i++) {
		if (pt_change_tb[i] == 1 && PartInfo[i].partition_idx != 0) {
            px = PartInfo[i].partition_idx;
            start = new_part[i].offset - MBR_START_ADDRESS_BYTE;
            size = new_part[i].size;
			pmt_info("update p %d %llx %llx\n", px, start, size);
			err = __update_msdos_partition(px, start, size);
			if (err) {
                err = -1;
				pmt_err("[SD_UPGRADE]update_msdos_partition fail\n");
				break;
			}
		}
	}

    return err;
}
Example #6
0
static int read_pmt(void __user *arg)
{
    pmt_info("read_pmt\n");
    if (copy_to_user(arg, last_part, sizeof(pt_resident) * PART_NUM)) {
        return -EFAULT;
    }
    return 0;
}
Example #7
0
static void init_storage_info(void)
{
	struct storage_info s_info = {0};

    msdc_check_init_done();

    BUG_ON(!msdc_get_info(EMMC_CARD_BOOT, EMMC_CAPACITY, &s_info));
    BUG_ON(!msdc_get_info(EMMC_CARD_BOOT, EMMC_USER_CAPACITY, &s_info)); 

	emmc_user_size = s_info.emmc_user_capacity * 512;
	emmc_total_size = s_info.emmc_capacity * 512;
	pmt_info("[%s]emmc_total_size = 0x%llx, user_region_size = 0x%llx\n", __func__,
                emmc_total_size, emmc_user_size);
}
Example #8
0
static int __init pmt_init(void)
{
    struct proc_dir_entry *pmt_upgrade_proc;

    pmt_upgrade_proc = create_proc_entry("sd_upgrade", 0600, NULL);
    if (pmt_upgrade_proc) {
        pmt_upgrade_proc->write_proc = pmt_upgrade_proc_write;
        pmt_info("[%s]success to register /proc/sd_upgrade(%pf)\n", __func__, pmt_upgrade_proc->write_proc);
    } else {
        pmt_err("[%s]fail to register /proc/sd_upgrade\n", __func__);
    }

    create_pmt_cdev();

    return 0;
}
Example #9
0
static int pmt_upgrade_handler(struct DM_PARTITION_INFO_PACKET_x *packet)
{
    int err;
	pt_resident *new_part;
	int pt_changed = 0;
	int pt_change_tb[PART_NUM] = {0};

	new_part = kzalloc(PART_NUM * sizeof(pt_resident), GFP_KERNEL);
	if (!new_part) {
        err = -ENOMEM;
        pmt_err("sd_upgrade_handler: fail to malloc new_part\n");
        goto fail_malloc;
	}

    err = unpack_and_verify(packet, new_part, &pt_changed, pt_change_tb);
    if (err) {
        goto out;
    }

	if (!pt_changed) {
		pmt_info("[SD_UPGRADE]layout can not change,skip update PMT/MBR\n");
		goto out;
	}

    memcpy(last_part, new_part, PART_NUM * sizeof(pt_resident));
    err = store_pmt(PMT_UPDATE_BY_UPGRADE);

    update_part_size(new_part, pt_change_tb);

    err = update_msdos_partition(new_part, pt_change_tb);
    if (err) {
        goto out;
    }

    err = update_disk_info(new_part, pt_change_tb);
    if (err) {
        goto out;
    }

out:
	kfree(new_part);

fail_malloc:
    return err;
}
Example #10
0
static int pmt_region_unpack(struct pmt_region *region, void *buf, pt_resident *part)
{
    int err;
    unsigned int head_sig, tail_sig;
    void *ptr;

    /* head sig info */
    ptr = buf;
    head_sig = *(unsigned int *)ptr;

    /* tail sig info */
    ptr += region->size - PT_SIG_SIZE;
    tail_sig = *(unsigned int *)ptr;

    if (head_sig != region->sig || tail_sig != region->sig) {
        err = -EINVAL;
        pmt_err("[%s]%s: head_sig = 0x%08x, tail_sig = 0x%08x\n",
                __func__, region->name, head_sig, tail_sig);
        goto out;
    }

    /* version info */
    ptr = buf + PT_SIG_SIZE;
    if (!memcmp(ptr, PMT_VER_V1P1, PMT_VER_SIZE)) {
        /* partition info */
        ptr += PMT_VER_SIZE;
        memcpy(part, ptr, PART_NUM * sizeof(pt_resident));
        err = DM_ERR_OK;
        pmt_info(KERN_NOTICE "find %s at 0x%llx, ver %s\n", 
                region->name, region->base_addr, PMT_VER_V1P1);
    } else {
        pmt_err(KERN_ERR "invalid pt version %s\n", ptr);
        err = ERR_NO_EXIST;
        goto out;
    }

    /* pt_info info */
    ptr = buf + region->size - PT_SIG_SIZE - sizeof(pi);
    pi.sequencenumber = *(unsigned char *)ptr;
    ptr++;
    pi.tool_or_sd_update = *(unsigned char *)ptr & 0xF;

out:
    return err;
}
Example #11
0
static int __update_msdos_partition(int px, unsigned long long start, unsigned long long size)
{
    int err = 0;

	int i, slot; 
	int xbr_idx = 0;
	char *this_name = NULL;
	unsigned long long this_addr;

	unsigned char *buf = NULL;
	struct partition *p;
		
	buf = kzalloc(512, GFP_KERNEL);
	if (!buf) {
		err = -ENOMEM;
		pmt_err("update_msdos_partition: malloc buf fail\n");
		goto fail_malloc;
	}
	
	//find px in which mbr/ebr.
	for (i = 0;i < MBR_COUNT; i++) {
		for (slot = 0; slot < 4; slot++) {
			if (MBR_EBR_px[i].part_index[slot] == px) {
                /* this_name is mbr or ebrx */
				xbr_idx = i;
				this_name = MBR_EBR_px[i].part_name;  
                goto found;
			}
		}
	}

	if (slot >= 4) {
		pmt_err("p%d can not be found in mbr\n", px);
		err = -EINVAL;
		goto out;
	}

found:
	pmt_info("update %s\n", this_name);

    /* check mbr or ebrx partition info */
	for (i = 0; i < PART_NUM; i++) {
		if (!strcmp(this_name, PartInfo[i].name)) {
			this_addr = PartInfo[i].start_address;
			pmt_info("update %s addr %llx\n", this_name, this_addr);
			break;
		}
	}

	if (i == PART_NUM) {
		pmt_err("can not find %s\n", this_name);
		err = -EINVAL;
		goto out;
	} 

    /* read mbr or ebr into buf */
	err = eMMC_rw_x(this_addr, (u32*)buf, 0, 0, 512, 1, EMMC_PART_USER);
	if (err || !msdos_magic_present(buf + 510)) {
		pmt_err("read %s error\n", this_name);
        err = -EIO;
		goto out;
	}

	if (!msdos_magic_present(buf + 510)) {
		pmt_err("read MBR/EBR fail\n");
		err = -1;
		goto out;
	}

	p = (struct partition *) (buf + 0x1be);

	p[slot].start_sect = (unsigned int)((start - this_addr) / 512);
	p[slot].nr_sects = (unsigned int)(size / 512);

	err = eMMC_rw_x(this_addr, (u32*)buf, 0, 1, 512, 1, EMMC_PART_USER);
	if (err) {
		pmt_err("write %s error\n", this_name);
        err = -EIO;
		goto out;
	}

out:
	kfree(buf);
fail_malloc:
	return err;
}