diff -uNr mtd-19990820/include/linux/mtd/mtd.h mtd-19991025/include/linux/mtd/mtd.h --- mtd-19990820/include/linux/mtd/mtd.h Thu Aug 19 23:59:04 1999 +++ mtd-19991025/include/linux/mtd/mtd.h Sat Oct 16 19:22:09 1999 @@ -2,6 +2,15 @@ #ifndef __MTD_MTD_H__ #define __MTD_MTD_H__ +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) + +#define DECLARE_WAIT_QUEUE_HEAD(x) struct wait_queue *x = NULL +#define wait_queue_head_t struct wait_queue * +#define init_waitqueue_head init_waitqueue +#define DECLARE_WAITQUEUE (x,y) struct wait_queue x = {y, NULL}; +#endif + #ifdef __KERNEL__ #include #endif diff -uNr mtd-19990820/include/linux/mtd/nftl.h mtd-19991025/include/linux/mtd/nftl.h --- mtd-19990820/include/linux/mtd/nftl.h Fri Aug 20 16:31:01 1999 +++ mtd-19991025/include/linux/mtd/nftl.h Sat Oct 16 19:22:14 1999 @@ -77,6 +77,10 @@ __u16 MediaUnit, SpareMediaUnit; __u32 EraseSize; struct NFTLMediaHeader MediaHdr; + int usecount; + unsigned char heads; + unsigned char sectors; + unsigned short cylinders; __u16 numvunits; __u16 lastEUN; __u16 numfreeEUNs; diff -uNr mtd-19990820/kernel/Config.in mtd-19991025/kernel/Config.in --- mtd-19990820/kernel/Config.in Thu Jan 1 01:00:00 1970 +++ mtd-19991025/kernel/Config.in Fri Sep 17 16:55:17 1999 @@ -0,0 +1,14 @@ +tristate 'Memory Technology Device (MTD) support' CONFIG_MTD + +if [ "$CONFIG_MTD" != "n" ]; then + dep_tristate 'M-Systems Disk-On-Chip 1000 support' CONFIG_MTD_DOC1000 $CONFIG_MTD + dep_tristate 'M-Systems Disk-On-Chip 2000' CONFIG_MTD_DOC2000 $CONFIG_MTD + dep_tristate 'Use extra onboard system memory as MTD device' CONFIG_MTD_SLRAM $CONFIG_MTD + dep_tristate 'Octagon 5066 SBC onboard flash support' CONFIG_MTD_OCTAGON $CONFIG_MTD + dep_tristate 'Tempustech VMAX SBC301 onboard flash support' CONFIG_MTD_VMAX $CONFIG_MTD + dep_tristate 'Mixcom piggyback flash card support' CONFIG_MTD_MIXMEM $CONFIG_MTD + + dep_tristate 'FTL (Flash Translation Layer) support' CONFIG_FTL $CONFIG_MTD + dep_tristate 'NFTL (NAND Flash Translation Layer) support' CONFIG_NFTL $CONFIG_MTD + dep_tristate 'Direct blockdevice access to MTD devices' CONFIG_MTDBLOCK $CONFIG_MTD +fi diff -uNr mtd-19990820/kernel/Makefile mtd-19991025/kernel/Makefile --- mtd-19990820/kernel/Makefile Fri Aug 20 16:31:01 1999 +++ mtd-19991025/kernel/Makefile Mon Oct 25 15:55:46 1999 @@ -1,25 +1,106 @@ -# $Id: Makefile,v 1.7 1999/08/20 15:31:01 dwmw2 Exp $ +# $Id: Makefile,v 1.8 1999/10/25 14:55:46 dwmw2 Exp $ + +ifndef CONFIG_MTD +# We're being invoked outside a normal kernel build. Fake it EXTRA_CFLAGS= -I$(shell pwd)/../include HWDRIVERS = slram.o doc1000.o doc2000.o vmax301.o octagon-5066.o USERDRIVERS = ftl.o nftl.o mtdblock.o - MIX_OBJS = mtd.o mapped.o MI_OBJS = $(HWDRIVERS) $(USERDRIVERS) -include $(TOPDIR)/Rules.make - - +else -#all : $(TARGETS) +O_TARGET := mtdlink.o +SUB_DIRS := +ALL_SUB_DIRS := +MOD_LIST_NAME := MTD_MODULES + + +ifeq ($(CONFIG_MTD),y) + OX_OBJS += mtd.o mapped.o +else + ifeq ($(CONFIG_MTD_DOC1000),m) + MX_OBJS += mtd.o mapped.o + endif +endif + +ifeq ($(CONFIG_MTD_DOC1000),y) + O_OBJS += doc1000.o +else + ifeq ($(CONFIG_MTD_DOC1000),m) + M_OBJS += doc1000.o + endif +endif + +ifeq ($(CONFIG_MTD_DOC2000),y) + O_OBJS += doc2000.o +else + ifeq ($(CONFIG_MTD_DOC2000),m) + M_OBJS += doc2000.o + endif +endif + +ifeq ($(CONFIG_MTD_SLRAM),y) + O_OBJS += slram.o +else + ifeq ($(CONFIG_MTD_SLRAM),m) + M_OBJS += slram.o + endif +endif + +ifeq ($(CONFIG_MTD_OCTAGON),y) + O_OBJS += octagon-5066.o +else + ifeq ($(CONFIG_MTD_OCTAGON),m) + M_OBJS += octagon-5066.o + endif +endif + +ifeq ($(CONFIG_MTD_VMAX),y) + O_OBJS += vmax301.o +else + ifeq ($(CONFIG_MTD_VMAX),m) + M_OBJS += vmax301.o + endif +endif + +ifeq ($(CONFIG_MTD_MIXMEM),y) + O_OBJS += mixmem.o +else + ifeq ($(CONFIG_MTD_MIXMEM),m) + M_OBJS += mixmem.o + endif +endif + +ifeq ($(CONFIG_FTL),y) + O_OBJS += ftl.o +else + ifeq ($(CONFIG_FTL),m) + M_OBJS += ftl.o + endif +endif + +ifeq ($(CONFIG_NFTL),y) + O_OBJS += nftl.o +else + ifeq ($(CONFIG_NFTL),m) + M_OBJS += nftl.o + endif +endif + +ifeq ($(CONFIG_MTD_BLOCK),y) + O_OBJS += mtdblock.o +else + ifeq ($(CONFIG_MTD_BLOCK),m) + M_OBJS += mtdblock.o + endif +endif -#flashcard.o mtd.o physmem.o ftl.o: ../include/mtd.h -#ftl.o: ../include/ftl.h ftl.c -#flashcard.o: ../include/iflash.h flashcard.c +endif -#clean: +include $(TOPDIR)/Rules.make -# rm -f $(TARGETS) $(wildcard ffs2/*.o) diff -uNr mtd-19990820/kernel/doc1000.c mtd-19991025/kernel/doc1000.c --- mtd-19990820/kernel/doc1000.c Tue Aug 17 17:36:21 1999 +++ mtd-19991025/kernel/doc1000.c Mon Oct 25 15:55:46 1999 @@ -1,6 +1,6 @@ /*====================================================================== - $Id: doc1000.c,v 1.3 1999/08/17 16:36:03 dwmw2 Exp $ + $Id: doc1000.c,v 1.4 1999/10/25 14:55:46 dwmw2 Exp $ A general driver for accessing PCMCIA card memory via Bulk Memory Services. @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -70,19 +71,16 @@ u_short numdevices; u_char interleave; struct erase_info *cur_erases; - struct wait_queue *wq; + wait_queue_head_t wq; u_char devstat[MAX_FLASH_DEVICES]; - u_long devsize; + u_long devshift; }; static void flashcard_periodic(u_long data); static int flashcard_erase (struct mtd_info *mtd, struct erase_info *instr); -static int flashcard_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf); -static void flashcard_unpoint (struct mtd_info *mtd, u_char * addr); static int flashcard_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); static int flashcard_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); -static void flashcard_openclose (struct mtd_info *mtd, int which); static void flashcard_sync (struct mtd_info *mtd); static inline void resume_erase(volatile u_char *addr); @@ -134,8 +132,8 @@ pageaddr=pagein(mtd,instr->addr); instr->mtd = mtd; - instr->dev = instr->addr / priv->devsize; - instr->cell = (instr->addr & (priv->devsize - 1)) / mtd->erasesize; + instr->dev = instr->addr >> priv->devshift; + instr->cell = (instr->addr - (instr->dev << priv->devshift)) / mtd->erasesize; instr->next = NULL; instr->state = MTD_ERASE_PENDING; @@ -149,40 +147,13 @@ return 0; } -int flashcard_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf) -{ - u_char *pageaddr = pagein(mtd,from); - struct mypriv *priv=mtd->priv; - u_char device = from / priv->devsize; - - *mtdbuf = pageaddr; - if ((from & WINDOW_MASK) + len <= WINDOW_SIZE) - *retlen = len; - else - *retlen = WINDOW_SIZE - (from & WINDOW_MASK); - - if (priv->devstat[device]) - { - /* There is an erase in progress or pending. Make them use flashcard_read() */ - return -EBUSY; - } - writew(IF_READ_ARRAY, (u_long)pageaddr & ~1); - -/* printk("Buffer is at %p, copying %lx bytes - %lx %lx.",pageaddr,*retlen, *(u_long *)pageaddr, *(u_long *)pageaddr +4); - */ return 0; -} - -void flashcard_unpoint (struct mtd_info *mtd, u_char * addr) -{ - writew(IF_READ_CSR, addr); -} int flashcard_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { u_char *pageaddr=pagein(mtd,from); struct mypriv *priv=mtd->priv; - u_char device = from / priv->devsize; - u_char cell = (from & (priv->devsize - 1)) / mtd->erasesize; + u_char device = from >> priv->devshift; + u_char cell = (from - (device << priv->devshift)) / mtd->erasesize; int ret = 0, timeron = 0; if ((from & WINDOW_MASK) + len <= WINDOW_SIZE) @@ -248,7 +219,7 @@ struct mypriv *priv = (struct mypriv *)mtd->priv; u_char *endaddr, *startaddr; register u_char *pageaddr; - u_char device = to / priv->devsize; + u_char device = to >> priv->devshift; /* jiffies_t oldj=jiffies;*/ int ret; @@ -547,7 +518,7 @@ } -int init_module(void) +static int __init init_doc1000(void) { struct mypriv *priv; @@ -579,7 +550,8 @@ priv=mymtd->priv; - + init_waitqueue_head(&priv->wq); + memset (priv,0,sizeof(struct mypriv)); priv->baseaddr = phys_to_virt(base); @@ -590,15 +562,15 @@ mymtd->size = 0x400000; mymtd->flags = MTD_CLEAR_BITS | MTD_ERASEABLE; mymtd->erase = flashcard_erase; - mymtd->point = flashcard_point; - mymtd->unpoint = flashcard_unpoint; + mymtd->point = NULL; + mymtd->unpoint = NULL; mymtd->read = flashcard_read; mymtd->write = flashcard_write; mymtd->sync = flashcard_sync; mymtd->erasesize = 0x20000; // mymtd->interleave = 2; - priv->devsize = 0x1000000; + priv->devshift = 24; mymtd->type = MTD_NORFLASH; if (add_mtd_device(mymtd)) @@ -615,13 +587,15 @@ return 0; } -void cleanup_module(void) +static void __init cleanup_doc1000(void) { kfree (mymtd->priv); del_mtd_device(mymtd); kfree(mymtd); } +module_init (init_doc1000); +module_exit(cleanup_doc1000); diff -uNr mtd-19990820/kernel/doc2000.c mtd-19991025/kernel/doc2000.c --- mtd-19990820/kernel/doc2000.c Fri Aug 20 16:31:01 1999 +++ mtd-19991025/kernel/doc2000.c Mon Oct 25 15:55:46 1999 @@ -2,7 +2,7 @@ /* Linux driver for Disk-On-Chip 2000 */ /* (c) 1999 Machine Vision Holdings, Inc. */ /* Author: David Woodhouse */ -/* $Id: doc2000.c,v 1.7 1999/08/20 15:31:01 dwmw2 Exp $ */ +/* $Id: doc2000.c,v 1.8 1999/10/25 14:55:46 dwmw2 Exp $ */ /* DOC_PASSIVE_PROBE: @@ -35,7 +35,7 @@ #include #include #include - +#include #include #include @@ -46,6 +46,14 @@ #warning The DiskOnChip driver is not SMP safe. I need to add some locking -dw #endif +#ifndef THIS_MODULE +#ifdef MODULE +#define THIS_MODULE (&__this_module) +#else +#define THIS_MODULE NULL +#endif +#endif + //#define PRERELEASE unsigned long doc_locations[] = { @@ -500,9 +508,7 @@ mtd->erasesize = 0x2000; mtd->oobblock = 512; mtd->oobsize = 16; -#ifdef MODULE - mtd->module = &__this_module; -#endif + mtd->module = THIS_MODULE; mtd->erase = doc_erase; mtd->point = NULL; mtd->unpoint = NULL; @@ -697,10 +703,16 @@ if (eccbuf) { WriteDOC( CSDN_CTRL_ECC_IO | CSDN_CTRL_CE , docptr, CSDNControl ); +#if 1 + /* eduardp@m-sys.com says this shouldn't be necessary, + * but it doesn't actually work without it, so I've + * left it in for now. dwmw2. + */ + WriteDOC( 0, docptr, 2k_CSDN_IO); WriteDOC( 0, docptr, 2k_CSDN_IO); WriteDOC( 0, docptr, 2k_CSDN_IO); - +#endif /* Read the ECC data through the DiskOnChip ECC logic */ for (di=0; di<6; di++) { eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di); @@ -868,16 +880,22 @@ * ****************************************************************************/ +#if LINUX_VERSION_CODE < 0x20300 +#ifdef MODULE +#define init_doc2000 init_module +#define cleanup_doc2000 cleanup_module +#endif +#define __exit +#endif - -int init_module(void) +static int __init init_doc2000(void) { int i; printk(KERN_NOTICE "M-Systems DiskOnChip driver. (C) 1999 Machine Vision Holdings, Inc.\n"); #ifdef PRERELEASE - printk(KERN_INFO "$Id: doc2000.c,v 1.7 1999/08/20 15:31:01 dwmw2 Exp $\n"); + printk(KERN_INFO "$Id: doc2000.c,v 1.8 1999/10/25 14:55:46 dwmw2 Exp $\n"); #endif for (i=0; doc_locations[i]; i++) { @@ -892,7 +910,7 @@ } -void cleanup_module(void) +static void __exit cleanup_doc2000(void) { int i; struct mtd_info *mtd; @@ -900,7 +918,7 @@ for (i=0; i < MAX_MTD_DEVICES; i++) { mtd = get_mtd_device(i); - if (mtd && mtd->module == &__this_module) { + if (mtd && mtd->module == THIS_MODULE) { struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv; del_mtd_device(mtd); @@ -911,9 +929,14 @@ } } } - - - +#if LINUX_VERSION_CODE < 0x20300 +#ifndef MODULE +__initfunc(init_doc2000); +#endif +#else /* V2.3.x */ +module_init(init_doc2000); +module_exit(cleanup_doc2000); +#endif diff -uNr mtd-19990820/kernel/ftl.c mtd-19991025/kernel/ftl.c --- mtd-19990820/kernel/ftl.c Tue Aug 17 17:36:21 1999 +++ mtd-19991025/kernel/ftl.c Mon Oct 25 15:55:46 1999 @@ -1,6 +1,6 @@ /*====================================================================== - $Id: ftl.c,v 1.3 1999/08/17 16:36:03 dwmw2 Exp $ + $Id: ftl.c,v 1.4 1999/10/25 14:55:46 dwmw2 Exp $ A Flash Translation Layer memory card driver @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -102,7 +103,7 @@ u_long BlocksPerUnit; erase_unit_header_t header; int open; - struct wait_queue *wq; + wait_queue_head_t wq; } partition_t; static partition_t myparts[MAX_MTD_DEVICES]; @@ -1352,13 +1353,21 @@ } } -int init_module(void) +#if LINUX_VERSION_CODE < 0x20300 +#ifdef MODULE +#define init_ftl init_module +#define cleanup_ftl cleanup_module +#endif +#define __exit +#endif + +static int __init init_ftl(void) { int i; struct mtd_info *mtd; memset(&myparts[0],0,sizeof(myparts)); - + init_waitqueue_head(&myparts->wq); if (register_blkdev(FTL_MAJOR,"ftl", &ftl_blk_fops)) { printk(KERN_NOTICE "ftl_cs: unable to grab major " @@ -1398,7 +1407,7 @@ } -void cleanup_module(void) +static void __exit cleanup_ftl(void) { int i; @@ -1410,3 +1419,7 @@ unregister_blkdev(FTL_MAJOR, "ftl"); } +#if LINUX_VERSION_CODE > 0x20300 +module_init(init_ftl); +module_exit(cleanup_ftl); +#endif diff -uNr mtd-19990820/kernel/mapped.c mtd-19991025/kernel/mapped.c --- mtd-19990820/kernel/mapped.c Tue Aug 17 17:36:21 1999 +++ mtd-19991025/kernel/mapped.c Mon Oct 25 15:55:46 1999 @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: mapped.c,v 1.4 1999/08/17 16:36:03 dwmw2 Exp $ +// $Id: mapped.c,v 1.5 1999/10/25 14:55:46 dwmw2 Exp $ /* ###################################################################### Flash MTD Routines @@ -24,8 +24,8 @@ #include struct JEDECTable mtd_JEDEC_table[] = - {{0x01AD,"AMD Am29F016",16/8*1024*1024,64*1024,MTD_CAP_NORFLASH}, - {0x01D5,"AMD Am29F080",8/8*1024*1024,64*1024,MTD_CAP_NORFLASH}, + {{0x01AD,"AMD Am29F016",2*1024*1024,64*1024,MTD_CAP_NORFLASH}, + {0x01D5,"AMD Am29F080",1*1024*1024,64*1024,MTD_CAP_NORFLASH}, {}}; // flash_setup - Setup the mapped_mtd_info structure for normal flash /*{{{*/ @@ -477,6 +477,7 @@ return 0; } +#if 1 /*}}}*/ // flash_write - Generic writing function /*{{{*/ // --------------------------------------------------------------------- @@ -496,8 +497,8 @@ while (len != 0) { // Compute the page offset and reposition - base = map->page(map,start/map->pagesize); - off = start % map->pagesize; + base = map->page(map,(u_long)start/map->pagesize); + off = (u_long)start % map->pagesize; // Loop over this page for (; off != map->pagesize && len != 0; start++, len--, off++,buf++) @@ -537,7 +538,8 @@ *retlen = len; return 0; } - /*}}}*/ +#endif + // ram_write - Generic writing function for ram /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -566,7 +568,7 @@ *retlen = origlen; return 0; } - /*}}}*/ + // rom_read - Read handler for any sort of device /*{{{*/ // --------------------------------------------------------------------- /* This is a generic read function that should work with any device in the @@ -596,7 +598,7 @@ *retlen = origlen; return 0; } - /*}}}*/ + // page_jump - Move the window and return the buffer /*{{{*/ // --------------------------------------------------------------------- /* Unlike the page function this returns a buffer and length adjusted for @@ -637,6 +639,7 @@ when things are being done to multiple chips it is possible to parallize the operations, particularly full memory erases of multi chip memories benifit */ + void flash_chip_scan(struct mapped_mtd_info *map,unsigned long start, unsigned long len) { @@ -664,3 +667,4 @@ } } /*}}}*/ + diff -uNr mtd-19990820/kernel/mixmem.c mtd-19991025/kernel/mixmem.c --- mtd-19990820/kernel/mixmem.c Tue Aug 17 17:36:21 1999 +++ mtd-19991025/kernel/mixmem.c Fri Sep 17 16:58:36 1999 @@ -14,7 +14,7 @@ #include #include #include - +#include #include #define MIXCOM_ID_OFFSET 0xc10 @@ -41,14 +41,6 @@ return base_addr; } -static void mixmem_openclose(struct mtd_info *mtd, int which) -{ - if (which) - MOD_INC_USE_COUNT; - else - MOD_DEC_USE_COUNT; -} - static int flash_probe(int base) { int prev,curr; @@ -111,11 +103,8 @@ return 0; } -#ifdef MODULE -#define mixmem_init init_module -#endif -void cleanup_module() +static void __exit cleanup_mixmem() { mtd_mapped_remove(SSD); kfree(SSD); @@ -123,7 +112,7 @@ release_region(base_io+MIXCOM_PAGE_OFFSET, 2); } -int mixmem_init(void) +static int __init init_mixmem(void) { if (mixmem_probe() != 0) return -EAGAIN; @@ -139,12 +128,11 @@ memset(SSD,0,sizeof(*SSD)); // Setup the MTD structure - SSD->mtd.openclose = mixmem_openclose; SSD->page = mixmem_page; SSD->pagesize = MIXMEM_PAGESIZE; SSD->maxsize = 0x7FF; SSD->mtd.lock = &MixLock; - strcpy(SSD->mtd.device,"mixcom piggyback"); + strcpy(SSD->mtd.name,"mixcom piggyback"); // Setup the MTD, this will sense the flash parameters and so on.. if (mtd_mapped_setup(SSD) != 0) @@ -156,3 +144,5 @@ return 0; } +module_init(init_mixmem); +module_exit(cleanup_mixmem); diff -uNr mtd-19990820/kernel/mtd.c mtd-19991025/kernel/mtd.c --- mtd-19990820/kernel/mtd.c Tue Aug 17 23:57:08 1999 +++ mtd-19991025/kernel/mtd.c Mon Oct 25 15:55:46 1999 @@ -1,6 +1,6 @@ /*====================================================================== - $Id: mtd.c,v 1.7 1999/08/17 22:57:08 dwmw2 Exp $ + $Id: mtd.c,v 1.8 1999/10/25 14:55:46 dwmw2 Exp $ A general driver for accessing Memory Technology Devices @@ -25,7 +25,7 @@ #include #include #include - +#include #ifdef CONFIG_PROC_FS #include #endif @@ -283,7 +283,7 @@ switch (cmd) { case MEMGETINFO: copy_to_user((struct mtd_info *)arg, mtd, - (u_long) &mtd->erase - (u_long)mtd); + sizeof(struct mtd_info_user)); break; case MEMERASE: { @@ -515,7 +515,16 @@ /*====================================================================*/ -int init_module(void) +#if LINUX_VERSION_CODE < 0x20300 +#ifdef MODULE +#define init_mtd init_module +#define cleanup_mtd cleanup_module +#endif +#define __exit +#endif + + +static int __init init_mtd(void) { int i; @@ -535,7 +544,7 @@ return 0; } -void cleanup_module(void) +static void __exit cleanup_mtd(void) { unregister_chrdev(MTD_CHAR_MAJOR, "mtd"); #ifdef CONFIG_PROC_FS @@ -547,4 +556,11 @@ - +#if LINUX_VERSION_CODE < 0x20300 +#ifndef MODULE +__initfunc(init_mtd); +#endif +#else +module_init(init_mtd); +module_exit(cleanup_mtd); +#endif diff -uNr mtd-19990820/kernel/mtdblock.c mtd-19991025/kernel/mtdblock.c --- mtd-19990820/kernel/mtdblock.c Tue Aug 17 17:36:21 1999 +++ mtd-19991025/kernel/mtdblock.c Mon Oct 25 15:55:46 1999 @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: mtdblock.c,v 1.2 1999/08/17 16:36:03 dwmw2 Exp $ +// $Id: mtdblock.c,v 1.3 1999/10/25 14:55:46 dwmw2 Exp $ /* ###################################################################### Memory Technology Devices Manager @@ -85,7 +85,7 @@ mtd = get_mtd_device(dev); if (!mtd) { - printk(KERN_WARNING "MTD device %d is absent on mtd_release!\n"); + printk(KERN_WARNING "MTD device is absent on mtd_release!\n"); MOD_DEC_USE_COUNT; return -ENODEV; @@ -218,13 +218,19 @@ +#if LINUX_VERSION_CODE < 0x20300 +#ifdef MODULE +#define init_mtdblock init_module +#define cleanup_mtdblock cleanup_module +#endif +#define __exit +#endif + + // init_module - Module entry point /*{{{*/ // --------------------------------------------------------------------- /* */ -#ifdef MODULE -#define mtd_init init_module -#endif -int __init mtd_init(void) +static int __init init_mtdblock(void) { if (register_blkdev(MAJOR_NR,DEVICE_NAME,&mtd_fops)) @@ -245,10 +251,13 @@ // cleanup_module - Module exit point /*{{{*/ // --------------------------------------------------------------------- /* */ -#ifdef MODULE -void cleanup_module(void) + +static void __exit cleanup_mtdblock(void) { unregister_blkdev(MAJOR_NR,DEVICE_NAME); } + +#if LINUX_VERSION_CODE > 0x20300 +module_init(init_mtdblock); +module_exit(cleanup_mtdblock); #endif - /*}}}*/ diff -uNr mtd-19990820/kernel/nftl.c mtd-19991025/kernel/nftl.c --- mtd-19990820/kernel/nftl.c Fri Aug 20 16:31:01 1999 +++ mtd-19991025/kernel/nftl.c Mon Oct 25 15:55:46 1999 @@ -2,7 +2,7 @@ /* Linux driver for NAND Flash Translation Layer */ /* (c) 1999 Machine Vision Holdings, Inc. */ /* Author: David Woodhouse */ -/* $Id: nftl.c,v 1.8 1999/08/20 15:31:01 dwmw2 Exp $ */ +/* $Id: nftl.c,v 1.9 1999/10/25 14:55:46 dwmw2 Exp $ */ #define PRERELEASE @@ -16,7 +16,7 @@ #include #include #include - +#include #include #include @@ -29,29 +29,67 @@ + + +/* Linux-specific block device functions */ + +/* I _HATE_ the Linux block device setup more than anything else I've ever + * encountered, except ... + */ + +static int nftl_sizes[256]={0,}; +static int nftl_blocksizes[256] = {0,}; + +/* .. for the Linux partition table handling. */ + +struct hd_struct part_table[256] = {{0,0},}; + + +void dummy_init (struct gendisk *crap) +{} + + +static struct gendisk nftl_gendisk = { + NFTL_MAJOR, /* Major number */ + "nftl", /* Major name */ + 4, /* Bits to shift to get real from partition */ + 15, /* Number of partitions per real */ + MAX_NFTLS, /* maximum number of real */ + dummy_init, /* init function */ + part_table, /* hd struct */ + nftl_sizes, /* block sizes */ + 0, /* number */ + NULL, /* internal use, not presently used */ + NULL /* next */ +}; + + struct NFTLrecord *NFTLs[MAX_NFTLS]; -int numnftls = 0; static void NFTL_setup(struct mtd_info *mtd, unsigned long ofs, struct NFTLMediaHeader *hdr) { int i; struct NFTLrecord *thisNFTL; - - for (i=0; i < numnftls; i++) - if (NFTLs[i] && NFTLs[i]->mtd == mtd && - NFTLs[i]->MediaHdr.FirstPhysicalEUN == hdr->FirstPhysicalEUN) { + unsigned long temp; + int firstfree = -1; + + for (i=0; i < MAX_NFTLS; i++) { + if (!NFTLs[i] && firstfree==-1) + firstfree = i; + else if (NFTLs[i] && NFTLs[i]->mtd == mtd && + NFTLs[i]->MediaHdr.FirstPhysicalEUN == hdr->FirstPhysicalEUN) { /* This is a Spare Media Header for an NFTL we've already found */ // printk("Spare Media Header for NFTL %d found at %lx\n",i, ofs); NFTLs[i]->SpareMediaUnit = ofs / mtd->erasesize; return; } - + } /* OK, it's a new one. Set up all the data structures. */ #ifdef PSYCHO_DEBUG - printk("Found new NFTL nftl%c at offset %lx\n",numnftls + 'a', ofs); + printk("Found new NFTL nftl%c at offset %lx\n",firstfree + 'a', ofs); #endif if (hdr->UnitSizeFactor != 0xff) { printk("Sorry, we don't support UnitSizeFactor of != 1 yet\n"); @@ -71,7 +109,36 @@ thisNFTL->SpareMediaUnit = 0xffff; thisNFTL->numvunits = le32_to_cpu(thisNFTL->MediaHdr.FormattedSize) / 8192; thisNFTL->nr_sects = thisNFTL->numvunits * (thisNFTL->EraseSize / 512); - + thisNFTL->usecount = 0; + + thisNFTL->cylinders = 1024; + thisNFTL->heads = 16; + + temp = thisNFTL->cylinders * thisNFTL->heads; + thisNFTL->sectors = thisNFTL->nr_sects / temp; + + if (thisNFTL->nr_sects % temp) { + + thisNFTL->sectors++; + temp = thisNFTL->cylinders * thisNFTL->sectors; + thisNFTL->heads = thisNFTL->nr_sects / temp; + + if (thisNFTL->nr_sects & temp) { + thisNFTL->heads++; + temp = thisNFTL->heads * thisNFTL->sectors; + + thisNFTL->cylinders = thisNFTL->nr_sects / temp; + } + } + if (thisNFTL->nr_sects != thisNFTL->heads * thisNFTL->cylinders * + thisNFTL->sectors) { + printk("NFTL capacity reduced for geometry reasons from %lx to %lx sectors\n", thisNFTL->nr_sects, + thisNFTL->nr_sects = thisNFTL->heads * thisNFTL->cylinders * thisNFTL->sectors); + } + + + + thisNFTL->EUNtable = kmalloc( 2 * thisNFTL->numvunits, GFP_KERNEL); @@ -156,12 +223,10 @@ } } - NFTLs[numnftls++] = thisNFTL; + NFTLs[firstfree] = thisNFTL; thisNFTL->LastFreeEUN = le16_to_cpu(thisNFTL->MediaHdr.FirstPhysicalEUN); - if (thisNFTL->mtd->module) - __MOD_INC_USE_COUNT(thisNFTL->mtd->module); -#define PSYCHO_DEBUG + //#define PSYCHO_DEBUG #ifdef PSYCHO_DEBUG for (i=0; i < 10/* thisNFTL->numvunits*/; i++) { u16 curEUN = thisNFTL->EUNtable[i]; @@ -181,27 +246,52 @@ printk("\n"); } #endif + + /* OK. Now we deal with the fact that we're in the real world. Sometimes + things don't actually happen the way they're supposed to. Find, fix, + and whinge about the most common deviations from spec that we have + been known to encounter. + */ + /* Except that I haven't implemented that bit yet :) */ + + /* Finally, set up the block device sizes */ + + part_table[firstfree * 16].nr_sects = thisNFTL->nr_sects; + resetup_one_dev(&nftl_gendisk, firstfree); +} + + +static void NFTL_unsetup(int i) +{ + struct NFTLrecord *thisNFTL = NFTLs[i]; + + NFTLs[i] = NULL; + + if (thisNFTL->VirtualUnitTable) + kfree(thisNFTL->VirtualUnitTable); + if (thisNFTL->ReplUnitTable) + kfree(thisNFTL->ReplUnitTable); + if (thisNFTL->EUNtable) + kfree(thisNFTL->EUNtable); + + kfree(thisNFTL); } -/* Search each DiskOnChip for NFTL partitions */ -static void NFTL_init(void) + +/* Search the MTD device for NFTL partitions */ + +static void NFTL_notify_func(struct mtd_info *mtd, int device) { int i; - struct mtd_info *mtd; unsigned long ofs; struct NFTLMediaHeader hdr; - - for (i=0; i < MAX_MTD_DEVICES; i++) { - mtd = get_mtd_device(i); - - if (!mtd) - continue; - + + if (mtd) { if (!mtd->read_oob) /* If this MTD doesn't have out-of-band data, then there's no point continuing */ - continue; + return; for (ofs = 0; ofs < mtd->size ; ofs += mtd->erasesize) { size_t retlen; @@ -215,9 +305,22 @@ NFTL_setup(mtd, ofs, &hdr); } } + return; + } + + mtd = get_mtd_device(device); + + /* We're removing a known device */ + + for (i=0; i< MAX_NFTLS; i++) { + if (NFTLs[i] && NFTLs[i]->mtd == mtd) + NFTL_unsetup(i); } } + + + /* Actual NFTL access routines */ @@ -832,29 +935,50 @@ -/* Linux-specific block device functions */ - -/* I _HATE_ the Linux block device setup more than anything else I've ever - * encountered, except ... - */ - -static int nftl_sizes[256]={0,}; -static int nftl_blocksizes[256] = {0,}; - -/* .. for the Linux partition table handling. */ +static int nftl_ioctl(struct inode * inode, struct file * file, + unsigned int cmd, unsigned long arg) +{ + struct NFTLrecord *thisNFTL; -struct hd_struct part_table[256] = {{0,0},}; + thisNFTL = NFTLs[MINOR(inode->i_rdev) / 16]; + if (!thisNFTL) return -EINVAL; -void dummy_init (struct gendisk *crap) -{} + switch (cmd) { + case HDIO_GETGEO: { + struct hd_geometry g; + + g.heads = thisNFTL->heads; + g.sectors = thisNFTL->sectors; + g.cylinders = thisNFTL->cylinders; + g.start = part_table[MINOR(inode->i_rdev)].start_sect; + return copy_to_user((void *)arg, &g, sizeof g) ? -EFAULT : 0; + } + case BLKGETSIZE: /* Return device size */ + if (!arg) return -EINVAL; + return put_user(part_table[MINOR(inode->i_rdev)].nr_sects, + (long *) arg); + + case BLKFLSBUF: + if(!capable(CAP_SYS_ADMIN)) return -EACCES; + fsync_dev(inode->i_rdev); + invalidate_buffers(inode->i_rdev); + return 0; -static int nftl_ioctl(struct inode * inode, struct file * file, - unsigned int cmd, unsigned long arg) -{ - printk("NFTL ioctl called\n"); - return -EINVAL; + case BLKRRPART: + if (!capable(CAP_SYS_ADMIN)) return -EACCES; + if (thisNFTL->usecount > 1) { + // printk("Use count %d\n", thisNFTL->usecount); + return -EBUSY; + } + resetup_one_dev(&nftl_gendisk, MINOR(inode->i_dev) / 16); + return 0; + + // RO_IOCTLS(inode->i_rdev, arg); /* ref. linux/blk.h */ + default: + return -EINVAL; + } } @@ -871,7 +995,7 @@ nsect = CURRENT->nr_sectors; buffer = CURRENT->buffer; - if (dev >= numnftls * 16) { + if (dev >= MAX_NFTLS * 16) { printk("fl: bad minor number: device=%s\n", kdevname(CURRENT->rq_dev)); end_request(0); /* fail */ @@ -924,43 +1048,44 @@ static int nftl_open(struct inode *ip, struct file *fp) { -#if 0 - if (fp->f_mode & FMODE_WRITE) - return -EROFS; -#endif + struct NFTLrecord *thisNFTL; + + thisNFTL = NFTLs[MINOR(ip->i_rdev) / 16]; + + if (!thisNFTL) + return -ENODEV; + + thisNFTL->usecount++; MOD_INC_USE_COUNT; + if (thisNFTL->mtd->module) + __MOD_INC_USE_COUNT(thisNFTL->mtd->module); + + return 0; } static int nftl_release(struct inode *inode, struct file *fp) { struct super_block *sb = get_super(inode->i_rdev); + struct NFTLrecord *thisNFTL; + + thisNFTL = NFTLs[MINOR(inode->i_rdev) / 16]; fsync_dev(inode->i_rdev); - if (sb) invalidate_inodes(sb); - invalidate_buffers(inode->i_rdev); - // mtd->sync() - + + if (thisNFTL->mtd->sync) + thisNFTL->mtd->sync(thisNFTL->mtd); + thisNFTL->usecount--; MOD_DEC_USE_COUNT; + + if (thisNFTL->mtd->module) + __MOD_DEC_USE_COUNT(thisNFTL->mtd->module); + return 0; } -static struct gendisk nftl_gendisk = { - NFTL_MAJOR, /* Major number */ - "nftl", /* Major name */ - 4, /* Bits to shift to get real from partition */ - 15, /* Number of partitions per real */ - MAX_NFTLS, /* maximum number of real */ - dummy_init, /* init function */ - part_table, /* hd struct */ - nftl_sizes, /* block sizes */ - 0, /* number */ - NULL, /* internal use, not presently used */ - NULL /* next */ -}; - static struct file_operations nftl_fops = { NULL, /* lseek - default */ block_read, /* read - block dev read */ @@ -984,64 +1109,65 @@ * ****************************************************************************/ +#if LINUX_VERSION_CODE < 0x20300 +#ifdef MODULE +#define init_nftl init_module +#define cleanup_nftl cleanup_module +#endif +#define __exit +#endif + +static struct mtd_notifier nftl_notifier = {NFTL_notify_func, NULL}; -int init_module(void) +static int __init init_nftl(void) { int i; - + struct mtd_info *mtd; printk(KERN_NOTICE "M-Systems NAND Flash Translation Layer driver. (C) 1999 MVHI\n"); #ifdef PRERELEASE - printk(KERN_INFO"$Id: nftl.c,v 1.8 1999/08/20 15:31:01 dwmw2 Exp $\n"); + printk(KERN_INFO"$Id: nftl.c,v 1.9 1999/10/25 14:55:46 dwmw2 Exp $\n"); #endif + register_mtd_notifier(&nftl_notifier); - NFTL_init(); - - if (numnftls) { - - for (i=0; i < numnftls ; i++) { - part_table[i * 16].nr_sects = NFTLs[i]->nr_sects; - } - - if (register_blkdev(NFTL_MAJOR, "nftl", &nftl_fops)){ - printk("unable to register NFTL block device\n"); - } else { - blk_dev[NFTL_MAJOR].request_fn = DEVICE_REQUEST; - for (i=0; i < 256 ; i++) - nftl_blocksizes[i] = 1024; - blksize_size[NFTL_MAJOR] = nftl_blocksizes; - nftl_gendisk.next = gendisk_head; - gendisk_head = &nftl_gendisk; - } - - for (i=0; i < numnftls ; i++) { - resetup_one_dev(&nftl_gendisk, i); - } + for (i=0; i < MAX_MTD_DEVICES; i++) { + mtd = get_mtd_device(i); - return 0; - } - printk("No NFTL partitions found\n"); - return -ENODEV; -} - + if (mtd) + NFTL_notify_func(mtd, i); + } + if (register_blkdev(NFTL_MAJOR, "nftl", &nftl_fops)){ + printk("unable to register NFTL block device\n"); + } else { + blk_dev[NFTL_MAJOR].request_fn = DEVICE_REQUEST; + for (i=0; i < 256 ; i++) + nftl_blocksizes[i] = 1024; + blksize_size[NFTL_MAJOR] = nftl_blocksizes; + nftl_gendisk.next = gendisk_head; + gendisk_head = &nftl_gendisk; + } + + + return 0; +} -void cleanup_module(void) +static void __exit cleanup_nftl(void) { struct gendisk *gd, **gdp; + int i; + + unregister_mtd_notifier(&nftl_notifier); + + for (i=0; i< MAX_NFTLS; i++) + if (NFTLs[i]) + NFTL_unsetup(i); - for (numnftls-- ; numnftls >= 0; numnftls--) { - kfree(NFTLs[numnftls]->VirtualUnitTable); - kfree(NFTLs[numnftls]->ReplUnitTable); - kfree(NFTLs[numnftls]->EUNtable); - if (NFTLs[numnftls]->mtd->module) - __MOD_DEC_USE_COUNT(NFTLs[numnftls]->mtd->module); - kfree(NFTLs[numnftls]); - } unregister_blkdev(NFTL_MAJOR, "nftl"); + for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next)) if (*gdp == &nftl_gendisk) { gd = *gdp; *gdp = gd->next; @@ -1050,9 +1176,10 @@ } - - - +#if LINUX_VERSION_CODE > 0x20300 +module_init(init_nftl); +module_exit(cleanup_nftl); +#endif diff -uNr mtd-19990820/kernel/vmax301.c mtd-19991025/kernel/vmax301.c --- mtd-19990820/kernel/vmax301.c Tue Aug 17 17:36:21 1999 +++ mtd-19991025/kernel/vmax301.c Mon Oct 25 15:55:46 1999 @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: vmax301.c,v 1.3 1999/08/17 16:36:03 dwmw2 Exp $ +// $Id: vmax301.c,v 1.4 1999/10/25 14:55:46 dwmw2 Exp $ /* ###################################################################### Tempustech VMAX SBC301 MTD Driver. @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -75,10 +76,19 @@ } /*}}}*/ +#if LINUX_VERSION_CODE < 0x20300 +#ifdef MODULE +#define init_vmax301 init_module +#define cleanup_vmax301 cleanup_module +#endif +#define __exit +#endif + + // cleanup_module - Clean up the allocations made /*{{{*/ // --------------------------------------------------------------------- /* */ -void cleanup_module() +static void __exit cleanup_vmax301() { int I; for (I = 0; I != 2; I++) @@ -92,7 +102,7 @@ // init_module - Module startup function /*{{{*/ // --------------------------------------------------------------------- /* Create the two SSD devices */ -int init_module() +static int __init init_vmax301() { // Print out our little header.. printk("Tempustech VMAX 301 MEM:0x%x-0x%x\n",WINDOW_START, @@ -103,7 +113,7 @@ SSD[1] = CreateSSD(); if (SSD[0] == 0 || SSD[1] == 0) { - cleanup_module(); + cleanup_vmax301(); return -EAGAIN; } @@ -122,10 +132,14 @@ if (mtd_mapped_setup(SSD[0]) != 0 || mtd_mapped_setup(SSD[1]) != 0) { printk("Failed to register new device\n"); - cleanup_module(); + cleanup_vmax301(); return -EAGAIN; } return 0; } /*}}}*/ +#if LINUX_VERSION_CODE > 0x20300 +module_init(init_vmax301); +module_exit(cleanup_vmax301); +#endif diff -uNr mtd-19990820/util/MAKEDEV mtd-19991025/util/MAKEDEV --- mtd-19990820/util/MAKEDEV Tue Aug 17 18:54:58 1999 +++ mtd-19991025/util/MAKEDEV Mon Aug 23 15:51:36 1999 @@ -1,5 +1,5 @@ #!/bin/bash -# $Id: MAKEDEV,v 1.1 1999/08/17 17:54:58 dwmw2 Exp $ +# $Id: MAKEDEV,v 1.2 1999/08/23 14:51:36 dwmw2 Exp $ function mkftl () { mknod /dev/ftl$1 b 44 $2 @@ -8,7 +8,7 @@ done } function mknftl () { - mknod /dev/nftl$1 b 44 $2 + mknod /dev/nftl$1 b 93 $2 for a in `seq 1 15`; do mknod /dev/nftl$1$a b 93 `expr $2 + $a` done diff -uNr mtd-19990820/util/nanddump.c mtd-19991025/util/nanddump.c --- mtd-19990820/util/nanddump.c Wed Aug 18 15:33:48 1999 +++ mtd-19991025/util/nanddump.c Sat Oct 16 17:13:35 1999 @@ -56,7 +56,7 @@ for (ofs = 0; ofs < meminfo.size ; ofs+=512) { -#if 0 +#if 1 if ( pread (fd, readbuf, 512, ofs) != 512) { perror("pread"); close(fd);