diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-07 13:20:31 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-07 13:20:31 -0500 |
| commit | a8e98d6d51a3eb7bb061b1625193a129c8bd094f (patch) | |
| tree | 0fa58b6e11e37023b024e55b8f0e7e01438706d4 /drivers/mtd/ubi/kapi.c | |
| parent | f0f1b3364ae7f48084bdf2837fb979ff59622523 (diff) | |
| parent | f9f7dd222364a6428d2ad99a515935dd1dd89d18 (diff) | |
Merge git://git.infradead.org/mtd-2.6
* git://git.infradead.org/mtd-2.6: (120 commits)
[MTD] Fix mtdoops.c compilation
[MTD] [NOR] fix startup lock when using multiple nor flash chips
[MTD] [DOC200x] eccbuf is statically defined and always evaluate to true
[MTD] Fix maps/physmap.c compilation with CONFIG_PM
[MTD] onenand: Add panic_write function to the onenand driver
[MTD] mtdoops: Use the panic_write function when present
[MTD] Add mtd panic_write function pointer
[MTD] [NAND] Freescale enhanced Local Bus Controller FCM NAND support.
[MTD] physmap.c: Add support for multiple resources
[MTD] [NAND] Fix misparenthesization introduced by commit 78b65179...
[MTD] [NAND] Fix Blackfin NFC ECC calculating bug with page size 512 bytes
[MTD] [NAND] Remove wrong operation in PM function of the BF54x NFC driver
[MTD] [NAND] Remove unused variable in plat_nand_remove
[MTD] Unlocking all Intel flash that is locked on power up.
[MTD] [NAND] at91_nand: Make mtdparts option can override board info
[MTD] mtdoops: Various minor cleanups
[MTD] mtdoops: Ensure sequential write to the buffer
[MTD] mtdoops: Perform write operations in a workqueue
[MTD] mtdoops: Add further error return code checking
[MTD] [NOR] Test devtype, not definition in flash_probe(), drivers/mtd/devices/lart.c
...
Diffstat (limited to 'drivers/mtd/ubi/kapi.c')
| -rw-r--r-- | drivers/mtd/ubi/kapi.c | 177 |
1 files changed, 116 insertions, 61 deletions
diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c index 03c774f41549..a70d58823f8d 100644 --- a/drivers/mtd/ubi/kapi.c +++ b/drivers/mtd/ubi/kapi.c | |||
| @@ -30,23 +30,27 @@ | |||
| 30 | * @ubi_num: UBI device number | 30 | * @ubi_num: UBI device number |
| 31 | * @di: the information is stored here | 31 | * @di: the information is stored here |
| 32 | * | 32 | * |
| 33 | * This function returns %0 in case of success and a %-ENODEV if there is no | 33 | * This function returns %0 in case of success, %-EINVAL if the UBI device |
| 34 | * such UBI device. | 34 | * number is invalid, and %-ENODEV if there is no such UBI device. |
| 35 | */ | 35 | */ |
| 36 | int ubi_get_device_info(int ubi_num, struct ubi_device_info *di) | 36 | int ubi_get_device_info(int ubi_num, struct ubi_device_info *di) |
| 37 | { | 37 | { |
| 38 | const struct ubi_device *ubi; | 38 | struct ubi_device *ubi; |
| 39 | |||
| 40 | if (ubi_num < 0 || ubi_num >= UBI_MAX_DEVICES) | ||
| 41 | return -EINVAL; | ||
| 39 | 42 | ||
| 40 | if (ubi_num < 0 || ubi_num >= UBI_MAX_DEVICES || | 43 | ubi = ubi_get_device(ubi_num); |
| 41 | !ubi_devices[ubi_num]) | 44 | if (!ubi) |
| 42 | return -ENODEV; | 45 | return -ENODEV; |
| 43 | 46 | ||
| 44 | ubi = ubi_devices[ubi_num]; | ||
| 45 | di->ubi_num = ubi->ubi_num; | 47 | di->ubi_num = ubi->ubi_num; |
| 46 | di->leb_size = ubi->leb_size; | 48 | di->leb_size = ubi->leb_size; |
| 47 | di->min_io_size = ubi->min_io_size; | 49 | di->min_io_size = ubi->min_io_size; |
| 48 | di->ro_mode = ubi->ro_mode; | 50 | di->ro_mode = ubi->ro_mode; |
| 49 | di->cdev = MKDEV(ubi->major, 0); | 51 | di->cdev = ubi->cdev.dev; |
| 52 | |||
| 53 | ubi_put_device(ubi); | ||
| 50 | return 0; | 54 | return 0; |
| 51 | } | 55 | } |
| 52 | EXPORT_SYMBOL_GPL(ubi_get_device_info); | 56 | EXPORT_SYMBOL_GPL(ubi_get_device_info); |
| @@ -73,7 +77,7 @@ void ubi_get_volume_info(struct ubi_volume_desc *desc, | |||
| 73 | vi->usable_leb_size = vol->usable_leb_size; | 77 | vi->usable_leb_size = vol->usable_leb_size; |
| 74 | vi->name_len = vol->name_len; | 78 | vi->name_len = vol->name_len; |
| 75 | vi->name = vol->name; | 79 | vi->name = vol->name; |
| 76 | vi->cdev = MKDEV(ubi->major, vi->vol_id + 1); | 80 | vi->cdev = vol->cdev.dev; |
| 77 | } | 81 | } |
| 78 | EXPORT_SYMBOL_GPL(ubi_get_volume_info); | 82 | EXPORT_SYMBOL_GPL(ubi_get_volume_info); |
| 79 | 83 | ||
| @@ -104,37 +108,39 @@ struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode) | |||
| 104 | 108 | ||
| 105 | dbg_msg("open device %d volume %d, mode %d", ubi_num, vol_id, mode); | 109 | dbg_msg("open device %d volume %d, mode %d", ubi_num, vol_id, mode); |
| 106 | 110 | ||
| 107 | err = -ENODEV; | 111 | if (ubi_num < 0 || ubi_num >= UBI_MAX_DEVICES) |
| 108 | if (ubi_num < 0) | 112 | return ERR_PTR(-EINVAL); |
| 109 | return ERR_PTR(err); | ||
| 110 | |||
| 111 | ubi = ubi_devices[ubi_num]; | ||
| 112 | |||
| 113 | if (!try_module_get(THIS_MODULE)) | ||
| 114 | return ERR_PTR(err); | ||
| 115 | |||
| 116 | if (ubi_num >= UBI_MAX_DEVICES || !ubi) | ||
| 117 | goto out_put; | ||
| 118 | 113 | ||
| 119 | err = -EINVAL; | ||
| 120 | if (vol_id < 0 || vol_id >= ubi->vtbl_slots) | ||
| 121 | goto out_put; | ||
| 122 | if (mode != UBI_READONLY && mode != UBI_READWRITE && | 114 | if (mode != UBI_READONLY && mode != UBI_READWRITE && |
| 123 | mode != UBI_EXCLUSIVE) | 115 | mode != UBI_EXCLUSIVE) |
| 124 | goto out_put; | 116 | return ERR_PTR(-EINVAL); |
| 117 | |||
| 118 | /* | ||
| 119 | * First of all, we have to get the UBI device to prevent its removal. | ||
| 120 | */ | ||
| 121 | ubi = ubi_get_device(ubi_num); | ||
| 122 | if (!ubi) | ||
| 123 | return ERR_PTR(-ENODEV); | ||
| 124 | |||
| 125 | if (vol_id < 0 || vol_id >= ubi->vtbl_slots) { | ||
| 126 | err = -EINVAL; | ||
| 127 | goto out_put_ubi; | ||
| 128 | } | ||
| 125 | 129 | ||
| 126 | desc = kmalloc(sizeof(struct ubi_volume_desc), GFP_KERNEL); | 130 | desc = kmalloc(sizeof(struct ubi_volume_desc), GFP_KERNEL); |
| 127 | if (!desc) { | 131 | if (!desc) { |
| 128 | err = -ENOMEM; | 132 | err = -ENOMEM; |
| 129 | goto out_put; | 133 | goto out_put_ubi; |
| 130 | } | 134 | } |
| 131 | 135 | ||
| 136 | err = -ENODEV; | ||
| 137 | if (!try_module_get(THIS_MODULE)) | ||
| 138 | goto out_free; | ||
| 139 | |||
| 132 | spin_lock(&ubi->volumes_lock); | 140 | spin_lock(&ubi->volumes_lock); |
| 133 | vol = ubi->volumes[vol_id]; | 141 | vol = ubi->volumes[vol_id]; |
| 134 | if (!vol) { | 142 | if (!vol) |
| 135 | err = -ENODEV; | ||
| 136 | goto out_unlock; | 143 | goto out_unlock; |
| 137 | } | ||
| 138 | 144 | ||
| 139 | err = -EBUSY; | 145 | err = -EBUSY; |
| 140 | switch (mode) { | 146 | switch (mode) { |
| @@ -156,21 +162,19 @@ struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode) | |||
| 156 | vol->exclusive = 1; | 162 | vol->exclusive = 1; |
| 157 | break; | 163 | break; |
| 158 | } | 164 | } |
| 165 | get_device(&vol->dev); | ||
| 166 | vol->ref_count += 1; | ||
| 159 | spin_unlock(&ubi->volumes_lock); | 167 | spin_unlock(&ubi->volumes_lock); |
| 160 | 168 | ||
| 161 | desc->vol = vol; | 169 | desc->vol = vol; |
| 162 | desc->mode = mode; | 170 | desc->mode = mode; |
| 163 | 171 | ||
| 164 | /* | 172 | mutex_lock(&ubi->ckvol_mutex); |
| 165 | * To prevent simultaneous checks of the same volume we use @vtbl_mutex, | ||
| 166 | * although it is not the purpose it was introduced for. | ||
| 167 | */ | ||
| 168 | mutex_lock(&ubi->vtbl_mutex); | ||
| 169 | if (!vol->checked) { | 173 | if (!vol->checked) { |
| 170 | /* This is the first open - check the volume */ | 174 | /* This is the first open - check the volume */ |
| 171 | err = ubi_check_volume(ubi, vol_id); | 175 | err = ubi_check_volume(ubi, vol_id); |
| 172 | if (err < 0) { | 176 | if (err < 0) { |
| 173 | mutex_unlock(&ubi->vtbl_mutex); | 177 | mutex_unlock(&ubi->ckvol_mutex); |
| 174 | ubi_close_volume(desc); | 178 | ubi_close_volume(desc); |
| 175 | return ERR_PTR(err); | 179 | return ERR_PTR(err); |
| 176 | } | 180 | } |
| @@ -181,14 +185,17 @@ struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode) | |||
| 181 | } | 185 | } |
| 182 | vol->checked = 1; | 186 | vol->checked = 1; |
| 183 | } | 187 | } |
| 184 | mutex_unlock(&ubi->vtbl_mutex); | 188 | mutex_unlock(&ubi->ckvol_mutex); |
| 189 | |||
| 185 | return desc; | 190 | return desc; |
| 186 | 191 | ||
| 187 | out_unlock: | 192 | out_unlock: |
| 188 | spin_unlock(&ubi->volumes_lock); | 193 | spin_unlock(&ubi->volumes_lock); |
| 189 | kfree(desc); | ||
| 190 | out_put: | ||
| 191 | module_put(THIS_MODULE); | 194 | module_put(THIS_MODULE); |
| 195 | out_free: | ||
| 196 | kfree(desc); | ||
| 197 | out_put_ubi: | ||
| 198 | ubi_put_device(ubi); | ||
| 192 | return ERR_PTR(err); | 199 | return ERR_PTR(err); |
| 193 | } | 200 | } |
| 194 | EXPORT_SYMBOL_GPL(ubi_open_volume); | 201 | EXPORT_SYMBOL_GPL(ubi_open_volume); |
| @@ -205,8 +212,8 @@ struct ubi_volume_desc *ubi_open_volume_nm(int ubi_num, const char *name, | |||
| 205 | int mode) | 212 | int mode) |
| 206 | { | 213 | { |
| 207 | int i, vol_id = -1, len; | 214 | int i, vol_id = -1, len; |
| 208 | struct ubi_volume_desc *ret; | ||
| 209 | struct ubi_device *ubi; | 215 | struct ubi_device *ubi; |
| 216 | struct ubi_volume_desc *ret; | ||
| 210 | 217 | ||
| 211 | dbg_msg("open volume %s, mode %d", name, mode); | 218 | dbg_msg("open volume %s, mode %d", name, mode); |
| 212 | 219 | ||
| @@ -217,14 +224,12 @@ struct ubi_volume_desc *ubi_open_volume_nm(int ubi_num, const char *name, | |||
| 217 | if (len > UBI_VOL_NAME_MAX) | 224 | if (len > UBI_VOL_NAME_MAX) |
| 218 | return ERR_PTR(-EINVAL); | 225 | return ERR_PTR(-EINVAL); |
| 219 | 226 | ||
| 220 | ret = ERR_PTR(-ENODEV); | 227 | if (ubi_num < 0 || ubi_num >= UBI_MAX_DEVICES) |
| 221 | if (!try_module_get(THIS_MODULE)) | 228 | return ERR_PTR(-EINVAL); |
| 222 | return ret; | ||
| 223 | |||
| 224 | if (ubi_num < 0 || ubi_num >= UBI_MAX_DEVICES || !ubi_devices[ubi_num]) | ||
| 225 | goto out_put; | ||
| 226 | 229 | ||
| 227 | ubi = ubi_devices[ubi_num]; | 230 | ubi = ubi_get_device(ubi_num); |
| 231 | if (!ubi) | ||
| 232 | return ERR_PTR(-ENODEV); | ||
| 228 | 233 | ||
| 229 | spin_lock(&ubi->volumes_lock); | 234 | spin_lock(&ubi->volumes_lock); |
| 230 | /* Walk all volumes of this UBI device */ | 235 | /* Walk all volumes of this UBI device */ |
| @@ -238,13 +243,16 @@ struct ubi_volume_desc *ubi_open_volume_nm(int ubi_num, const char *name, | |||
| 238 | } | 243 | } |
| 239 | spin_unlock(&ubi->volumes_lock); | 244 | spin_unlock(&ubi->volumes_lock); |
| 240 | 245 | ||
| 241 | if (vol_id < 0) | 246 | if (vol_id >= 0) |
| 242 | goto out_put; | 247 | ret = ubi_open_volume(ubi_num, vol_id, mode); |
| 248 | else | ||
| 249 | ret = ERR_PTR(-ENODEV); | ||
| 243 | 250 | ||
| 244 | ret = ubi_open_volume(ubi_num, vol_id, mode); | 251 | /* |
| 245 | 252 | * We should put the UBI device even in case of success, because | |
| 246 | out_put: | 253 | * 'ubi_open_volume()' took a reference as well. |
| 247 | module_put(THIS_MODULE); | 254 | */ |
| 255 | ubi_put_device(ubi); | ||
| 248 | return ret; | 256 | return ret; |
| 249 | } | 257 | } |
| 250 | EXPORT_SYMBOL_GPL(ubi_open_volume_nm); | 258 | EXPORT_SYMBOL_GPL(ubi_open_volume_nm); |
| @@ -256,10 +264,11 @@ EXPORT_SYMBOL_GPL(ubi_open_volume_nm); | |||
| 256 | void ubi_close_volume(struct ubi_volume_desc *desc) | 264 | void ubi_close_volume(struct ubi_volume_desc *desc) |
| 257 | { | 265 | { |
| 258 | struct ubi_volume *vol = desc->vol; | 266 | struct ubi_volume *vol = desc->vol; |
| 267 | struct ubi_device *ubi = vol->ubi; | ||
| 259 | 268 | ||
| 260 | dbg_msg("close volume %d, mode %d", vol->vol_id, desc->mode); | 269 | dbg_msg("close volume %d, mode %d", vol->vol_id, desc->mode); |
| 261 | 270 | ||
| 262 | spin_lock(&vol->ubi->volumes_lock); | 271 | spin_lock(&ubi->volumes_lock); |
| 263 | switch (desc->mode) { | 272 | switch (desc->mode) { |
| 264 | case UBI_READONLY: | 273 | case UBI_READONLY: |
| 265 | vol->readers -= 1; | 274 | vol->readers -= 1; |
| @@ -270,9 +279,12 @@ void ubi_close_volume(struct ubi_volume_desc *desc) | |||
| 270 | case UBI_EXCLUSIVE: | 279 | case UBI_EXCLUSIVE: |
| 271 | vol->exclusive = 0; | 280 | vol->exclusive = 0; |
| 272 | } | 281 | } |
| 273 | spin_unlock(&vol->ubi->volumes_lock); | 282 | vol->ref_count -= 1; |
| 283 | spin_unlock(&ubi->volumes_lock); | ||
| 274 | 284 | ||
| 275 | kfree(desc); | 285 | kfree(desc); |
| 286 | put_device(&vol->dev); | ||
| 287 | ubi_put_device(ubi); | ||
| 276 | module_put(THIS_MODULE); | 288 | module_put(THIS_MODULE); |
| 277 | } | 289 | } |
| 278 | EXPORT_SYMBOL_GPL(ubi_close_volume); | 290 | EXPORT_SYMBOL_GPL(ubi_close_volume); |
| @@ -332,7 +344,7 @@ int ubi_leb_read(struct ubi_volume_desc *desc, int lnum, char *buf, int offset, | |||
| 332 | if (len == 0) | 344 | if (len == 0) |
| 333 | return 0; | 345 | return 0; |
| 334 | 346 | ||
| 335 | err = ubi_eba_read_leb(ubi, vol_id, lnum, buf, offset, len, check); | 347 | err = ubi_eba_read_leb(ubi, vol, lnum, buf, offset, len, check); |
| 336 | if (err && err == -EBADMSG && vol->vol_type == UBI_STATIC_VOLUME) { | 348 | if (err && err == -EBADMSG && vol->vol_type == UBI_STATIC_VOLUME) { |
| 337 | ubi_warn("mark volume %d as corrupted", vol_id); | 349 | ubi_warn("mark volume %d as corrupted", vol_id); |
| 338 | vol->corrupted = 1; | 350 | vol->corrupted = 1; |
| @@ -399,7 +411,7 @@ int ubi_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf, | |||
| 399 | if (len == 0) | 411 | if (len == 0) |
| 400 | return 0; | 412 | return 0; |
| 401 | 413 | ||
| 402 | return ubi_eba_write_leb(ubi, vol_id, lnum, buf, offset, len, dtype); | 414 | return ubi_eba_write_leb(ubi, vol, lnum, buf, offset, len, dtype); |
| 403 | } | 415 | } |
| 404 | EXPORT_SYMBOL_GPL(ubi_leb_write); | 416 | EXPORT_SYMBOL_GPL(ubi_leb_write); |
| 405 | 417 | ||
| @@ -448,7 +460,7 @@ int ubi_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf, | |||
| 448 | if (len == 0) | 460 | if (len == 0) |
| 449 | return 0; | 461 | return 0; |
| 450 | 462 | ||
| 451 | return ubi_eba_atomic_leb_change(ubi, vol_id, lnum, buf, len, dtype); | 463 | return ubi_eba_atomic_leb_change(ubi, vol, lnum, buf, len, dtype); |
| 452 | } | 464 | } |
| 453 | EXPORT_SYMBOL_GPL(ubi_leb_change); | 465 | EXPORT_SYMBOL_GPL(ubi_leb_change); |
| 454 | 466 | ||
| @@ -468,9 +480,9 @@ int ubi_leb_erase(struct ubi_volume_desc *desc, int lnum) | |||
| 468 | { | 480 | { |
| 469 | struct ubi_volume *vol = desc->vol; | 481 | struct ubi_volume *vol = desc->vol; |
| 470 | struct ubi_device *ubi = vol->ubi; | 482 | struct ubi_device *ubi = vol->ubi; |
| 471 | int err, vol_id = vol->vol_id; | 483 | int err; |
| 472 | 484 | ||
| 473 | dbg_msg("erase LEB %d:%d", vol_id, lnum); | 485 | dbg_msg("erase LEB %d:%d", vol->vol_id, lnum); |
| 474 | 486 | ||
| 475 | if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME) | 487 | if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME) |
| 476 | return -EROFS; | 488 | return -EROFS; |
| @@ -481,7 +493,7 @@ int ubi_leb_erase(struct ubi_volume_desc *desc, int lnum) | |||
| 481 | if (vol->upd_marker) | 493 | if (vol->upd_marker) |
| 482 | return -EBADF; | 494 | return -EBADF; |
| 483 | 495 | ||
| 484 | err = ubi_eba_unmap_leb(ubi, vol_id, lnum); | 496 | err = ubi_eba_unmap_leb(ubi, vol, lnum); |
| 485 | if (err) | 497 | if (err) |
| 486 | return err; | 498 | return err; |
| 487 | 499 | ||
| @@ -529,9 +541,8 @@ int ubi_leb_unmap(struct ubi_volume_desc *desc, int lnum) | |||
| 529 | { | 541 | { |
| 530 | struct ubi_volume *vol = desc->vol; | 542 | struct ubi_volume *vol = desc->vol; |
| 531 | struct ubi_device *ubi = vol->ubi; | 543 | struct ubi_device *ubi = vol->ubi; |
| 532 | int vol_id = vol->vol_id; | ||
| 533 | 544 | ||
| 534 | dbg_msg("unmap LEB %d:%d", vol_id, lnum); | 545 | dbg_msg("unmap LEB %d:%d", vol->vol_id, lnum); |
| 535 | 546 | ||
| 536 | if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME) | 547 | if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME) |
| 537 | return -EROFS; | 548 | return -EROFS; |
| @@ -542,11 +553,55 @@ int ubi_leb_unmap(struct ubi_volume_desc *desc, int lnum) | |||
| 542 | if (vol->upd_marker) | 553 | if (vol->upd_marker) |
| 543 | return -EBADF; | 554 | return -EBADF; |
| 544 | 555 | ||
| 545 | return ubi_eba_unmap_leb(ubi, vol_id, lnum); | 556 | return ubi_eba_unmap_leb(ubi, vol, lnum); |
| 546 | } | 557 | } |
| 547 | EXPORT_SYMBOL_GPL(ubi_leb_unmap); | 558 | EXPORT_SYMBOL_GPL(ubi_leb_unmap); |
| 548 | 559 | ||
| 549 | /** | 560 | /** |
| 561 | * ubi_leb_map - map logical erasblock to a physical eraseblock. | ||
| 562 | * @desc: volume descriptor | ||
| 563 | * @lnum: logical eraseblock number | ||
| 564 | * @dtype: expected data type | ||
| 565 | * | ||
| 566 | * This function maps an un-mapped logical eraseblock @lnum to a physical | ||
| 567 | * eraseblock. This means, that after a successfull invocation of this | ||
| 568 | * function the logical eraseblock @lnum will be empty (contain only %0xFF | ||
| 569 | * bytes) and be mapped to a physical eraseblock, even if an unclean reboot | ||
| 570 | * happens. | ||
| 571 | * | ||
| 572 | * This function returns zero in case of success, %-EBADF if the volume is | ||
| 573 | * damaged because of an interrupted update, %-EBADMSG if the logical | ||
| 574 | * eraseblock is already mapped, and other negative error codes in case of | ||
| 575 | * other failures. | ||
| 576 | */ | ||
| 577 | int ubi_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype) | ||
| 578 | { | ||
| 579 | struct ubi_volume *vol = desc->vol; | ||
| 580 | struct ubi_device *ubi = vol->ubi; | ||
| 581 | |||
| 582 | dbg_msg("unmap LEB %d:%d", vol->vol_id, lnum); | ||
| 583 | |||
| 584 | if (desc->mode == UBI_READONLY || vol->vol_type == UBI_STATIC_VOLUME) | ||
| 585 | return -EROFS; | ||
| 586 | |||
| 587 | if (lnum < 0 || lnum >= vol->reserved_pebs) | ||
| 588 | return -EINVAL; | ||
| 589 | |||
| 590 | if (dtype != UBI_LONGTERM && dtype != UBI_SHORTTERM && | ||
| 591 | dtype != UBI_UNKNOWN) | ||
| 592 | return -EINVAL; | ||
| 593 | |||
| 594 | if (vol->upd_marker) | ||
| 595 | return -EBADF; | ||
| 596 | |||
| 597 | if (vol->eba_tbl[lnum] >= 0) | ||
| 598 | return -EBADMSG; | ||
| 599 | |||
| 600 | return ubi_eba_write_leb(ubi, vol, lnum, NULL, 0, 0, dtype); | ||
| 601 | } | ||
| 602 | EXPORT_SYMBOL_GPL(ubi_leb_map); | ||
| 603 | |||
| 604 | /** | ||
| 550 | * ubi_is_mapped - check if logical eraseblock is mapped. | 605 | * ubi_is_mapped - check if logical eraseblock is mapped. |
| 551 | * @desc: volume descriptor | 606 | * @desc: volume descriptor |
| 552 | * @lnum: logical eraseblock number | 607 | * @lnum: logical eraseblock number |
