Revert last change. Bug noticed by Linus.
[linux-2.6/linux-mips.git] / drivers / mtd / slram.c
blob48067c814a28252221a92a4367b5341b7686e896
1 /*======================================================================
3 $Id: slram.c,v 1.10 2000/07/03 10:01:38 dwmw2 Exp $
5 ======================================================================*/
8 #include <linux/module.h>
9 #include <asm/uaccess.h>
10 #include <linux/types.h>
11 #include <linux/kernel.h>
12 #include <linux/sched.h>
13 #include <linux/ptrace.h>
14 #include <linux/malloc.h>
15 #include <linux/string.h>
16 #include <linux/timer.h>
17 #include <linux/major.h>
18 #include <linux/fs.h>
19 #include <linux/ioctl.h>
20 #include <linux/init.h>
21 #include <asm/io.h>
22 #include <asm/system.h>
23 #include <asm/segment.h>
24 #include <stdarg.h>
26 #include <linux/mtd/mtd.h>
28 struct mypriv {
29 u_char *start;
30 u_char *end;
33 int physmem_erase (struct mtd_info *mtd, struct erase_info *instr);
34 int physmem_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf);
35 void physmem_unpoint (struct mtd_info *mtd, u_char *addr);
36 int physmem_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
37 int physmem_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
40 int physmem_erase (struct mtd_info *mtd, struct erase_info *instr)
42 struct mypriv *priv = mtd->priv;
44 if (instr->addr + instr->len > mtd->size)
45 return -EINVAL;
47 memset(priv->start + instr->addr, 0xff, instr->len);
49 /* This'll catch a few races. Free the thing before returning :)
50 * I don't feel at all ashamed. This kind of thing is possible anyway
51 * with flash, but unlikely.
54 instr->state = MTD_ERASE_DONE;
56 if (instr->callback)
57 (*(instr->callback))(instr);
58 else
59 kfree(instr);
61 return 0;
65 int physmem_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf)
67 struct mypriv *priv = (struct mypriv *)mtd->priv;
69 *mtdbuf = priv->start + from;
70 *retlen = len;
71 return 0;
74 void physmem_unpoint (struct mtd_info *mtd, u_char *addr)
78 int physmem_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
80 struct mypriv *priv = (struct mypriv *)mtd->priv;
82 memcpy (buf, priv->start + from, len);
84 *retlen=len;
85 return 0;
88 int physmem_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
90 struct mypriv *priv = (struct mypriv *)mtd->priv;
92 memcpy (priv->start + to, buf, len);
94 *retlen=len;
95 return 0;
101 /*====================================================================*/
103 /* Place your defaults here */
105 static u_long start = 100663296;
106 static u_long length = 33554432;
107 static u_long end = 0;
109 #if LINUX_VERSION_CODE < 0x20300
110 #ifdef MODULE
111 #define init_slram init_module
112 #define cleanup_slram cleanup_module
113 #endif
114 #define __exit
115 #endif
117 #ifdef MODULE
118 MODULE_PARM(start,"l");
119 MODULE_PARM(length,"l");
120 MODULE_PARM(end,"l");
121 #endif
123 struct mtd_info *mymtd;
125 void __init mtd_slram_setup(char *str, int *ints)
127 if (ints[0] > 0)
128 start=ints[1];
129 if (ints[0] > 1)
130 length=ints[2];
133 int init_slram(void)
135 if (!start)
137 printk(KERN_NOTICE "physmem: No start address for memory device.\n");
138 return -EINVAL;
141 if (!length && !end)
143 printk(KERN_NOTICE "physmem: No length or endpointer given.\n");
144 return -EINVAL;
147 if (!end)
148 end = start + length;
150 if (!length)
151 length = end - start;
153 if (start + length != end)
155 printk(KERN_NOTICE "physmem: start(%lx) + length(%lx) != end(%lx) !\n",
156 start, length, end);
157 return -EINVAL;
160 mymtd = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
162 memset(mymtd, 0, sizeof(*mymtd));
164 if (mymtd)
166 memset((char *)mymtd, 0, sizeof(struct mtd_info));
167 mymtd->priv = (void *) kmalloc (sizeof(struct mypriv), GFP_KERNEL);
168 if (!mymtd->priv)
170 kfree(mymtd);
171 mymtd = NULL;
173 memset(mymtd->priv, 0, sizeof(struct mypriv));
176 if (!mymtd)
178 printk(KERN_NOTICE "physmem: Cannot allocate new MTD device.\n");
179 return -ENOMEM;
183 ((struct mypriv *)mymtd->priv)->start = ioremap(start, length);
184 ((struct mypriv *)mymtd->priv)->end = ((struct mypriv *)mymtd->priv)->start + length;
187 mymtd->name = "Raw memory";
189 mymtd->size = length;
190 mymtd->flags = MTD_CLEAR_BITS | MTD_SET_BITS | MTD_WRITEB_WRITEABLE | MTD_VOLATILE;
191 mymtd->erase = physmem_erase;
192 mymtd->point = physmem_point;
193 mymtd->unpoint = physmem_unpoint;
194 mymtd->read = physmem_read;
195 mymtd->write = physmem_write;
196 mymtd->module = THIS_MODULE;
197 mymtd->type = MTD_RAM;
198 mymtd->erasesize = 0x10000;
200 if (add_mtd_device(mymtd))
202 printk("Failed to register new device\n");
203 kfree(mymtd->priv);
204 kfree(mymtd);
205 return -EAGAIN;
207 printk("Registered physmem device from %dKb to %dKb\n",
208 (int)(start / 1024), (int)(end / 1024));
209 printk("Mapped from 0x%p to 0x%p\n",((struct mypriv *)mymtd->priv)->start,
210 ((struct mypriv *)mymtd->priv)->end);
212 return 0;
215 static void __exit cleanup_slram(void)
217 iounmap(((struct mypriv *)mymtd->priv)->start);
218 kfree (mymtd->priv);
219 del_mtd_device(mymtd);
220 kfree(mymtd);
223 #if LINUX_VERSION_CODE > 0x20300
224 module_init(init_slram);
225 module_exit(cleanup_slram);
226 #endif