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; }
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; }