diff options
Diffstat (limited to 'drivers/memstick/core/ms_block.c')
| -rw-r--r-- | drivers/memstick/core/ms_block.c | 128 |
1 files changed, 52 insertions, 76 deletions
diff --git a/drivers/memstick/core/ms_block.c b/drivers/memstick/core/ms_block.c index 4a4573fa7b0f..1af157ce0a63 100644 --- a/drivers/memstick/core/ms_block.c +++ b/drivers/memstick/core/ms_block.c @@ -996,7 +996,7 @@ static int msb_verify_block(struct msb_data *msb, u16 pba, return 0; } -/* Writes exectly one block + oob */ +/* Writes exactly one block + oob */ static int msb_write_block(struct msb_data *msb, u16 pba, u32 lba, struct scatterlist *sg, int offset) { @@ -1105,7 +1105,7 @@ static u16 msb_get_free_block(struct msb_data *msb, int zone) dbg_verbose("result of the free blocks scan: pba %d", pba); if (pba == msb->block_count || (msb_get_zone_from_pba(pba)) != zone) { - pr_err("BUG: cant get a free block"); + pr_err("BUG: can't get a free block"); msb->read_only = true; return MS_BLOCK_INVALID; } @@ -1341,17 +1341,17 @@ static int msb_ftl_initialize(struct msb_data *msb) msb->zone_count = msb->block_count / MS_BLOCKS_IN_ZONE; msb->logical_block_count = msb->zone_count * 496 - 2; - msb->used_blocks_bitmap = kzalloc(msb->block_count / 8, GFP_KERNEL); - msb->erased_blocks_bitmap = kzalloc(msb->block_count / 8, GFP_KERNEL); + msb->used_blocks_bitmap = bitmap_zalloc(msb->block_count, GFP_KERNEL); + msb->erased_blocks_bitmap = bitmap_zalloc(msb->block_count, GFP_KERNEL); msb->lba_to_pba_table = kmalloc_array(msb->logical_block_count, sizeof(u16), GFP_KERNEL); if (!msb->used_blocks_bitmap || !msb->lba_to_pba_table || !msb->erased_blocks_bitmap) { - kfree(msb->used_blocks_bitmap); + bitmap_free(msb->used_blocks_bitmap); + bitmap_free(msb->erased_blocks_bitmap); kfree(msb->lba_to_pba_table); - kfree(msb->erased_blocks_bitmap); return -ENOMEM; } @@ -1498,7 +1498,7 @@ static int msb_ftl_scan(struct msb_data *msb) static void msb_cache_flush_timer(struct timer_list *t) { - struct msb_data *msb = from_timer(msb, t, cache_flush_timer); + struct msb_data *msb = timer_container_of(msb, t, cache_flush_timer); msb->need_flush_cache = true; queue_work(msb->io_queue, &msb->io_work); @@ -1510,7 +1510,7 @@ static void msb_cache_discard(struct msb_data *msb) if (msb->cache_block_lba == MS_BLOCK_INVALID) return; - del_timer_sync(&msb->cache_flush_timer); + timer_delete_sync(&msb->cache_flush_timer); dbg_verbose("Discarding the write cache"); msb->cache_block_lba = MS_BLOCK_INVALID; @@ -1684,7 +1684,7 @@ static int msb_cache_read(struct msb_data *msb, int lba, */ static const struct chs_entry chs_table[] = { -/* size sectors cylynders heads */ +/* size sectors cylinders heads */ { 4, 16, 247, 2 }, { 8, 16, 495, 2 }, { 16, 16, 495, 4 }, @@ -1729,14 +1729,14 @@ static int msb_init_card(struct memstick_dev *card) boot_block = &msb->boot_page[0]; - /* Save intersting attributes from boot page */ + /* Save interesting attributes from boot page */ msb->block_count = boot_block->attr.number_of_blocks; msb->page_size = boot_block->attr.page_size; msb->pages_in_block = boot_block->attr.block_size * 2; msb->block_size = msb->page_size * msb->pages_in_block; - if (msb->page_size > PAGE_SIZE) { + if ((size_t)msb->page_size > PAGE_SIZE) { /* this isn't supported by linux at all, anyway*/ dbg("device page %d size isn't supported", msb->page_size); return -EINVAL; @@ -1904,7 +1904,7 @@ static void msb_io_work(struct work_struct *work) /* process the request */ dbg_verbose("IO: processing new request"); - blk_rq_map_sg(msb->queue, req, sg); + blk_rq_map_sg(req, sg); lba = blk_rq_pos(req); @@ -1943,64 +1943,33 @@ static void msb_io_work(struct work_struct *work) static DEFINE_IDR(msb_disk_idr); /*set of used disk numbers */ static DEFINE_MUTEX(msb_disk_lock); /* protects against races in open/release */ -static int msb_bd_open(struct block_device *bdev, fmode_t mode) -{ - struct gendisk *disk = bdev->bd_disk; - struct msb_data *msb = disk->private_data; - - dbg_verbose("block device open"); - - mutex_lock(&msb_disk_lock); - - if (msb && msb->card) - msb->usage_count++; - - mutex_unlock(&msb_disk_lock); - return 0; -} - static void msb_data_clear(struct msb_data *msb) { kfree(msb->boot_page); - kfree(msb->used_blocks_bitmap); + bitmap_free(msb->used_blocks_bitmap); + bitmap_free(msb->erased_blocks_bitmap); kfree(msb->lba_to_pba_table); kfree(msb->cache); msb->card = NULL; } -static int msb_disk_release(struct gendisk *disk) +static int msb_bd_getgeo(struct gendisk *disk, + struct hd_geometry *geo) { struct msb_data *msb = disk->private_data; - - dbg_verbose("block device release"); - mutex_lock(&msb_disk_lock); - - if (msb) { - if (msb->usage_count) - msb->usage_count--; - - if (!msb->usage_count) { - disk->private_data = NULL; - idr_remove(&msb_disk_idr, msb->disk_id); - put_disk(disk); - kfree(msb); - } - } - mutex_unlock(&msb_disk_lock); + *geo = msb->geometry; return 0; } -static void msb_bd_release(struct gendisk *disk, fmode_t mode) +static void msb_bd_free_disk(struct gendisk *disk) { - msb_disk_release(disk); -} + struct msb_data *msb = disk->private_data; -static int msb_bd_getgeo(struct block_device *bdev, - struct hd_geometry *geo) -{ - struct msb_data *msb = bdev->bd_disk->private_data; - *geo = msb->geometry; - return 0; + mutex_lock(&msb_disk_lock); + idr_remove(&msb_disk_idr, msb->disk_id); + mutex_unlock(&msb_disk_lock); + + kfree(msb); } static blk_status_t msb_queue_rq(struct blk_mq_hw_ctx *hctx, @@ -2058,7 +2027,7 @@ static void msb_stop(struct memstick_dev *card) msb->io_queue_stopped = true; spin_unlock_irqrestore(&msb->q_lock, flags); - del_timer_sync(&msb->cache_flush_timer); + timer_delete_sync(&msb->cache_flush_timer); flush_workqueue(msb->io_queue); spin_lock_irqsave(&msb->q_lock, flags); @@ -2096,10 +2065,9 @@ static void msb_start(struct memstick_dev *card) } static const struct block_device_operations msb_bdops = { - .open = msb_bd_open, - .release = msb_bd_release, - .getgeo = msb_bd_getgeo, - .owner = THIS_MODULE + .owner = THIS_MODULE, + .getgeo = msb_bd_getgeo, + .free_disk = msb_bd_free_disk, }; static const struct blk_mq_ops msb_mq_ops = { @@ -2110,6 +2078,12 @@ static const struct blk_mq_ops msb_mq_ops = { static int msb_init_disk(struct memstick_dev *card) { struct msb_data *msb = memstick_get_drvdata(card); + struct queue_limits lim = { + .logical_block_size = msb->page_size, + .max_hw_sectors = MS_BLOCK_MAX_PAGES, + .max_segments = MS_BLOCK_MAX_SEGS, + .max_segment_size = MS_BLOCK_MAX_PAGES * msb->page_size, + }; int rc; unsigned long capacity; @@ -2120,24 +2094,17 @@ static int msb_init_disk(struct memstick_dev *card) if (msb->disk_id < 0) return msb->disk_id; - rc = blk_mq_alloc_sq_tag_set(&msb->tag_set, &msb_mq_ops, 2, - BLK_MQ_F_SHOULD_MERGE); + rc = blk_mq_alloc_sq_tag_set(&msb->tag_set, &msb_mq_ops, 2, 0); if (rc) goto out_release_id; - msb->disk = blk_mq_alloc_disk(&msb->tag_set, card); + msb->disk = blk_mq_alloc_disk(&msb->tag_set, &lim, card); if (IS_ERR(msb->disk)) { rc = PTR_ERR(msb->disk); goto out_free_tag_set; } msb->queue = msb->disk->queue; - blk_queue_max_hw_sectors(msb->queue, MS_BLOCK_MAX_PAGES); - blk_queue_max_segments(msb->queue, MS_BLOCK_MAX_SEGS); - blk_queue_max_segment_size(msb->queue, - MS_BLOCK_MAX_PAGES * msb->page_size); - blk_queue_logical_block_size(msb->queue, msb->page_size); - sprintf(msb->disk->disk_name, "msblk%d", msb->disk_id); msb->disk->fops = &msb_bdops; msb->disk->private_data = msb; @@ -2147,8 +2114,12 @@ static int msb_init_disk(struct memstick_dev *card) set_capacity(msb->disk, capacity); dbg("Set total disk size to %lu sectors", capacity); - msb->usage_count = 1; msb->io_queue = alloc_ordered_workqueue("ms_block", WQ_MEM_RECLAIM); + if (!msb->io_queue) { + rc = -ENOMEM; + goto out_cleanup_disk; + } + INIT_WORK(&msb->io_work, msb_io_work); sg_init_table(msb->prealloc_sg, MS_BLOCK_MAX_SEGS+1); @@ -2156,10 +2127,16 @@ static int msb_init_disk(struct memstick_dev *card) set_disk_ro(msb->disk, 1); msb_start(card); - device_add_disk(&card->dev, msb->disk, NULL); + rc = device_add_disk(&card->dev, msb->disk, NULL); + if (rc) + goto out_destroy_workqueue; dbg("Disk added"); return 0; +out_destroy_workqueue: + destroy_workqueue(msb->io_queue); +out_cleanup_disk: + put_disk(msb->disk); out_free_tag_set: blk_mq_free_tag_set(&msb->tag_set); out_release_id: @@ -2217,7 +2194,6 @@ static void msb_remove(struct memstick_dev *card) /* Remove the disk */ del_gendisk(msb->disk); - blk_cleanup_queue(msb->queue); blk_mq_free_tag_set(&msb->tag_set); msb->queue = NULL; @@ -2225,7 +2201,7 @@ static void msb_remove(struct memstick_dev *card) msb_data_clear(msb); mutex_unlock(&msb_disk_lock); - msb_disk_release(msb->disk); + put_disk(msb->disk); memstick_set_drvdata(card, NULL); } @@ -2274,8 +2250,8 @@ static int msb_resume(struct memstick_dev *card) goto out; if (msb->block_count != new_msb->block_count || - memcmp(msb->used_blocks_bitmap, new_msb->used_blocks_bitmap, - msb->block_count / 8)) + !bitmap_equal(msb->used_blocks_bitmap, new_msb->used_blocks_bitmap, + msb->block_count)) goto out; card_dead = false; @@ -2302,7 +2278,7 @@ out: #endif /* CONFIG_PM */ -static struct memstick_device_id msb_id_tbl[] = { +static const struct memstick_device_id msb_id_tbl[] = { {MEMSTICK_MATCH_ALL, MEMSTICK_TYPE_LEGACY, MEMSTICK_CATEGORY_STORAGE, MEMSTICK_CLASS_FLASH}, |
