diff options
Diffstat (limited to 'drivers/mtd/rfd_ftl.c')
| -rw-r--r-- | drivers/mtd/rfd_ftl.c | 69 |
1 files changed, 43 insertions, 26 deletions
diff --git a/drivers/mtd/rfd_ftl.c b/drivers/mtd/rfd_ftl.c index 94720f2ca9a8..be26cc67a1c4 100644 --- a/drivers/mtd/rfd_ftl.c +++ b/drivers/mtd/rfd_ftl.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * rfd_ftl.c -- resident flash disk (flash translation layer) * @@ -189,13 +190,10 @@ static int scan_header(struct partition *part) if (!part->blocks) goto err; - part->sector_map = vmalloc(array_size(sizeof(u_long), - part->sector_count)); - if (!part->sector_map) { - printk(KERN_ERR PREFIX "'%s': unable to allocate memory for " - "sector map", part->mbd.mtd->name); + part->sector_map = vmalloc_array(part->sector_count, + sizeof(u_long)); + if (!part->sector_map) goto err; - } for (i=0; i<part->sector_count; i++) part->sector_map[i] = -1; @@ -241,7 +239,7 @@ err: static int rfd_ftl_readsect(struct mtd_blktrans_dev *dev, u_long sector, char *buf) { - struct partition *part = (struct partition*)dev; + struct partition *part = container_of(dev, struct partition, mbd); u_long addr; size_t retlen; int rc; @@ -602,7 +600,7 @@ static int find_free_sector(const struct partition *part, const struct block *bl static int do_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf, ulong *old_addr) { - struct partition *part = (struct partition*)dev; + struct partition *part = container_of(dev, struct partition, mbd); struct block *block; u_long addr; int i; @@ -668,7 +666,7 @@ err: static int rfd_ftl_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf) { - struct partition *part = (struct partition*)dev; + struct partition *part = container_of(dev, struct partition, mbd); u_long old_addr; int i; int rc = 0; @@ -707,9 +705,37 @@ err: return rc; } +static int rfd_ftl_discardsect(struct mtd_blktrans_dev *dev, + unsigned long sector, unsigned int nr_sects) +{ + struct partition *part = container_of(dev, struct partition, mbd); + u_long addr; + int rc; + + while (nr_sects) { + if (sector >= part->sector_count) + return -EIO; + + addr = part->sector_map[sector]; + + if (addr != -1) { + rc = mark_sector_deleted(part, addr); + if (rc) + return rc; + + part->sector_map[sector] = -1; + } + + sector++; + nr_sects--; + } + + return 0; +} + static int rfd_ftl_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo) { - struct partition *part = (struct partition*)dev; + struct partition *part = container_of(dev, struct partition, mbd); geo->heads = 1; geo->sectors = SECTORS_PER_TRACK; @@ -722,7 +748,8 @@ static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) { struct partition *part; - if (mtd->type != MTD_NORFLASH || mtd->size > UINT_MAX) + if ((mtd->type != MTD_NORFLASH && mtd->type != MTD_RAM) || + mtd->size > UINT_MAX) return; part = kzalloc(sizeof(struct partition), GFP_KERNEL); @@ -756,7 +783,7 @@ static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) printk(KERN_INFO PREFIX "name: '%s' type: %d flags %x\n", mtd->name, mtd->type, mtd->flags); - if (!add_mtd_blktrans_dev((void*)part)) + if (!add_mtd_blktrans_dev(&part->mbd)) return; } out: @@ -765,7 +792,7 @@ out: static void rfd_ftl_remove_dev(struct mtd_blktrans_dev *dev) { - struct partition *part = (struct partition*)dev; + struct partition *part = container_of(dev, struct partition, mbd); int i; for (i=0; i<part->total_blocks; i++) { @@ -773,10 +800,10 @@ static void rfd_ftl_remove_dev(struct mtd_blktrans_dev *dev) part->mbd.mtd->name, i, part->blocks[i].erases); } - del_mtd_blktrans_dev(dev); vfree(part->sector_map); kfree(part->header_cache); kfree(part->blocks); + del_mtd_blktrans_dev(&part->mbd); } static struct mtd_blktrans_ops rfd_ftl_tr = { @@ -787,24 +814,14 @@ static struct mtd_blktrans_ops rfd_ftl_tr = { .readsect = rfd_ftl_readsect, .writesect = rfd_ftl_writesect, + .discard = rfd_ftl_discardsect, .getgeo = rfd_ftl_getgeo, .add_mtd = rfd_ftl_add_mtd, .remove_dev = rfd_ftl_remove_dev, .owner = THIS_MODULE, }; -static int __init init_rfd_ftl(void) -{ - return register_mtd_blktrans(&rfd_ftl_tr); -} - -static void __exit cleanup_rfd_ftl(void) -{ - deregister_mtd_blktrans(&rfd_ftl_tr); -} - -module_init(init_rfd_ftl); -module_exit(cleanup_rfd_ftl); +module_mtd_blktrans(rfd_ftl_tr); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Sean Young <sean@mess.org>"); |
