/*
* YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
*
- * Copyright (C) 2002-2011 Aleph One Ltd.
- * for Toby Churchill Ltd and Brightstar Engineering
+ * Copyright (C) 2002-2018 Aleph One Ltd.
*
* Created by Charles Manning <charles@aleph1.co.uk>
*
#include "linux/mtd/mtd.h"
#include "linux/types.h"
#include "linux/time.h"
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0))
#include "linux/mtd/nand.h"
+#else
+#include "linux/mtd/rawnand.h"
+#endif
#include "linux/kernel.h"
#include "linux/version.h"
#include "linux/types.h"
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
+#include "uapi/linux/major.h"
+#endif
#include "yaffs_trace.h"
#include "yaffs_guts.h"
#include "yaffs_linux.h"
-
-
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
#define MTD_OPS_AUTO_OOB MTD_OOB_AUTO
#endif
#define mtd_block_markbad(m, offs) (m)->block_markbad(m, offs)
#endif
-
-
int nandmtd_erase_block(struct yaffs_dev *dev, int block_no)
{
struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
- u32 addr =
- ((loff_t) block_no) * dev->param.total_bytes_per_chunk *
- dev->param.chunks_per_block;
+ u32 addr = ((loff_t) block_no) * dev->param.total_bytes_per_chunk *
+ dev->param.chunks_per_block;
struct erase_info ei;
int retval = 0;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0))
ei.mtd = mtd;
+#endif
ei.addr = addr;
ei.len = dev->param.total_bytes_per_chunk * dev->param.chunks_per_block;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0))
ei.time = 1000;
ei.retries = 2;
ei.callback = NULL;
ei.priv = (u_long) dev;
+#endif
retval = mtd_erase(mtd, &ei);
return YAFFS_FAIL;
}
-
-static int yaffs_mtd_write(struct yaffs_dev *dev, int nand_chunk,
- const u8 *data, int data_len,
- const u8 *oob, int oob_len)
+static int yaffs_mtd_write(struct yaffs_dev *dev, int nand_chunk,
+ const u8 *data, int data_len,
+ const u8 *oob, int oob_len)
{
struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
loff_t addr;
struct mtd_oob_ops ops;
int retval;
+ yaffs_trace(YAFFS_TRACE_MTD,
+ "yaffs_mtd_write(%p, %d, %p, %d, %p, %d)\n",
+ dev, nand_chunk, data, data_len, oob, oob_len);
+
+ if (!data || !data_len) {
+ data = NULL;
+ data_len = 0;
+ }
+
+ if (!oob || !oob_len) {
+ oob = NULL;
+ oob_len = 0;
+ }
+
addr = ((loff_t) nand_chunk) * dev->param.total_bytes_per_chunk;
memset(&ops, 0, sizeof(ops));
ops.mode = MTD_OPS_AUTO_OOB;
struct mtd_oob_ops ops;
int retval;
- addr = ((loff_t) nand_chunk) * dev->data_bytes_per_chunk;
+ addr = ((loff_t) nand_chunk) * dev->param.total_bytes_per_chunk;
memset(&ops, 0, sizeof(ops));
ops.mode = MTD_OPS_AUTO_OOB;
ops.len = (data) ? data_len : 0;
return YAFFS_OK;
}
-static int yaffs_mtd_erase(struct yaffs_dev *dev, int block_no)
+static int yaffs_mtd_erase(struct yaffs_dev *dev, int block_no)
{
struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
dev->param.chunks_per_block;
addr = ((loff_t) block_no) * block_size;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0))
ei.mtd = mtd;
+#endif
ei.addr = addr;
ei.len = block_size;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0))
ei.time = 1000;
ei.retries = 2;
ei.callback = NULL;
ei.priv = (u_long) dev;
+#endif
retval = mtd_erase(mtd, &ei);
static int yaffs_mtd_mark_bad(struct yaffs_dev *dev, int block_no)
{
struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
- int blocksize = dev->param.chunks_per_block * dev->data_bytes_per_chunk;
+ int blocksize = dev->param.chunks_per_block * dev->param.total_bytes_per_chunk;
int retval;
yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, "marking block %d bad", block_no);
static int yaffs_mtd_check_bad(struct yaffs_dev *dev, int block_no)
{
struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
- int blocksize = dev->param.chunks_per_block * dev->data_bytes_per_chunk;
+ int blocksize = dev->param.chunks_per_block * dev->param.total_bytes_per_chunk;
int retval;
- yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, "checking block %d bad", block_no);
+ yaffs_trace(YAFFS_TRACE_MTD, "checking block %d bad", block_no);
retval = mtd_block_isbad(mtd, (loff_t) blocksize * block_no);
return (retval) ? YAFFS_FAIL : YAFFS_OK;
return YAFFS_OK;
}
-
void yaffs_mtd_drv_install(struct yaffs_dev *dev)
{
struct yaffs_driver *drv = &dev->drv;
drv->drv_deinitialise_fn = yaffs_mtd_deinitialise;
}
-
struct mtd_info * yaffs_get_mtd_device(dev_t sdev)
{
struct mtd_info *mtd;
return 0;
}
-
void yaffs_put_mtd_device(struct mtd_info *mtd)
{
- if(mtd)
+ if (mtd)
put_mtd_device(mtd);
}