mtdcore.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. /*
  2. * Core registration and callback routines for MTD
  3. * drivers and users.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. */
  9. #include <linux/mtd/mtd.h>
  10. #include <linux/compat.h>
  11. #include <ubi_uboot.h>
  12. struct mtd_info *mtd_table[MAX_MTD_DEVICES];
  13. int add_mtd_device(struct mtd_info *mtd)
  14. {
  15. int i;
  16. BUG_ON(mtd->writesize == 0);
  17. for (i = 0; i < MAX_MTD_DEVICES; i++)
  18. if (!mtd_table[i]) {
  19. mtd_table[i] = mtd;
  20. mtd->index = i;
  21. mtd->usecount = 0;
  22. /* default value if not set by driver */
  23. if (mtd->bitflip_threshold == 0)
  24. mtd->bitflip_threshold = mtd->ecc_strength;
  25. /* No need to get a refcount on the module containing
  26. the notifier, since we hold the mtd_table_mutex */
  27. /* We _know_ we aren't being removed, because
  28. our caller is still holding us here. So none
  29. of this try_ nonsense, and no bitching about it
  30. either. :) */
  31. return 0;
  32. }
  33. return 1;
  34. }
  35. /**
  36. * del_mtd_device - unregister an MTD device
  37. * @mtd: pointer to MTD device info structure
  38. *
  39. * Remove a device from the list of MTD devices present in the system,
  40. * and notify each currently active MTD 'user' of its departure.
  41. * Returns zero on success or 1 on failure, which currently will happen
  42. * if the requested device does not appear to be present in the list.
  43. */
  44. int del_mtd_device(struct mtd_info *mtd)
  45. {
  46. int ret;
  47. if (mtd_table[mtd->index] != mtd) {
  48. ret = -ENODEV;
  49. } else if (mtd->usecount) {
  50. printk(KERN_NOTICE "Removing MTD device #%d (%s)"
  51. " with use count %d\n",
  52. mtd->index, mtd->name, mtd->usecount);
  53. ret = -EBUSY;
  54. } else {
  55. /* No need to get a refcount on the module containing
  56. * the notifier, since we hold the mtd_table_mutex */
  57. mtd_table[mtd->index] = NULL;
  58. ret = 0;
  59. }
  60. return ret;
  61. }
  62. /**
  63. * get_mtd_device - obtain a validated handle for an MTD device
  64. * @mtd: last known address of the required MTD device
  65. * @num: internal device number of the required MTD device
  66. *
  67. * Given a number and NULL address, return the num'th entry in the device
  68. * table, if any. Given an address and num == -1, search the device table
  69. * for a device with that address and return if it's still present. Given
  70. * both, return the num'th driver only if its address matches. Return
  71. * error code if not.
  72. */
  73. struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)
  74. {
  75. struct mtd_info *ret = NULL;
  76. int i, err = -ENODEV;
  77. if (num == -1) {
  78. for (i = 0; i < MAX_MTD_DEVICES; i++)
  79. if (mtd_table[i] == mtd)
  80. ret = mtd_table[i];
  81. } else if (num < MAX_MTD_DEVICES) {
  82. ret = mtd_table[num];
  83. if (mtd && mtd != ret)
  84. ret = NULL;
  85. }
  86. if (!ret)
  87. goto out_unlock;
  88. ret->usecount++;
  89. return ret;
  90. out_unlock:
  91. return ERR_PTR(err);
  92. }
  93. /**
  94. * get_mtd_device_nm - obtain a validated handle for an MTD device by
  95. * device name
  96. * @name: MTD device name to open
  97. *
  98. * This function returns MTD device description structure in case of
  99. * success and an error code in case of failure.
  100. */
  101. struct mtd_info *get_mtd_device_nm(const char *name)
  102. {
  103. int i, err = -ENODEV;
  104. struct mtd_info *mtd = NULL;
  105. for (i = 0; i < MAX_MTD_DEVICES; i++) {
  106. if (mtd_table[i] && !strcmp(name, mtd_table[i]->name)) {
  107. mtd = mtd_table[i];
  108. break;
  109. }
  110. }
  111. if (!mtd)
  112. goto out_unlock;
  113. mtd->usecount++;
  114. return mtd;
  115. out_unlock:
  116. return ERR_PTR(err);
  117. }
  118. void put_mtd_device(struct mtd_info *mtd)
  119. {
  120. int c;
  121. c = --mtd->usecount;
  122. BUG_ON(c < 0);
  123. }
  124. #if defined(CONFIG_CMD_MTDPARTS_SPREAD)
  125. /**
  126. * mtd_get_len_incl_bad
  127. *
  128. * Check if length including bad blocks fits into device.
  129. *
  130. * @param mtd an MTD device
  131. * @param offset offset in flash
  132. * @param length image length
  133. * @return image length including bad blocks in *len_incl_bad and whether or not
  134. * the length returned was truncated in *truncated
  135. */
  136. void mtd_get_len_incl_bad(struct mtd_info *mtd, uint64_t offset,
  137. const uint64_t length, uint64_t *len_incl_bad,
  138. int *truncated)
  139. {
  140. *truncated = 0;
  141. *len_incl_bad = 0;
  142. if (!mtd->block_isbad) {
  143. *len_incl_bad = length;
  144. return;
  145. }
  146. uint64_t len_excl_bad = 0;
  147. uint64_t block_len;
  148. while (len_excl_bad < length) {
  149. if (offset >= mtd->size) {
  150. *truncated = 1;
  151. return;
  152. }
  153. block_len = mtd->erasesize - (offset & (mtd->erasesize - 1));
  154. if (!mtd->block_isbad(mtd, offset & ~(mtd->erasesize - 1)))
  155. len_excl_bad += block_len;
  156. *len_incl_bad += block_len;
  157. offset += block_len;
  158. }
  159. }
  160. #endif /* defined(CONFIG_CMD_MTDPARTS_SPREAD) */
  161. /*
  162. * Erase is an asynchronous operation. Device drivers are supposed
  163. * to call instr->callback() whenever the operation completes, even
  164. * if it completes with a failure.
  165. * Callers are supposed to pass a callback function and wait for it
  166. * to be called before writing to the block.
  167. */
  168. int mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
  169. {
  170. if (instr->addr > mtd->size || instr->len > mtd->size - instr->addr)
  171. return -EINVAL;
  172. if (!(mtd->flags & MTD_WRITEABLE))
  173. return -EROFS;
  174. instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
  175. if (!instr->len) {
  176. instr->state = MTD_ERASE_DONE;
  177. mtd_erase_callback(instr);
  178. return 0;
  179. }
  180. return mtd->_erase(mtd, instr);
  181. }
  182. int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
  183. u_char *buf)
  184. {
  185. if (from < 0 || from > mtd->size || len > mtd->size - from)
  186. return -EINVAL;
  187. if (!len)
  188. return 0;
  189. return mtd->_read(mtd, from, len, retlen, buf);
  190. }
  191. int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
  192. const u_char *buf)
  193. {
  194. *retlen = 0;
  195. if (to < 0 || to > mtd->size || len > mtd->size - to)
  196. return -EINVAL;
  197. if (!mtd->_write || !(mtd->flags & MTD_WRITEABLE))
  198. return -EROFS;
  199. if (!len)
  200. return 0;
  201. return mtd->_write(mtd, to, len, retlen, buf);
  202. }
  203. /*
  204. * In blackbox flight recorder like scenarios we want to make successful writes
  205. * in interrupt context. panic_write() is only intended to be called when its
  206. * known the kernel is about to panic and we need the write to succeed. Since
  207. * the kernel is not going to be running for much longer, this function can
  208. * break locks and delay to ensure the write succeeds (but not sleep).
  209. */
  210. int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
  211. const u_char *buf)
  212. {
  213. *retlen = 0;
  214. if (!mtd->_panic_write)
  215. return -EOPNOTSUPP;
  216. if (to < 0 || to > mtd->size || len > mtd->size - to)
  217. return -EINVAL;
  218. if (!(mtd->flags & MTD_WRITEABLE))
  219. return -EROFS;
  220. if (!len)
  221. return 0;
  222. return mtd->_panic_write(mtd, to, len, retlen, buf);
  223. }
  224. int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
  225. {
  226. ops->retlen = ops->oobretlen = 0;
  227. if (!mtd->_read_oob)
  228. return -EOPNOTSUPP;
  229. return mtd->_read_oob(mtd, from, ops);
  230. }
  231. /*
  232. * Method to access the protection register area, present in some flash
  233. * devices. The user data is one time programmable but the factory data is read
  234. * only.
  235. */
  236. int mtd_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf,
  237. size_t len)
  238. {
  239. if (!mtd->_get_fact_prot_info)
  240. return -EOPNOTSUPP;
  241. if (!len)
  242. return 0;
  243. return mtd->_get_fact_prot_info(mtd, buf, len);
  244. }
  245. int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
  246. size_t *retlen, u_char *buf)
  247. {
  248. *retlen = 0;
  249. if (!mtd->_read_fact_prot_reg)
  250. return -EOPNOTSUPP;
  251. if (!len)
  252. return 0;
  253. return mtd->_read_fact_prot_reg(mtd, from, len, retlen, buf);
  254. }
  255. int mtd_get_user_prot_info(struct mtd_info *mtd, struct otp_info *buf,
  256. size_t len)
  257. {
  258. if (!mtd->_get_user_prot_info)
  259. return -EOPNOTSUPP;
  260. if (!len)
  261. return 0;
  262. return mtd->_get_user_prot_info(mtd, buf, len);
  263. }
  264. int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
  265. size_t *retlen, u_char *buf)
  266. {
  267. *retlen = 0;
  268. if (!mtd->_read_user_prot_reg)
  269. return -EOPNOTSUPP;
  270. if (!len)
  271. return 0;
  272. return mtd->_read_user_prot_reg(mtd, from, len, retlen, buf);
  273. }
  274. int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, size_t len,
  275. size_t *retlen, u_char *buf)
  276. {
  277. *retlen = 0;
  278. if (!mtd->_write_user_prot_reg)
  279. return -EOPNOTSUPP;
  280. if (!len)
  281. return 0;
  282. return mtd->_write_user_prot_reg(mtd, to, len, retlen, buf);
  283. }
  284. int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len)
  285. {
  286. if (!mtd->_lock_user_prot_reg)
  287. return -EOPNOTSUPP;
  288. if (!len)
  289. return 0;
  290. return mtd->_lock_user_prot_reg(mtd, from, len);
  291. }
  292. /* Chip-supported device locking */
  293. int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
  294. {
  295. if (!mtd->_lock)
  296. return -EOPNOTSUPP;
  297. if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs)
  298. return -EINVAL;
  299. if (!len)
  300. return 0;
  301. return mtd->_lock(mtd, ofs, len);
  302. }
  303. int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
  304. {
  305. if (!mtd->_unlock)
  306. return -EOPNOTSUPP;
  307. if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs)
  308. return -EINVAL;
  309. if (!len)
  310. return 0;
  311. return mtd->_unlock(mtd, ofs, len);
  312. }
  313. int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs)
  314. {
  315. if (!mtd->_block_isbad)
  316. return 0;
  317. if (ofs < 0 || ofs > mtd->size)
  318. return -EINVAL;
  319. return mtd->_block_isbad(mtd, ofs);
  320. }
  321. int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs)
  322. {
  323. if (!mtd->_block_markbad)
  324. return -EOPNOTSUPP;
  325. if (ofs < 0 || ofs > mtd->size)
  326. return -EINVAL;
  327. if (!(mtd->flags & MTD_WRITEABLE))
  328. return -EROFS;
  329. return mtd->_block_markbad(mtd, ofs);
  330. }