mtdram.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:4k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * mtdram - a test mtd device
  3.  * $Id: mtdram.c,v 1.26 2001/12/01 10:24:18 dwmw2 Exp $
  4.  * Author: Alexander Larsson <alex@cendio.se>
  5.  *
  6.  * Copyright (c) 1999 Alexander Larsson <alex@cendio.se>
  7.  *
  8.  * This code is GPL
  9.  *
  10.  */
  11. #include <linux/config.h>
  12. #include <linux/module.h>
  13. #include <linux/slab.h>
  14. #include <linux/ioport.h>
  15. #include <linux/mtd/compatmac.h>
  16. #include <linux/mtd/mtd.h>
  17. #ifndef CONFIG_MTDRAM_ABS_POS
  18.   #define CONFIG_MTDRAM_ABS_POS 0
  19. #endif
  20. #if CONFIG_MTDRAM_ABS_POS > 0
  21.   #include <asm/io.h>
  22. #endif
  23. #ifdef MODULE
  24. static unsigned long total_size = CONFIG_MTDRAM_TOTAL_SIZE;
  25. static unsigned long erase_size = CONFIG_MTDRAM_ERASE_SIZE;
  26. MODULE_PARM(total_size,"l");
  27. MODULE_PARM(erase_size,"l");
  28. #define MTDRAM_TOTAL_SIZE (total_size * 1024)
  29. #define MTDRAM_ERASE_SIZE (erase_size * 1024)
  30. #else
  31. #define MTDRAM_TOTAL_SIZE (CONFIG_MTDRAM_TOTAL_SIZE * 1024)
  32. #define MTDRAM_ERASE_SIZE (CONFIG_MTDRAM_ERASE_SIZE * 1024)
  33. #endif
  34. // We could store these in the mtd structure, but we only support 1 device..
  35. static struct mtd_info *mtd_info;
  36. static int
  37. ram_erase(struct mtd_info *mtd, struct erase_info *instr)
  38. {
  39.   DEBUG(MTD_DEBUG_LEVEL2, "ram_erase(pos:%ld, len:%ld)n", (long)instr->addr, (long)instr->len);
  40.   if (instr->addr + instr->len > mtd->size) {
  41.     DEBUG(MTD_DEBUG_LEVEL1, "ram_erase() out of bounds (%ld > %ld)n", (long)(instr->addr + instr->len), (long)mtd->size);
  42.     return -EINVAL;
  43.   }
  44.   memset((char *)mtd->priv + instr->addr, 0xff, instr->len);
  45.   instr->state = MTD_ERASE_DONE;
  46.   if (instr->callback)
  47.     (*(instr->callback))(instr);
  48.   return 0;
  49. }
  50. static int ram_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf)
  51. {
  52.   if (from + len > mtd->size)
  53.     return -EINVAL;
  54.   *mtdbuf = mtd->priv + from;
  55.   *retlen = len;
  56.   return 0;
  57. }
  58. static void ram_unpoint (struct mtd_info *mtd, u_char *addr)
  59. {
  60.   DEBUG(MTD_DEBUG_LEVEL2, "ram_unpointn");
  61. }
  62. static int ram_read(struct mtd_info *mtd, loff_t from, size_t len,
  63.      size_t *retlen, u_char *buf)
  64. {
  65.   DEBUG(MTD_DEBUG_LEVEL2, "ram_read(pos:%ld, len:%ld)n", (long)from, (long)len);
  66.   if (from + len > mtd->size) {
  67.     DEBUG(MTD_DEBUG_LEVEL1, "ram_read() out of bounds (%ld > %ld)n", (long)(from + len), (long)mtd->size);
  68.     return -EINVAL;
  69.   }
  70.   memcpy(buf, mtd->priv + from, len);
  71.   *retlen=len;
  72.   return 0;
  73. }
  74. static int ram_write(struct mtd_info *mtd, loff_t to, size_t len,
  75.       size_t *retlen, const u_char *buf)
  76. {
  77.   DEBUG(MTD_DEBUG_LEVEL2, "ram_write(pos:%ld, len:%ld)n", (long)to, (long)len);
  78.   if (to + len > mtd->size) {
  79.     DEBUG(MTD_DEBUG_LEVEL1, "ram_write() out of bounds (%ld > %ld)n", (long)(to + len), (long)mtd->size);
  80.     return -EINVAL;
  81.   }
  82.   memcpy ((char *)mtd->priv + to, buf, len);
  83.   *retlen=len;
  84.   return 0;
  85. }
  86. static void __exit cleanup_mtdram(void)
  87. {
  88.   if (mtd_info) {
  89.     del_mtd_device(mtd_info);
  90.     if (mtd_info->priv)
  91. #if CONFIG_MTDRAM_ABS_POS > 0
  92.       iounmap(mtd_info->priv);
  93. #else
  94.       vfree(mtd_info->priv);
  95. #endif
  96.     kfree(mtd_info);
  97.   }
  98. }
  99. int __init init_mtdram(void)
  100. {
  101.    // Allocate some memory
  102.    mtd_info = (struct mtd_info *)kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
  103.    if (!mtd_info)
  104.       return -ENOMEM;
  105.    
  106.    memset(mtd_info, 0, sizeof(*mtd_info));
  107.    // Setup the MTD structure
  108.    mtd_info->name = "mtdram test device";
  109.    mtd_info->type = MTD_RAM;
  110.    mtd_info->flags = MTD_CAP_RAM;
  111.    mtd_info->size = MTDRAM_TOTAL_SIZE;
  112.    mtd_info->erasesize = MTDRAM_ERASE_SIZE;
  113. #if CONFIG_MTDRAM_ABS_POS > 0
  114.    mtd_info->priv = ioremap(CONFIG_MTDRAM_ABS_POS, MTDRAM_TOTAL_SIZE);
  115. #else
  116.    mtd_info->priv = vmalloc(MTDRAM_TOTAL_SIZE);
  117. #endif
  118.    if (!mtd_info->priv) {
  119.      DEBUG(MTD_DEBUG_LEVEL1, "Failed to vmalloc(/ioremap) memory region of size %ld (ABS_POS:%ld)n", (long)MTDRAM_TOTAL_SIZE, (long)CONFIG_MTDRAM_ABS_POS);
  120.      kfree(mtd_info);
  121.      mtd_info = NULL;
  122.      return -ENOMEM;
  123.    }
  124.    memset(mtd_info->priv, 0xff, MTDRAM_TOTAL_SIZE);
  125.    mtd_info->module = THIS_MODULE;
  126.    mtd_info->erase = ram_erase;
  127.    mtd_info->point = ram_point;
  128.    mtd_info->unpoint = ram_unpoint;
  129.    mtd_info->read = ram_read;
  130.    mtd_info->write = ram_write;
  131.    if (add_mtd_device(mtd_info)) {
  132. #if CONFIG_MTDRAM_ABS_POS > 0
  133.      iounmap(mtd_info->priv);
  134. #else
  135.      vfree(mtd_info->priv);
  136. #endif
  137.      kfree(mtd_info);
  138.      mtd_info = NULL;
  139.      return -EIO;
  140.    }
  141.    
  142.    return 0;
  143. }
  144. module_init(init_mtdram);
  145. module_exit(cleanup_mtdram);
  146. MODULE_LICENSE("GPL");
  147. MODULE_AUTHOR("Alexander Larsson <alexl@redhat.com>");
  148. MODULE_DESCRIPTION("Simulated MTD driver for testing");