mtdram.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:5k
源码类别:

嵌入式Linux

开发平台:

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_DESC(total_size, "Total device size in KiB");
  28. MODULE_PARM(erase_size,"l");
  29. MODULE_PARM_DESC(erase_size, "Device erase block size in KiB");
  30. #define MTDRAM_TOTAL_SIZE (total_size * 1024)
  31. #define MTDRAM_ERASE_SIZE (erase_size * 1024)
  32. #else
  33. #define MTDRAM_TOTAL_SIZE (CONFIG_MTDRAM_TOTAL_SIZE * 1024)
  34. #define MTDRAM_ERASE_SIZE (CONFIG_MTDRAM_ERASE_SIZE * 1024)
  35. #endif
  36. // We could store these in the mtd structure, but we only support 1 device..
  37. static struct mtd_info *mtd_info;
  38. static int
  39. ram_erase(struct mtd_info *mtd, struct erase_info *instr)
  40. {
  41.   DEBUG(MTD_DEBUG_LEVEL2, "ram_erase(pos:%ld, len:%ld)n", (long)instr->addr, (long)instr->len);
  42.   if (instr->addr + instr->len > mtd->size) {
  43.     DEBUG(MTD_DEBUG_LEVEL1, "ram_erase() out of bounds (%ld > %ld)n", (long)(instr->addr + instr->len), (long)mtd->size);
  44.     return -EINVAL;
  45.   }
  46.   memset((char *)mtd->priv + instr->addr, 0xff, instr->len);
  47.   instr->state = MTD_ERASE_DONE;
  48.   if (instr->callback)
  49.     (*(instr->callback))(instr);
  50.   return 0;
  51. }
  52. static int ram_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf)
  53. {
  54.   if (from + len > mtd->size)
  55.     return -EINVAL;
  56.   *mtdbuf = mtd->priv + from;
  57.   *retlen = len;
  58.   return 0;
  59. }
  60. static void ram_unpoint (struct mtd_info *mtd, u_char *addr)
  61. {
  62.   DEBUG(MTD_DEBUG_LEVEL2, "ram_unpointn");
  63. }
  64. static int ram_read(struct mtd_info *mtd, loff_t from, size_t len,
  65.      size_t *retlen, u_char *buf)
  66. {
  67.   DEBUG(MTD_DEBUG_LEVEL2, "ram_read(pos:%ld, len:%ld)n", (long)from, (long)len);
  68.   if (from + len > mtd->size) {
  69.     DEBUG(MTD_DEBUG_LEVEL1, "ram_read() out of bounds (%ld > %ld)n", (long)(from + len), (long)mtd->size);
  70.     return -EINVAL;
  71.   }
  72.   memcpy(buf, mtd->priv + from, len);
  73.   *retlen=len;
  74.   return 0;
  75. }
  76. static int ram_write(struct mtd_info *mtd, loff_t to, size_t len,
  77.       size_t *retlen, const u_char *buf)
  78. {
  79.   DEBUG(MTD_DEBUG_LEVEL2, "ram_write(pos:%ld, len:%ld)n", (long)to, (long)len);
  80.   if (to + len > mtd->size) {
  81.     DEBUG(MTD_DEBUG_LEVEL1, "ram_write() out of bounds (%ld > %ld)n", (long)(to + len), (long)mtd->size);
  82.     return -EINVAL;
  83.   }
  84.   memcpy ((char *)mtd->priv + to, buf, len);
  85.   *retlen=len;
  86.   return 0;
  87. }
  88. static void __exit cleanup_mtdram(void)
  89. {
  90.   if (mtd_info) {
  91.     del_mtd_device(mtd_info);
  92.     if (mtd_info->priv)
  93. #if CONFIG_MTDRAM_ABS_POS > 0
  94.       iounmap(mtd_info->priv);
  95. #else
  96.       vfree(mtd_info->priv);
  97. #endif
  98.     kfree(mtd_info);
  99.   }
  100. }
  101. int __init init_mtdram(void)
  102. {
  103.    // Allocate some memory
  104.    mtd_info = (struct mtd_info *)kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
  105.    if (!mtd_info)
  106.       return -ENOMEM;
  107.    
  108.    memset(mtd_info, 0, sizeof(*mtd_info));
  109.    // Setup the MTD structure
  110.    mtd_info->name = "mtdram test device";
  111.    mtd_info->type = MTD_RAM;
  112.    mtd_info->flags = MTD_CAP_RAM;
  113.    mtd_info->size = MTDRAM_TOTAL_SIZE;
  114.    mtd_info->erasesize = MTDRAM_ERASE_SIZE;
  115. #if CONFIG_MTDRAM_ABS_POS > 0
  116.    mtd_info->priv = ioremap(CONFIG_MTDRAM_ABS_POS, MTDRAM_TOTAL_SIZE);
  117. #else
  118.    mtd_info->priv = vmalloc(MTDRAM_TOTAL_SIZE);
  119. #endif
  120.    if (!mtd_info->priv) {
  121.      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);
  122.      kfree(mtd_info);
  123.      mtd_info = NULL;
  124.      return -ENOMEM;
  125.    }
  126. #ifndef CONFIG_MIZI   
  127.    memset(mtd_info->priv, 0xff, MTDRAM_TOTAL_SIZE);
  128. #endif
  129.    mtd_info->module = THIS_MODULE;
  130.    mtd_info->erase = ram_erase;
  131.    mtd_info->point = ram_point;
  132.    mtd_info->unpoint = ram_unpoint;
  133.    mtd_info->read = ram_read;
  134.    mtd_info->write = ram_write;
  135.    if (add_mtd_device(mtd_info)) {
  136. #if CONFIG_MTDRAM_ABS_POS > 0
  137.      iounmap(mtd_info->priv);
  138. #else
  139.      vfree(mtd_info->priv);
  140. #endif
  141.      kfree(mtd_info);
  142.      mtd_info = NULL;
  143.      return -EIO;
  144.    }
  145.    
  146.    return 0;
  147. }
  148. module_init(init_mtdram);
  149. module_exit(cleanup_mtdram);
  150. MODULE_LICENSE("GPL");
  151. MODULE_AUTHOR("Alexander Larsson <alexl@redhat.com>");
  152. MODULE_DESCRIPTION("Simulated MTD driver for testing");