linux/drivers/mtd/sm_ftl.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright © 2009 - Maxim Levitsky
 * SmartMedia/xD translation layer
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/random.h>
#include <linux/hdreg.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <linux/sysfs.h>
#include <linux/bitops.h>
#include <linux/slab.h>
#include <linux/mtd/nand-ecc-sw-hamming.h>
#include "nand/raw/sm_common.h"
#include "sm_ftl.h"



static struct workqueue_struct *cache_flush_workqueue;

static int cache_timeout =;
module_param(cache_timeout, int, S_IRUGO);
MODULE_PARM_DESC();

static int debug;
module_param(debug, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC();


/* ------------------- sysfs attributes ---------------------------------- */
struct sm_sysfs_attribute {};

static ssize_t sm_attr_show(struct device *dev, struct device_attribute *attr,
		     char *buf)
{}


#define NUM_ATTRIBUTES
#define SM_CIS_VENDOR_OFFSET
static struct attribute_group *sm_create_sysfs_attributes(struct sm_ftl *ftl)
{}

static void sm_delete_sysfs_attributes(struct sm_ftl *ftl)
{}


/* ----------------------- oob helpers -------------------------------------- */

static int sm_get_lba(uint8_t *lba)
{}


/*
 * Read LBA associated with block
 * returns -1, if block is erased
 * returns -2 if error happens
 */
static int sm_read_lba(struct sm_oob *oob)
{}

static void sm_write_lba(struct sm_oob *oob, uint16_t lba)
{}


/* Make offset from parts */
static loff_t sm_mkoffset(struct sm_ftl *ftl, int zone, int block, int boffset)
{}

/* Breaks offset into parts */
static void sm_break_offset(struct sm_ftl *ftl, loff_t loffset,
			    int *zone, int *block, int *boffset)
{}

/* ---------------------- low level IO ------------------------------------- */

static int sm_correct_sector(uint8_t *buffer, struct sm_oob *oob)
{}

/* Reads a sector + oob*/
static int sm_read_sector(struct sm_ftl *ftl,
			  int zone, int block, int boffset,
			  uint8_t *buffer, struct sm_oob *oob)
{}

/* Writes a sector to media */
static int sm_write_sector(struct sm_ftl *ftl,
			   int zone, int block, int boffset,
			   uint8_t *buffer, struct sm_oob *oob)
{}

/* ------------------------ block IO ------------------------------------- */

/* Write a block using data and lba, and invalid sector bitmap */
static int sm_write_block(struct sm_ftl *ftl, uint8_t *buf,
			  int zone, int block, int lba,
			  unsigned long invalid_bitmap)
{}


/* Mark whole block at offset 'offs' as bad. */
static void sm_mark_block_bad(struct sm_ftl *ftl, int zone, int block)
{}

/*
 * Erase a block within a zone
 * If erase succeeds, it updates free block fifo, otherwise marks block as bad
 */
static int sm_erase_block(struct sm_ftl *ftl, int zone_num, uint16_t block,
			  int put_free)
{}

/* Thoroughly test that block is valid. */
static int sm_check_block(struct sm_ftl *ftl, int zone, int block)
{}

/* ----------------- media scanning --------------------------------- */
static const struct chs_entry chs_table[] =;


static const uint8_t cis_signature[] =;
/* Find out media parameters.
 * This ideally has to be based on nand id, but for now device size is enough
 */
static int sm_get_media_info(struct sm_ftl *ftl, struct mtd_info *mtd)
{}

/* Validate the CIS */
static int sm_read_cis(struct sm_ftl *ftl)
{}

/* Scan the media for the CIS */
static int sm_find_cis(struct sm_ftl *ftl)
{}

/* Basic test to determine if underlying mtd device if functional */
static int sm_recheck_media(struct sm_ftl *ftl)
{}

/* Initialize a FTL zone */
static int sm_init_zone(struct sm_ftl *ftl, int zone_num)
{}

/* Get and automatically initialize an FTL mapping for one zone */
static struct ftl_zone *sm_get_zone(struct sm_ftl *ftl, int zone_num)
{}


/* ----------------- cache handling ------------------------------------------*/

/* Initialize the one block cache */
static void sm_cache_init(struct sm_ftl *ftl)
{}

/* Put sector in one block cache */
static void sm_cache_put(struct sm_ftl *ftl, char *buffer, int boffset)
{}

/* Read a sector from the cache */
static int sm_cache_get(struct sm_ftl *ftl, char *buffer, int boffset)
{}

/* Write the cache to hardware */
static int sm_cache_flush(struct sm_ftl *ftl)
{}


/* flush timer, runs a second after last write */
static void sm_cache_flush_timer(struct timer_list *t)
{}

/* cache flush work, kicked by timer */
static void sm_cache_flush_work(struct work_struct *work)
{}

/* ---------------- outside interface -------------------------------------- */

/* outside interface: read a sector */
static int sm_read(struct mtd_blktrans_dev *dev,
		   unsigned long sect_no, char *buf)
{}

/* outside interface: write a sector */
static int sm_write(struct mtd_blktrans_dev *dev,
				unsigned long sec_no, char *buf)
{}

/* outside interface: flush everything */
static int sm_flush(struct mtd_blktrans_dev *dev)
{}

/* outside interface: device is released */
static void sm_release(struct mtd_blktrans_dev *dev)
{}

/* outside interface: get geometry */
static int sm_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo)
{}

/* external interface: main initialization function */
static void sm_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
{}

/* main interface: device {surprise,} removal */
static void sm_remove_dev(struct mtd_blktrans_dev *dev)
{}

static struct mtd_blktrans_ops sm_ftl_ops =;

static __init int sm_module_init(void)
{}

static void __exit sm_module_exit(void)
{}

module_init();
module_exit(sm_module_exit);

MODULE_LICENSE();
MODULE_AUTHOR();
MODULE_DESCRIPTION();