~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/mtd/slram.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*======================================================================
  2 
  3   $Id: slram.c,v 1.10 2000/07/03 10:01:38 dwmw2 Exp $
  4 
  5 ======================================================================*/
  6 
  7 
  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>
 25 
 26 #include <linux/mtd/mtd.h>
 27 
 28 struct mypriv {
 29         u_char *start;
 30         u_char *end;
 31 };
 32 
 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);
 38         
 39 
 40 int physmem_erase (struct mtd_info *mtd, struct erase_info *instr)
 41 {
 42         struct mypriv *priv = mtd->priv;
 43 
 44         if (instr->addr + instr->len > mtd->size)
 45                 return -EINVAL;
 46         
 47         memset(priv->start + instr->addr, 0xff, instr->len);
 48 
 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.
 52          */
 53 
 54         instr->state = MTD_ERASE_DONE;
 55 
 56         if (instr->callback)
 57                 (*(instr->callback))(instr);
 58         else
 59                 kfree(instr);
 60 
 61         return 0;
 62 }
 63 
 64 
 65 int physmem_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf)
 66 {
 67         struct mypriv *priv = (struct mypriv *)mtd->priv;
 68 
 69         *mtdbuf = priv->start + from;
 70         *retlen = len;
 71         return 0;
 72 }
 73 
 74 void physmem_unpoint (struct mtd_info *mtd, u_char *addr)
 75 {
 76 }
 77 
 78 int physmem_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
 79 {
 80         struct mypriv *priv = (struct mypriv *)mtd->priv;
 81         
 82         memcpy (buf, priv->start + from, len);
 83 
 84         *retlen=len;
 85         return 0;
 86 }
 87 
 88 int physmem_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
 89 {
 90         struct mypriv *priv = (struct mypriv *)mtd->priv;
 91 
 92         memcpy (priv->start + to, buf, len);
 93 
 94         *retlen=len;
 95         return 0;
 96 }
 97 
 98 
 99 
100 
101 /*====================================================================*/
102 
103 /* Place your defaults here */
104 
105 static u_long start = 100663296;
106 static u_long length = 33554432;
107 static u_long end = 0;
108 
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
116 
117 #ifdef MODULE
118 MODULE_PARM(start,"l");
119 MODULE_PARM(length,"l");
120 MODULE_PARM(end,"l");
121 #endif
122 
123 struct mtd_info *mymtd;
124 
125 void __init mtd_slram_setup(char *str, int *ints)
126 {
127         if (ints[0] > 0)
128                 start=ints[1];
129         if (ints[0] > 1)
130                 length=ints[2];
131 }
132 
133 int init_slram(void)
134 {
135         if (!start)
136         {
137                 printk(KERN_NOTICE "physmem: No start address for memory device.\n");
138                 return -EINVAL;
139         }
140         
141         if (!length && !end)
142         {
143                 printk(KERN_NOTICE "physmem: No length or endpointer given.\n");
144                 return -EINVAL;
145         }
146         
147         if (!end)
148                 end = start + length;
149         
150         if (!length)
151           length = end - start;
152 
153         if (start + length != end)
154           {
155             printk(KERN_NOTICE "physmem: start(%lx) + length(%lx) != end(%lx) !\n",
156                    start, length, end);
157             return -EINVAL;
158           }
159 
160         mymtd = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
161         
162         memset(mymtd, 0, sizeof(*mymtd));
163         
164         if (mymtd)
165         {
166                 memset((char *)mymtd, 0, sizeof(struct mtd_info));
167                 mymtd->priv = (void *) kmalloc (sizeof(struct mypriv), GFP_KERNEL);
168                 if (!mymtd->priv)
169                 {
170                         kfree(mymtd);
171                         mymtd = NULL;
172                 }
173                 memset(mymtd->priv, 0, sizeof(struct mypriv));
174         }
175 
176         if (!mymtd)
177         {
178                 printk(KERN_NOTICE "physmem: Cannot allocate new MTD device.\n");
179                 return -ENOMEM;
180         }
181         
182         
183         ((struct mypriv *)mymtd->priv)->start = ioremap(start, length);
184         ((struct mypriv *)mymtd->priv)->end = ((struct mypriv *)mymtd->priv)->start + length;
185 
186 
187         mymtd->name = "Raw memory";
188 
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;
199 
200         if (add_mtd_device(mymtd))
201         {
202                 printk("Failed to register new device\n");
203                 kfree(mymtd->priv);
204                 kfree(mymtd);
205                 return -EAGAIN;
206         }
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);
211 
212         return 0;
213 }
214 
215 static void __exit cleanup_slram(void)
216 {
217         iounmap(((struct mypriv *)mymtd->priv)->start);
218         kfree (mymtd->priv);
219         del_mtd_device(mymtd);
220         kfree(mymtd);
221 }
222 
223 #if LINUX_VERSION_CODE > 0x20300
224 module_init(init_slram);
225 module_exit(cleanup_slram);
226 #endif
227 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.