xref: /openbmc/linux/drivers/mtd/sm_ftl.h (revision 75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37)
1*d2912cb1SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
27d17c02aSMaxim Levitsky /*
37d17c02aSMaxim Levitsky  * Copyright © 2009 - Maxim Levitsky
47d17c02aSMaxim Levitsky  * SmartMedia/xD translation layer
57d17c02aSMaxim Levitsky  *
67d17c02aSMaxim Levitsky  * Based loosly on ssfdc.c which is
77d17c02aSMaxim Levitsky  *  © 2005 Eptar srl
87d17c02aSMaxim Levitsky  *  Author: Claudio Lanconelli <lanconelli.claudio@eptar.com>
97d17c02aSMaxim Levitsky  */
107d17c02aSMaxim Levitsky 
117d17c02aSMaxim Levitsky #include <linux/mtd/blktrans.h>
127d17c02aSMaxim Levitsky #include <linux/kfifo.h>
137d17c02aSMaxim Levitsky #include <linux/sched.h>
147d17c02aSMaxim Levitsky #include <linux/completion.h>
157d17c02aSMaxim Levitsky #include <linux/mtd/mtd.h>
167d17c02aSMaxim Levitsky 
177d17c02aSMaxim Levitsky 
187d17c02aSMaxim Levitsky 
197d17c02aSMaxim Levitsky struct ftl_zone {
20334e5f56SMaxim Levitsky 	bool initialized;
217d17c02aSMaxim Levitsky 	int16_t *lba_to_phys_table;		/* LBA to physical table */
227d17c02aSMaxim Levitsky 	struct kfifo free_sectors;	/* queue of free sectors */
237d17c02aSMaxim Levitsky };
247d17c02aSMaxim Levitsky 
257d17c02aSMaxim Levitsky struct sm_ftl {
267d17c02aSMaxim Levitsky 	struct mtd_blktrans_dev *trans;
277d17c02aSMaxim Levitsky 
287d17c02aSMaxim Levitsky 	struct mutex mutex;		/* protects the structure */
297d17c02aSMaxim Levitsky 	struct ftl_zone *zones;		/* FTL tables for each zone */
307d17c02aSMaxim Levitsky 
317d17c02aSMaxim Levitsky 	/* Media information */
327d17c02aSMaxim Levitsky 	int block_size;			/* block size in bytes */
337d17c02aSMaxim Levitsky 	int zone_size;			/* zone size in blocks */
347d17c02aSMaxim Levitsky 	int zone_count;			/* number of zones */
357d17c02aSMaxim Levitsky 	int max_lba;			/* maximum lba in a zone */
367d17c02aSMaxim Levitsky 	int smallpagenand;		/* 256 bytes/page nand */
37334e5f56SMaxim Levitsky 	bool readonly;			/* is FS readonly */
38334e5f56SMaxim Levitsky 	bool unstable;
397d17c02aSMaxim Levitsky 	int cis_block;			/* CIS block location */
407d17c02aSMaxim Levitsky 	int cis_boffset;		/* CIS offset in the block */
417d17c02aSMaxim Levitsky 	int cis_page_offset;		/* CIS offset in the page */
427d17c02aSMaxim Levitsky 	void *cis_buffer;		/* tmp buffer for cis reads */
437d17c02aSMaxim Levitsky 
447d17c02aSMaxim Levitsky 	/* Cache */
457d17c02aSMaxim Levitsky 	int cache_block;		/* block number of cached block */
467d17c02aSMaxim Levitsky 	int cache_zone;			/* zone of cached block */
477d17c02aSMaxim Levitsky 	unsigned char *cache_data;	/* cached block data */
487d17c02aSMaxim Levitsky 	long unsigned int cache_data_invalid_bitmap;
49334e5f56SMaxim Levitsky 	bool cache_clean;
507d17c02aSMaxim Levitsky 	struct work_struct flush_work;
517d17c02aSMaxim Levitsky 	struct timer_list timer;
527d17c02aSMaxim Levitsky 
537d17c02aSMaxim Levitsky 	/* Geometry stuff */
547d17c02aSMaxim Levitsky 	int heads;
557d17c02aSMaxim Levitsky 	int sectors;
567d17c02aSMaxim Levitsky 	int cylinders;
577d17c02aSMaxim Levitsky 
587d17c02aSMaxim Levitsky 	struct attribute_group *disk_attributes;
597d17c02aSMaxim Levitsky };
607d17c02aSMaxim Levitsky 
617d17c02aSMaxim Levitsky struct chs_entry {
627d17c02aSMaxim Levitsky 	unsigned long size;
637d17c02aSMaxim Levitsky 	unsigned short cyl;
647d17c02aSMaxim Levitsky 	unsigned char head;
657d17c02aSMaxim Levitsky 	unsigned char sec;
667d17c02aSMaxim Levitsky };
677d17c02aSMaxim Levitsky 
687d17c02aSMaxim Levitsky 
697d17c02aSMaxim Levitsky #define SM_FTL_PARTN_BITS	3
707d17c02aSMaxim Levitsky 
717d17c02aSMaxim Levitsky #define sm_printk(format, ...) \
727d17c02aSMaxim Levitsky 	printk(KERN_WARNING "sm_ftl" ": " format "\n", ## __VA_ARGS__)
737d17c02aSMaxim Levitsky 
747d17c02aSMaxim Levitsky #define dbg(format, ...) \
757d17c02aSMaxim Levitsky 	if (debug) \
767d17c02aSMaxim Levitsky 		printk(KERN_DEBUG "sm_ftl" ": " format "\n", ## __VA_ARGS__)
777d17c02aSMaxim Levitsky 
787d17c02aSMaxim Levitsky #define dbg_verbose(format, ...) \
797d17c02aSMaxim Levitsky 	if (debug > 1) \
807d17c02aSMaxim Levitsky 		printk(KERN_DEBUG "sm_ftl" ": " format "\n", ## __VA_ARGS__)
817d17c02aSMaxim Levitsky 
827d17c02aSMaxim Levitsky 
837d17c02aSMaxim Levitsky static int sm_erase_block(struct sm_ftl *ftl, int zone_num, uint16_t block,
847d17c02aSMaxim Levitsky 								int put_free);
857d17c02aSMaxim Levitsky static void sm_mark_block_bad(struct sm_ftl *ftl, int zone_num, int block);
867d17c02aSMaxim Levitsky 
877d17c02aSMaxim Levitsky static int sm_recheck_media(struct sm_ftl *ftl);
88