static ssize_t upgrade_proc_write(struct file *file, const char __user *buf, 
            size_t count, loff_t *ppos)
{
    struct partition_package *package;
    int err;
    size_t size;
    //int len;

    package = kzalloc(count, GFP_KERNEL);
    if (!package) {
        err = -ENOMEM;
        part_err("upgrade_proc_write: fail to malloc package\n");
        goto fail_malloc;
    }

    size = simple_write_to_buffer(package, sizeof(*package), ppos, buf, count);
    if (size < 0) {
        err = size;
        part_err("upgrade_proc_write: fail to receive data(%zu)\n", size);
        goto out;
    }

    err = upgrade_handler(package, size);
    
out:
    kfree(package);
fail_malloc:
    if (err)
        return err;
    else
        return count;
}
static int reload_partition_table(void)
{
    struct file *filp;
    mm_segment_t old_fs;
    long ret;

    filp = filp_open("/dev/block/mmcblk0", O_RDWR, 0); 
    if (IS_ERR(filp)) {
        part_err("%s: open error(%ld)\n", __func__, PTR_ERR(filp));
        return -EIO;
    }   

    if (!filp->f_op || !filp->f_op->unlocked_ioctl) {
        part_err("%s: operation not supported\n", __func__);
        return -EIO;
    }   

    old_fs = get_fs();
    set_fs(KERNEL_DS);

    ret = filp->f_op->unlocked_ioctl(filp, BLKRRPART, 0);
    if (ret < 0) {
        part_err("%s: rrpart error(%ld)\n", __func__, ret);
    }   

    set_fs(old_fs);
    filp_close(filp, NULL);

    return 0;
}
static int __init partition_init(void)
{
    struct proc_dir_entry *partinfo_proc, *upgrade_proc;

    partinfo_proc = proc_create("partinfo", 0444, NULL, &partinfo_proc_fops);
    if (!partinfo_proc) {
        part_err("[%s]fail to register /proc/partinfo\n", __func__);
    }

    upgrade_proc = proc_create("upgrade", 0600, NULL, &upgrade_proc_fops);
    if (!upgrade_proc) {
        part_err("[%s]fail to register /proc/upgrade\n", __func__);
    }

    return 0;
}
static ssize_t upgrade_proc_read(struct file *file, char __user *buf, 
            size_t count, loff_t *ppos)
{
    dev_t devt;
    int partno;
    struct gendisk *disk;

    struct partition_package *package;
    int len; 
    size_t ret;

    devt = blk_lookup_devt("mmcblk0", 0);
    disk = get_gendisk(devt, &partno);

    if (!disk || get_capacity(disk) == 0)
        return 0;

    package = alloc_partition_package(disk, &len);
    if (!package) {
        ret = -ENOMEM;
        part_err("upgrade_proc_read: fail to malloc package\n");
        goto fail_malloc;
    }

    get_partition_package(disk, package);

    ret = simple_read_from_buffer(buf, count, ppos, package, len);

    kfree(package);

fail_malloc:
    return ret;
}
Exemple #5
0
int mt_part_generic_read(part_dev_t *dev, u64 src, uchar *dst, int size, unsigned int part_id)
{
    int dev_id = dev->id;
    uchar *buf = &mt_part_buf[0];
    block_dev_desc_t *blkdev = dev->blkdev;
    u64 end, part_start, part_end, part_len, aligned_start, aligned_end;
    ulong blknr, blkcnt;

	if (!blkdev) {
        part_err("No block device registered\n");
        return -ENODEV;
	}

	if (size == 0) { 
		return 0;
    }

	end = src + size;
	
	part_start    = src &  ((u64)BLK_SIZE - 1);
	part_end      = end &  ((u64)BLK_SIZE - 1);
	aligned_start = src & ~((u64)BLK_SIZE - 1);
	aligned_end   = end & ~((u64)BLK_SIZE - 1);
 
	if (part_start) {
		blknr = aligned_start >> BLK_BITS;	
		part_len = BLK_SIZE - part_start;
        	if (part_len > (u64)size) {
            		part_len = size;
        	}
		if ((blkdev->block_read(dev_id, blknr, 1, (unsigned long*)buf, part_id)) != 1) {
			return -EIO;
        	}
		memcpy(dst, buf + part_start, part_len);
		dst += part_len;
        	src += part_len;
	}
	aligned_start = src & ~((u64)BLK_SIZE - 1);
	blknr  = aligned_start >> BLK_BITS;
	blkcnt = (aligned_end - aligned_start) >> BLK_BITS;
	
	if ((blkdev->block_read(dev_id, blknr, blkcnt, (unsigned long *)(dst), part_id)) != blkcnt) {
		return -EIO;
	}

	src += (blkcnt << BLK_BITS);
	dst += (blkcnt << BLK_BITS);

	if (part_end && src < end) {
	    blknr = aligned_end >> BLK_BITS;	
		if ((blkdev->block_read(dev_id, blknr, 1, (unsigned long*)buf, part_id)) != 1) {
			return -EIO;
        }
		memcpy(dst, buf, part_end);
	}
static int valid_package(struct partition_package *package, int size)
{
    int err = 0;
    int num = package->nr_parts;
    if (size != sizeof(*package) + num * sizeof(struct part_t)) {
        part_err("valid_package: num=%d, total_size=%d\n", num, size);
        err = 1;
    }

    return err;
}