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>
19 #include <linux/ioctl.h>
20 #include <linux/init.h>
22 #include <asm/system.h>
23 #include <asm/segment.h>
26 #include <linux/mtd/mtd.h>
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
)
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
;
57 (*(instr
->callback
))(instr
);
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
;
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
);
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
);
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
111 #define init_slram init_module
112 #define cleanup_slram cleanup_module
118 MODULE_PARM(start
,"l");
119 MODULE_PARM(length
,"l");
120 MODULE_PARM(end
,"l");
123 struct mtd_info
*mymtd
;
125 void __init
mtd_slram_setup(char *str
, int *ints
)
137 printk(KERN_NOTICE
"physmem: No start address for memory device.\n");
143 printk(KERN_NOTICE
"physmem: No length or endpointer given.\n");
148 end
= start
+ length
;
151 length
= end
- start
;
153 if (start
+ length
!= end
)
155 printk(KERN_NOTICE
"physmem: start(%lx) + length(%lx) != end(%lx) !\n",
160 mymtd
= kmalloc(sizeof(struct mtd_info
), GFP_KERNEL
);
162 memset(mymtd
, 0, sizeof(*mymtd
));
166 memset((char *)mymtd
, 0, sizeof(struct mtd_info
));
167 mymtd
->priv
= (void *) kmalloc (sizeof(struct mypriv
), GFP_KERNEL
);
173 memset(mymtd
->priv
, 0, sizeof(struct mypriv
));
178 printk(KERN_NOTICE
"physmem: Cannot allocate new MTD device.\n");
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");
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
);
215 static void __exit
cleanup_slram(void)
217 iounmap(((struct mypriv
*)mymtd
->priv
)->start
);
219 del_mtd_device(mymtd
);
223 #if LINUX_VERSION_CODE > 0x20300
224 module_init(init_slram
);
225 module_exit(cleanup_slram
);