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

嵌入式Linux

开发平台:

Unix_Linux

  1. /* fortunet.c memory map
  2.  */
  3. #include <linux/module.h>
  4. #include <linux/types.h>
  5. #include <linux/kernel.h>
  6. #include <asm/io.h>
  7. #include <linux/mtd/mtd.h>
  8. #include <linux/mtd/map.h>
  9. #include <linux/mtd/partitions.h>
  10. #define MAX_NUM_REGIONS 4
  11. #define MAX_NUM_PARTITIONS 8
  12. #define DEF_WINDOW_ADDR_PHY 0x00000000
  13. #define DEF_WINDOW_SIZE 0x00800000 // 8 Mega Bytes
  14. #define MTD_FORTUNET_PK "MTD FortuNet: "
  15. #define MAX_NAME_SIZE 128
  16. struct map_region
  17. {
  18. int window_addr_phyical;
  19. int altbuswidth;
  20. struct map_info map_info;
  21. struct mtd_info *mymtd;
  22. struct mtd_partition parts[MAX_NUM_PARTITIONS];
  23. char map_name[MAX_NAME_SIZE];
  24. char parts_name[MAX_NUM_PARTITIONS][MAX_NAME_SIZE];
  25. };
  26. static struct map_region map_regions[MAX_NUM_REGIONS];
  27. static int map_regions_set[MAX_NUM_REGIONS] = {0,0,0,0};
  28. static int map_regions_parts[MAX_NUM_REGIONS] = {0,0,0,0};
  29. __u8 fortunet_read8(struct map_info *map, unsigned long ofs)
  30. {
  31. return *(__u8 *)(map->map_priv_1 + ofs);
  32. }
  33. __u16 fortunet_read16(struct map_info *map, unsigned long ofs)
  34. {
  35. return *(__u16 *)(map->map_priv_1 + ofs);
  36. }
  37. __u32 fortunet_read32(struct map_info *map, unsigned long ofs)
  38. {
  39. return *(__u32 *)(map->map_priv_1 + ofs);
  40. }
  41. void fortunet_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
  42. {
  43. memcpy(to, (void *)(map->map_priv_1 + from), len);
  44. }
  45. void fortunet_write8(struct map_info *map, __u8 d, unsigned long adr)
  46. {
  47. *(__u8 *)(map->map_priv_1 + adr) = d;
  48. }
  49. void fortunet_write16(struct map_info *map, __u16 d, unsigned long adr)
  50. {
  51. *(__u16 *)(map->map_priv_1 + adr) = d;
  52. }
  53. void fortunet_write32(struct map_info *map, __u32 d, unsigned long adr)
  54. {
  55. *(__u32 *)(map->map_priv_1 + adr) = d;
  56. }
  57. void fortunet_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
  58. {
  59. memcpy((void *)(map->map_priv_1 + to), from, len);
  60. }
  61. struct map_info default_map = {
  62. size: DEF_WINDOW_SIZE,
  63. buswidth: 4,
  64. read8: fortunet_read8,
  65. read16: fortunet_read16,
  66. read32: fortunet_read32,
  67. copy_from: fortunet_copy_from,
  68. write8: fortunet_write8,
  69. write16: fortunet_write16,
  70. write32: fortunet_write32,
  71. copy_to: fortunet_copy_to
  72. };
  73. static char * __init get_string_option(char *dest,int dest_size,char *sor)
  74. {
  75. if(!dest_size)
  76. return sor;
  77. dest_size--;
  78. while(*sor)
  79. {
  80. if(*sor==',')
  81. {
  82. sor++;
  83. break;
  84. }
  85. else if(*sor=='"')
  86. {
  87. sor++;
  88. while(*sor)
  89. {
  90. if(*sor=='"')
  91. {
  92. sor++;
  93. break;
  94. }
  95. *dest = *sor;
  96. dest++;
  97. sor++;
  98. dest_size--;
  99. if(!dest_size)
  100. {
  101. *dest = 0;
  102. return sor;
  103. }
  104. }
  105. }
  106. else
  107. {
  108. *dest = *sor;
  109. dest++;
  110. sor++;
  111. dest_size--;
  112. if(!dest_size)
  113. {
  114. *dest = 0;
  115. return sor;
  116. }
  117. }
  118. }
  119. *dest = 0;
  120. return sor;
  121. }
  122. static int __init MTD_New_Region(char *line)
  123. {
  124. char string[MAX_NAME_SIZE];
  125. int params[6];
  126. get_options (get_string_option(string,sizeof(string),line),6,params);
  127. if(params[0]<1)
  128. {
  129. printk(MTD_FORTUNET_PK "Bad paramters for MTD Region "
  130. " name,region-number[,base,size,buswidth,altbuswidth]n");
  131. return 1;
  132. }
  133. if((params[1]<0)||(params[1]>=MAX_NUM_REGIONS))
  134. {
  135. printk(MTD_FORTUNET_PK "Bad region index of %d only have 0..%u regionsn",
  136. params[1],MAX_NUM_REGIONS-1);
  137. return 1;
  138. }
  139. memset(&map_regions[params[1]],0,sizeof(map_regions[params[1]]));
  140. memcpy(&map_regions[params[1]].map_info,
  141. &default_map,sizeof(map_regions[params[1]].map_info));
  142.         map_regions_set[params[1]] = 1;
  143.         map_regions[params[1]].window_addr_phyical = DEF_WINDOW_ADDR_PHY;
  144.         map_regions[params[1]].altbuswidth = 2;
  145.         map_regions[params[1]].mymtd = NULL;
  146. map_regions[params[1]].map_info.name = map_regions[params[1]].map_name;
  147. strcpy(map_regions[params[1]].map_info.name,string);
  148. if(params[0]>1)
  149. {
  150. map_regions[params[1]].window_addr_phyical = params[2];
  151. }
  152. if(params[0]>2)
  153. {
  154. map_regions[params[1]].map_info.size = params[3];
  155. }
  156. if(params[0]>3)
  157. {
  158. map_regions[params[1]].map_info.buswidth = params[4];
  159. }
  160. if(params[0]>4)
  161. {
  162. map_regions[params[1]].altbuswidth = params[5];
  163. }
  164. return 1;
  165. }
  166. static int __init MTD_New_Partion(char *line)
  167. {
  168. char string[MAX_NAME_SIZE];
  169. int params[4];
  170. get_options (get_string_option(string,sizeof(string),line),4,params);
  171. if(params[0]<3)
  172. {
  173. printk(MTD_FORTUNET_PK "Bad paramters for MTD Partion "
  174. " name,region-number,size,offsetn");
  175. return 1;
  176. }
  177. if((params[1]<0)||(params[1]>=MAX_NUM_REGIONS))
  178. {
  179. printk(MTD_FORTUNET_PK "Bad region index of %d only have 0..%u regionsn",
  180. params[1],MAX_NUM_REGIONS-1);
  181. return 1;
  182. }
  183. if(map_regions_parts[params[1]]>=MAX_NUM_PARTITIONS)
  184. {
  185. printk(MTD_FORTUNET_PK "Out of space for partion in this regionn");
  186. return 1;
  187. }
  188. map_regions[params[1]].parts[map_regions_parts[params[1]]].name =
  189. map_regions[params[1]]. parts_name[map_regions_parts[params[1]]];
  190. strcpy(map_regions[params[1]].parts[map_regions_parts[params[1]]].name,string);
  191. map_regions[params[1]].parts[map_regions_parts[params[1]]].size =
  192. params[2];
  193. map_regions[params[1]].parts[map_regions_parts[params[1]]].offset =
  194. params[3];
  195. map_regions[params[1]].parts[map_regions_parts[params[1]]].mask_flags = 0;
  196. map_regions_parts[params[1]]++;
  197. return 1;
  198. }
  199. __setup("MTD_Region=", MTD_New_Region);
  200. __setup("MTD_Partion=", MTD_New_Partion);
  201. int __init init_fortunet(void)
  202. {
  203. int ix,iy;
  204. for(iy=ix=0;ix<MAX_NUM_REGIONS;ix++)
  205. {
  206. if(map_regions_parts[ix]&&(!map_regions_set[ix]))
  207. {
  208. printk(MTD_FORTUNET_PK "Region %d is not setup (Seting to default)n",
  209. ix);
  210. memset(&map_regions[ix],0,sizeof(map_regions[ix]));
  211. memcpy(&map_regions[ix].map_info,&default_map,
  212. sizeof(map_regions[ix].map_info));
  213. map_regions_set[ix] = 1;
  214. map_regions[ix].window_addr_phyical = DEF_WINDOW_ADDR_PHY;
  215. map_regions[ix].altbuswidth = 2;
  216. map_regions[ix].mymtd = NULL;
  217. map_regions[ix].map_info.name = map_regions[ix].map_name;
  218. strcpy(map_regions[ix].map_info.name,"FORTUNET");
  219. }
  220. if(map_regions_set[ix])
  221. {
  222. iy++;
  223. printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash device at phyicaly "
  224. " address %x size %xn",
  225. map_regions[ix].map_info.name,
  226. map_regions[ix].window_addr_phyical,
  227. map_regions[ix].map_info.size);
  228. map_regions[ix].map_info.map_priv_1 =
  229. (int)ioremap_nocache(
  230. map_regions[ix].window_addr_phyical,
  231. map_regions[ix].map_info.size);
  232. if(!map_regions[ix].map_info.map_priv_1)
  233. {
  234. printk(MTD_FORTUNET_PK "%s flash failed to ioremap!n",
  235. map_regions[ix].map_info.name);
  236. return -ENXIO;
  237. }
  238. printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash is veritualy at: %xn",
  239. map_regions[ix].map_info.name,
  240. map_regions[ix].map_info.map_priv_1);
  241. map_regions[ix].mymtd = do_map_probe("cfi_probe",
  242. &map_regions[ix].map_info);
  243. if((!map_regions[ix].mymtd)&&(
  244. map_regions[ix].altbuswidth!=map_regions[ix].map_info.buswidth))
  245. {
  246. printk(KERN_NOTICE MTD_FORTUNET_PK "Trying alternet buswidth "
  247. "for %s flash.n",
  248. map_regions[ix].map_info.name);
  249. map_regions[ix].map_info.buswidth =
  250. map_regions[ix].altbuswidth;
  251. map_regions[ix].mymtd = do_map_probe("cfi_probe",
  252. &map_regions[ix].map_info);
  253. }
  254. map_regions[ix].mymtd->module = THIS_MODULE;
  255. add_mtd_partitions(map_regions[ix].mymtd,
  256. map_regions[ix].parts,map_regions_parts[ix]);
  257. }
  258. }
  259. if(iy)
  260. return 0;
  261. return -ENXIO;
  262. }
  263. static void __exit cleanup_fortunet(void)
  264. {
  265. int ix;
  266. for(ix=0;ix<MAX_NUM_REGIONS;ix++)
  267. {
  268. if(map_regions_set[ix])
  269. {
  270. if( map_regions[ix].mymtd )
  271. {
  272. del_mtd_partitions( map_regions[ix].mymtd );
  273. map_destroy( map_regions[ix].mymtd );
  274. }
  275. iounmap((void *)map_regions[ix].map_info.map_priv_1);
  276. }
  277. }
  278. }
  279. module_init(init_fortunet);
  280. module_exit(cleanup_fortunet);
  281. MODULE_AUTHOR("FortuNet, Inc.");
  282. MODULE_DESCRIPTION("MTD map driver for FortuNet boards");