firmware/br-ext-chip-allwinner/board/v83x/kernel/patches/00000-drivers_mtd_mtdchar.c...

137 lines
3.7 KiB
Diff

diff -drupN a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
--- a/drivers/mtd/mtdchar.c 2018-08-06 17:23:04.000000000 +0300
+++ b/drivers/mtd/mtdchar.c 2022-06-12 05:28:14.000000000 +0300
@@ -36,6 +36,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/map.h>
+#include <linux/mtd/aw-spinand.h>
#include <asm/uaccess.h>
@@ -52,6 +53,19 @@ struct mtd_file_info {
enum mtd_file_modes mode;
};
+struct burn_param_t {
+ void *buffer;
+ long length;
+};
+
+#if IS_ENABLED(CONFIG_AW_SPINAND_SECURE_STORAGE)
+struct secblc_op_t {
+ int item;
+ unsigned char *buf;
+ unsigned int len;
+};
+#endif
+
static loff_t mtdchar_lseek(struct file *file, loff_t offset, int orig)
{
struct mtd_file_info *mfi = file->private_data;
@@ -664,6 +678,12 @@ static int mtdchar_ioctl(struct file *fi
int ret = 0;
u_long size;
struct mtd_info_user info;
+ struct burn_param_t burn_param;
+ char *boot0_kbuf, *boot1_kbuf;
+#if IS_ENABLED(CONFIG_AW_SPINAND_SECURE_STORAGE)
+ struct secblc_op_t sec_op_st;
+ char *buf_secure;
+#endif
pr_debug("MTD_ioctl\n");
@@ -678,6 +698,91 @@ static int mtdchar_ioctl(struct file *fi
}
switch (cmd) {
+ case BLKBURNBOOT0:
+ if (copy_from_user(&burn_param,
+ (struct burn_param_t __user *)arg,
+ sizeof(burn_param))) {
+ pr_err("nand ioctl input arg err\n");
+ return -EINVAL;
+ }
+
+ boot0_kbuf = vmalloc(burn_param.length + 16 * 1024);
+ if (!boot0_kbuf)
+ return -ENOMEM;
+
+ if (copy_from_user(boot0_kbuf,
+ (const void *)burn_param.buffer, burn_param.length)) {
+ pr_err("nand ioctl input buffer err\n");
+ vfree(boot0_kbuf);
+ return -EINVAL;
+ }
+ ret = aw_spinand_mtd_download_boot0(mtd->priv,
+ burn_param.length, boot0_kbuf);
+ vfree(boot0_kbuf);
+ break;
+ case BLKBURNBOOT1:
+ if (copy_from_user(&burn_param,
+ (struct burn_param_t __user *)arg,
+ sizeof(burn_param))) {
+ pr_err("nand ioctl input arg err\n");
+ return -EINVAL;
+ }
+ boot1_kbuf = vmalloc(burn_param.length + 0x10000);
+ if (!boot1_kbuf)
+ return -ENOMEM;
+
+ if (copy_from_user(boot1_kbuf,
+ (const void *)burn_param.buffer, burn_param.length)) {
+ pr_err("nand ioctl input buffer err\n");
+ vfree(boot1_kbuf);
+ return -EINVAL;
+ }
+ ret = aw_spinand_mtd_download_uboot(mtd->priv,
+ burn_param.length, boot1_kbuf);
+ vfree(boot1_kbuf);
+ break;
+#if IS_ENABLED(CONFIG_AW_SPINAND_SECURE_STORAGE)
+ case SECBLK_READ:
+ if (copy_from_user(&sec_op_st,
+ (struct secblc_op_t __user *)arg,
+ sizeof(sec_op_st))) {
+ pr_err("nand_ioctl input arg err\n");
+ return -EINVAL;
+ }
+ buf_secure = kmalloc(sec_op_st.len, GFP_KERNEL);
+ if (buf_secure == NULL) {
+ pr_err("buf_secure malloc fail!\n");
+ return -ENOMEM;
+ }
+ ret = aw_spinand_mtd_read_secure_storage(mtd->priv,
+ sec_op_st.item, buf_secure, sec_op_st.len);
+ if (copy_to_user(sec_op_st.buf, buf_secure, sec_op_st.len))
+ ret = -EFAULT;
+ kfree(buf_secure);
+ break;
+ case SECBLK_WRITE:
+ if (copy_from_user(&sec_op_st,
+ (struct secblc_op_t __user *)arg,
+ sizeof(sec_op_st))) {
+ pr_err("nand_ioctl input arg err\n");
+ return -EINVAL;
+ }
+ buf_secure = kmalloc(sec_op_st.len, GFP_KERNEL);
+ if (buf_secure == NULL) {
+ pr_err("buf_secure malloc fail!\n");
+ return -ENOMEM;
+ }
+ if (copy_from_user(buf_secure,
+ (const void *)sec_op_st.buf, sec_op_st.len))
+ ret = -EFAULT;
+
+ ret = aw_spinand_mtd_write_secure_storage(mtd->priv,
+ sec_op_st.item, buf_secure, sec_op_st.len);
+ if (copy_to_user(sec_op_st.buf, buf_secure, sec_op_st.len))
+ ret = -EFAULT;
+ kfree(buf_secure);
+ break;
+#endif
case MEMGETREGIONCOUNT:
if (copy_to_user(argp, &(mtd->numeraseregions), sizeof(int)))
return -EFAULT;