Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] Architecture: [ i386 ]
  1 /*
  2  * mtdram - a test mtd device
  3  * $Id: mtdram.c,v 1.37 2005/04/21 03:42:11 joern Exp $
  4  * Author: Alexander Larsson <alex@cendio.se>
  5  *
  6  * Copyright (c) 1999 Alexander Larsson <alex@cendio.se>
  7  * Copyright (c) 2005 Joern Engel <joern@wh.fh-wedel.de>
  8  *
  9  * This code is GPL
 10  *
 11  */
 12 
 13 #include <linux/module.h>
 14 #include <linux/slab.h>
 15 #include <linux/ioport.h>
 16 #include <linux/vmalloc.h>
 17 #include <linux/init.h>
 18 #include <linux/mtd/compatmac.h>
 19 #include <linux/mtd/mtd.h>
 20 
 21 static unsigned long total_size = CONFIG_MTDRAM_TOTAL_SIZE;
 22 static unsigned long erase_size = CONFIG_MTDRAM_ERASE_SIZE;
 23 #define MTDRAM_TOTAL_SIZE (total_size * 1024)
 24 #define MTDRAM_ERASE_SIZE (erase_size * 1024)
 25 
 26 #ifdef MODULE
 27 module_param(total_size, ulong, 0);
 28 MODULE_PARM_DESC(total_size, "Total device size in KiB");
 29 module_param(erase_size, ulong, 0);
 30 MODULE_PARM_DESC(erase_size, "Device erase block size in KiB");
 31 #endif
 32 
 33 // We could store these in the mtd structure, but we only support 1 device..
 34 static struct mtd_info *mtd_info;
 35 
 36 static int ram_erase(struct mtd_info *mtd, struct erase_info *instr)
 37 {
 38         if (instr->addr + instr->len > mtd->size)
 39                 return -EINVAL;
 40 
 41         memset((char *)mtd->priv + instr->addr, 0xff, instr->len);
 42 
 43         instr->state = MTD_ERASE_DONE;
 44         mtd_erase_callback(instr);
 45 
 46         return 0;
 47 }
 48 
 49 static int ram_point(struct mtd_info *mtd, loff_t from, size_t len,
 50                 size_t *retlen, u_char **mtdbuf)
 51 {
 52         if (from + len > mtd->size)
 53                 return -EINVAL;
 54 
 55         *mtdbuf = mtd->priv + from;
 56         *retlen = len;
 57         return 0;
 58 }
 59 
 60 static void ram_unpoint(struct mtd_info *mtd, u_char * addr, loff_t from,
 61                 size_t len)
 62 {
 63 }
 64 
 65 static int ram_read(struct mtd_info *mtd, loff_t from, size_t len,
 66                 size_t *retlen, u_char *buf)
 67 {
 68         if (from + len > mtd->size)
 69                 return -EINVAL;
 70 
 71         memcpy(buf, mtd->priv + from, len);
 72 
 73         *retlen = len;
 74         return 0;
 75 }
 76 
 77 static int ram_write(struct mtd_info *mtd, loff_t to, size_t len,
 78                 size_t *retlen, const u_char *buf)
 79 {
 80         if (to + len > mtd->size)
 81                 return -EINVAL;
 82 
 83         memcpy((char *)mtd->priv + to, buf, len);
 84 
 85         *retlen = len;
 86         return 0;
 87 }
 88 
 89 static void __exit cleanup_mtdram(void)
 90 {
 91         if (mtd_info) {
 92                 del_mtd_device(mtd_info);
 93                 vfree(mtd_info->priv);
 94                 kfree(mtd_info);
 95         }
 96 }
 97 
 98 int mtdram_init_device(struct mtd_info *mtd, void *mapped_address,
 99                 unsigned long size, char *name)
100 {
101         memset(mtd, 0, sizeof(*mtd));
102 
103         /* Setup the MTD structure */
104         mtd->name = name;
105         mtd->type = MTD_RAM;
106         mtd->flags = MTD_CAP_RAM;
107         mtd->size = size;
108         mtd->writesize = 1;
109         mtd->erasesize = MTDRAM_ERASE_SIZE;
110         mtd->priv = mapped_address;
111 
112         mtd->owner = THIS_MODULE;
113         mtd->erase = ram_erase;
114         mtd->point = ram_point;
115         mtd->unpoint = ram_unpoint;
116         mtd->read = ram_read;
117         mtd->write = ram_write;
118 
119         if (add_mtd_device(mtd)) {
120                 return -EIO;
121         }
122 
123         return 0;
124 }
125 
126 static int __init init_mtdram(void)
127 {
128         void *addr;
129         int err;
130 
131         if (!total_size)
132                 return -EINVAL;
133 
134         /* Allocate some memory */
135         mtd_info = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
136         if (!mtd_info)
137                 return -ENOMEM;
138 
139         addr = vmalloc(MTDRAM_TOTAL_SIZE);
140         if (!addr) {
141                 kfree(mtd_info);
142                 mtd_info = NULL;
143                 return -ENOMEM;
144         }
145         err = mtdram_init_device(mtd_info, addr, MTDRAM_TOTAL_SIZE, "mtdram test device");
146         if (err) {
147                 vfree(addr);
148                 kfree(mtd_info);
149                 mtd_info = NULL;
150                 return err;
151         }
152         memset(mtd_info->priv, 0xff, MTDRAM_TOTAL_SIZE);
153         return err;
154 }
155 
156 module_init(init_mtdram);
157 module_exit(cleanup_mtdram);
158 
159 MODULE_LICENSE("GPL");
160 MODULE_AUTHOR("Alexander Larsson <alexl@redhat.com>");
161 MODULE_DESCRIPTION("Simulated MTD driver for testing");
162 
  This page was automatically generated by the LXR engine.