aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/mtd/mtd.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/mtd/mtd.h')
-rw-r--r--include/linux/mtd/mtd.h304
1 files changed, 84 insertions, 220 deletions
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index d43dc25af82e..cf5ea8cdcf8e 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -164,6 +164,9 @@ struct mtd_info {
164 /* ECC layout structure pointer - read only! */ 164 /* ECC layout structure pointer - read only! */
165 struct nand_ecclayout *ecclayout; 165 struct nand_ecclayout *ecclayout;
166 166
167 /* max number of correctible bit errors per writesize */
168 unsigned int ecc_strength;
169
167 /* Data for variable erase regions. If numeraseregions is zero, 170 /* Data for variable erase regions. If numeraseregions is zero,
168 * it means that the whole device has erasesize as given above. 171 * it means that the whole device has erasesize as given above.
169 */ 172 */
@@ -174,52 +177,52 @@ struct mtd_info {
174 * Do not call via these pointers, use corresponding mtd_*() 177 * Do not call via these pointers, use corresponding mtd_*()
175 * wrappers instead. 178 * wrappers instead.
176 */ 179 */
177 int (*erase) (struct mtd_info *mtd, struct erase_info *instr); 180 int (*_erase) (struct mtd_info *mtd, struct erase_info *instr);
178 int (*point) (struct mtd_info *mtd, loff_t from, size_t len, 181 int (*_point) (struct mtd_info *mtd, loff_t from, size_t len,
179 size_t *retlen, void **virt, resource_size_t *phys); 182 size_t *retlen, void **virt, resource_size_t *phys);
180 void (*unpoint) (struct mtd_info *mtd, loff_t from, size_t len); 183 int (*_unpoint) (struct mtd_info *mtd, loff_t from, size_t len);
181 unsigned long (*get_unmapped_area) (struct mtd_info *mtd, 184 unsigned long (*_get_unmapped_area) (struct mtd_info *mtd,
182 unsigned long len, 185 unsigned long len,
183 unsigned long offset, 186 unsigned long offset,
184 unsigned long flags); 187 unsigned long flags);
185 int (*read) (struct mtd_info *mtd, loff_t from, size_t len, 188 int (*_read) (struct mtd_info *mtd, loff_t from, size_t len,
186 size_t *retlen, u_char *buf); 189 size_t *retlen, u_char *buf);
187 int (*write) (struct mtd_info *mtd, loff_t to, size_t len, 190 int (*_write) (struct mtd_info *mtd, loff_t to, size_t len,
188 size_t *retlen, const u_char *buf); 191 size_t *retlen, const u_char *buf);
189 int (*panic_write) (struct mtd_info *mtd, loff_t to, size_t len, 192 int (*_panic_write) (struct mtd_info *mtd, loff_t to, size_t len,
190 size_t *retlen, const u_char *buf); 193 size_t *retlen, const u_char *buf);
191 int (*read_oob) (struct mtd_info *mtd, loff_t from, 194 int (*_read_oob) (struct mtd_info *mtd, loff_t from,
192 struct mtd_oob_ops *ops);
193 int (*write_oob) (struct mtd_info *mtd, loff_t to,
194 struct mtd_oob_ops *ops); 195 struct mtd_oob_ops *ops);
195 int (*get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, 196 int (*_write_oob) (struct mtd_info *mtd, loff_t to,
196 size_t len); 197 struct mtd_oob_ops *ops);
197 int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, 198 int (*_get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf,
198 size_t len, size_t *retlen, u_char *buf); 199 size_t len);
199 int (*get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf, 200 int (*_read_fact_prot_reg) (struct mtd_info *mtd, loff_t from,
200 size_t len); 201 size_t len, size_t *retlen, u_char *buf);
201 int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, 202 int (*_get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf,
202 size_t len, size_t *retlen, u_char *buf); 203 size_t len);
203 int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t to, size_t len, 204 int (*_read_user_prot_reg) (struct mtd_info *mtd, loff_t from,
204 size_t *retlen, u_char *buf); 205 size_t len, size_t *retlen, u_char *buf);
205 int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, 206 int (*_write_user_prot_reg) (struct mtd_info *mtd, loff_t to,
206 size_t len); 207 size_t len, size_t *retlen, u_char *buf);
207 int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, 208 int (*_lock_user_prot_reg) (struct mtd_info *mtd, loff_t from,
209 size_t len);
210 int (*_writev) (struct mtd_info *mtd, const struct kvec *vecs,
208 unsigned long count, loff_t to, size_t *retlen); 211 unsigned long count, loff_t to, size_t *retlen);
209 void (*sync) (struct mtd_info *mtd); 212 void (*_sync) (struct mtd_info *mtd);
210 int (*lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len); 213 int (*_lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
211 int (*unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len); 214 int (*_unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
212 int (*is_locked) (struct mtd_info *mtd, loff_t ofs, uint64_t len); 215 int (*_is_locked) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
213 int (*block_isbad) (struct mtd_info *mtd, loff_t ofs); 216 int (*_block_isbad) (struct mtd_info *mtd, loff_t ofs);
214 int (*block_markbad) (struct mtd_info *mtd, loff_t ofs); 217 int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs);
215 int (*suspend) (struct mtd_info *mtd); 218 int (*_suspend) (struct mtd_info *mtd);
216 void (*resume) (struct mtd_info *mtd); 219 void (*_resume) (struct mtd_info *mtd);
217 /* 220 /*
218 * If the driver is something smart, like UBI, it may need to maintain 221 * If the driver is something smart, like UBI, it may need to maintain
219 * its own reference counting. The below functions are only for driver. 222 * its own reference counting. The below functions are only for driver.
220 */ 223 */
221 int (*get_device) (struct mtd_info *mtd); 224 int (*_get_device) (struct mtd_info *mtd);
222 void (*put_device) (struct mtd_info *mtd); 225 void (*_put_device) (struct mtd_info *mtd);
223 226
224 /* Backing device capabilities for this device 227 /* Backing device capabilities for this device
225 * - provides mmap capabilities 228 * - provides mmap capabilities
@@ -240,214 +243,75 @@ struct mtd_info {
240 int usecount; 243 int usecount;
241}; 244};
242 245
243/* 246int mtd_erase(struct mtd_info *mtd, struct erase_info *instr);
244 * Erase is an asynchronous operation. Device drivers are supposed 247int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
245 * to call instr->callback() whenever the operation completes, even 248 void **virt, resource_size_t *phys);
246 * if it completes with a failure. 249int mtd_unpoint(struct mtd_info *mtd, loff_t from, size_t len);
247 * Callers are supposed to pass a callback function and wait for it 250unsigned long mtd_get_unmapped_area(struct mtd_info *mtd, unsigned long len,
248 * to be called before writing to the block. 251 unsigned long offset, unsigned long flags);
249 */ 252int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,
250static inline int mtd_erase(struct mtd_info *mtd, struct erase_info *instr) 253 u_char *buf);
251{ 254int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
252 return mtd->erase(mtd, instr); 255 const u_char *buf);
253} 256int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
254 257 const u_char *buf);
255/*
256 * This stuff for eXecute-In-Place. phys is optional and may be set to NULL.
257 */
258static inline int mtd_point(struct mtd_info *mtd, loff_t from, size_t len,
259 size_t *retlen, void **virt, resource_size_t *phys)
260{
261 *retlen = 0;
262 if (!mtd->point)
263 return -EOPNOTSUPP;
264 return mtd->point(mtd, from, len, retlen, virt, phys);
265}
266
267/* We probably shouldn't allow XIP if the unpoint isn't a NULL */
268static inline void mtd_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
269{
270 return mtd->unpoint(mtd, from, len);
271}
272
273/*
274 * Allow NOMMU mmap() to directly map the device (if not NULL)
275 * - return the address to which the offset maps
276 * - return -ENOSYS to indicate refusal to do the mapping
277 */
278static inline unsigned long mtd_get_unmapped_area(struct mtd_info *mtd,
279 unsigned long len,
280 unsigned long offset,
281 unsigned long flags)
282{
283 if (!mtd->get_unmapped_area)
284 return -EOPNOTSUPP;
285 return mtd->get_unmapped_area(mtd, len, offset, flags);
286}
287
288static inline int mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
289 size_t *retlen, u_char *buf)
290{
291 return mtd->read(mtd, from, len, retlen, buf);
292}
293
294static inline int mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
295 size_t *retlen, const u_char *buf)
296{
297 *retlen = 0;
298 if (!mtd->write)
299 return -EROFS;
300 return mtd->write(mtd, to, len, retlen, buf);
301}
302
303/*
304 * In blackbox flight recorder like scenarios we want to make successful writes
305 * in interrupt context. panic_write() is only intended to be called when its
306 * known the kernel is about to panic and we need the write to succeed. Since
307 * the kernel is not going to be running for much longer, this function can
308 * break locks and delay to ensure the write succeeds (but not sleep).
309 */
310static inline int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
311 size_t *retlen, const u_char *buf)
312{
313 *retlen = 0;
314 if (!mtd->panic_write)
315 return -EOPNOTSUPP;
316 return mtd->panic_write(mtd, to, len, retlen, buf);
317}
318 258
319static inline int mtd_read_oob(struct mtd_info *mtd, loff_t from, 259static inline int mtd_read_oob(struct mtd_info *mtd, loff_t from,
320 struct mtd_oob_ops *ops) 260 struct mtd_oob_ops *ops)
321{ 261{
322 ops->retlen = ops->oobretlen = 0; 262 ops->retlen = ops->oobretlen = 0;
323 if (!mtd->read_oob) 263 if (!mtd->_read_oob)
324 return -EOPNOTSUPP; 264 return -EOPNOTSUPP;
325 return mtd->read_oob(mtd, from, ops); 265 return mtd->_read_oob(mtd, from, ops);
326} 266}
327 267
328static inline int mtd_write_oob(struct mtd_info *mtd, loff_t to, 268static inline int mtd_write_oob(struct mtd_info *mtd, loff_t to,
329 struct mtd_oob_ops *ops) 269 struct mtd_oob_ops *ops)
330{ 270{
331 ops->retlen = ops->oobretlen = 0; 271 ops->retlen = ops->oobretlen = 0;
332 if (!mtd->write_oob) 272 if (!mtd->_write_oob)
333 return -EOPNOTSUPP;
334 return mtd->write_oob(mtd, to, ops);
335}
336
337/*
338 * Method to access the protection register area, present in some flash
339 * devices. The user data is one time programmable but the factory data is read
340 * only.
341 */
342static inline int mtd_get_fact_prot_info(struct mtd_info *mtd,
343 struct otp_info *buf, size_t len)
344{
345 if (!mtd->get_fact_prot_info)
346 return -EOPNOTSUPP; 273 return -EOPNOTSUPP;
347 return mtd->get_fact_prot_info(mtd, buf, len); 274 if (!(mtd->flags & MTD_WRITEABLE))
348} 275 return -EROFS;
349 276 return mtd->_write_oob(mtd, to, ops);
350static inline int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from,
351 size_t len, size_t *retlen,
352 u_char *buf)
353{
354 *retlen = 0;
355 if (!mtd->read_fact_prot_reg)
356 return -EOPNOTSUPP;
357 return mtd->read_fact_prot_reg(mtd, from, len, retlen, buf);
358}
359
360static inline int mtd_get_user_prot_info(struct mtd_info *mtd,
361 struct otp_info *buf,
362 size_t len)
363{
364 if (!mtd->get_user_prot_info)
365 return -EOPNOTSUPP;
366 return mtd->get_user_prot_info(mtd, buf, len);
367}
368
369static inline int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from,
370 size_t len, size_t *retlen,
371 u_char *buf)
372{
373 *retlen = 0;
374 if (!mtd->read_user_prot_reg)
375 return -EOPNOTSUPP;
376 return mtd->read_user_prot_reg(mtd, from, len, retlen, buf);
377}
378
379static inline int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to,
380 size_t len, size_t *retlen,
381 u_char *buf)
382{
383 *retlen = 0;
384 if (!mtd->write_user_prot_reg)
385 return -EOPNOTSUPP;
386 return mtd->write_user_prot_reg(mtd, to, len, retlen, buf);
387} 277}
388 278
389static inline int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, 279int mtd_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf,
390 size_t len) 280 size_t len);
391{ 281int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
392 if (!mtd->lock_user_prot_reg) 282 size_t *retlen, u_char *buf);
393 return -EOPNOTSUPP; 283int mtd_get_user_prot_info(struct mtd_info *mtd, struct otp_info *buf,
394 return mtd->lock_user_prot_reg(mtd, from, len); 284 size_t len);
395} 285int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
286 size_t *retlen, u_char *buf);
287int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, size_t len,
288 size_t *retlen, u_char *buf);
289int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len);
396 290
397int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, 291int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,
398 unsigned long count, loff_t to, size_t *retlen); 292 unsigned long count, loff_t to, size_t *retlen);
399 293
400static inline void mtd_sync(struct mtd_info *mtd) 294static inline void mtd_sync(struct mtd_info *mtd)
401{ 295{
402 if (mtd->sync) 296 if (mtd->_sync)
403 mtd->sync(mtd); 297 mtd->_sync(mtd);
404}
405
406/* Chip-supported device locking */
407static inline int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
408{
409 if (!mtd->lock)
410 return -EOPNOTSUPP;
411 return mtd->lock(mtd, ofs, len);
412} 298}
413 299
414static inline int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) 300int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
415{ 301int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
416 if (!mtd->unlock) 302int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len);
417 return -EOPNOTSUPP; 303int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs);
418 return mtd->unlock(mtd, ofs, len); 304int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs);
419}
420
421static inline int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
422{
423 if (!mtd->is_locked)
424 return -EOPNOTSUPP;
425 return mtd->is_locked(mtd, ofs, len);
426}
427 305
428static inline int mtd_suspend(struct mtd_info *mtd) 306static inline int mtd_suspend(struct mtd_info *mtd)
429{ 307{
430 return mtd->suspend ? mtd->suspend(mtd) : 0; 308 return mtd->_suspend ? mtd->_suspend(mtd) : 0;
431} 309}
432 310
433static inline void mtd_resume(struct mtd_info *mtd) 311static inline void mtd_resume(struct mtd_info *mtd)
434{ 312{
435 if (mtd->resume) 313 if (mtd->_resume)
436 mtd->resume(mtd); 314 mtd->_resume(mtd);
437}
438
439static inline int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs)
440{
441 if (!mtd->block_isbad)
442 return 0;
443 return mtd->block_isbad(mtd, ofs);
444}
445
446static inline int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs)
447{
448 if (!mtd->block_markbad)
449 return -EOPNOTSUPP;
450 return mtd->block_markbad(mtd, ofs);
451} 315}
452 316
453static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd) 317static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd)
@@ -482,12 +346,12 @@ static inline uint32_t mtd_mod_by_ws(uint64_t sz, struct mtd_info *mtd)
482 346
483static inline int mtd_has_oob(const struct mtd_info *mtd) 347static inline int mtd_has_oob(const struct mtd_info *mtd)
484{ 348{
485 return mtd->read_oob && mtd->write_oob; 349 return mtd->_read_oob && mtd->_write_oob;
486} 350}
487 351
488static inline int mtd_can_have_bb(const struct mtd_info *mtd) 352static inline int mtd_can_have_bb(const struct mtd_info *mtd)
489{ 353{
490 return !!mtd->block_isbad; 354 return !!mtd->_block_isbad;
491} 355}
492 356
493 /* Kernel-side ioctl definitions */ 357 /* Kernel-side ioctl definitions */