| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * ms_block.c - Sony MemoryStick (legacy) storage support |
|---|
| 3 | 4 | |
|---|
| 4 | 5 | * Copyright (C) 2013 Maxim Levitsky <maximlevitsky@gmail.com> |
|---|
| 5 | 6 | * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 7 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 8 | | - * published by the Free Software Foundation. |
|---|
| 9 | | - * |
|---|
| 10 | 7 | * Minor portions of the driver were copied from mspro_block.c which is |
|---|
| 11 | 8 | * Copyright (C) 2007 Alex Dubov <oakad@yahoo.com> |
|---|
| 12 | | - * |
|---|
| 13 | 9 | */ |
|---|
| 14 | 10 | #define DRIVER_NAME "ms_block" |
|---|
| 15 | 11 | #define pr_fmt(fmt) DRIVER_NAME ": " fmt |
|---|
| 16 | 12 | |
|---|
| 17 | 13 | #include <linux/module.h> |
|---|
| 18 | | -#include <linux/blkdev.h> |
|---|
| 14 | +#include <linux/blk-mq.h> |
|---|
| 19 | 15 | #include <linux/memstick.h> |
|---|
| 20 | 16 | #include <linux/idr.h> |
|---|
| 21 | 17 | #include <linux/hdreg.h> |
|---|
| .. | .. |
|---|
| 375 | 371 | serial mode), then just fall through */ |
|---|
| 376 | 372 | if (msb_read_int_reg(msb, -1)) |
|---|
| 377 | 373 | return 0; |
|---|
| 378 | | - /* fallthrough */ |
|---|
| 374 | + fallthrough; |
|---|
| 379 | 375 | |
|---|
| 380 | 376 | case MSB_RP_RECEIVE_INT_REQ_RESULT: |
|---|
| 381 | 377 | intreg = mrq->data[0]; |
|---|
| .. | .. |
|---|
| 407 | 403 | case MSB_RP_RECEIVE_STATUS_REG: |
|---|
| 408 | 404 | msb->regs.status = *(struct ms_status_register *)mrq->data; |
|---|
| 409 | 405 | msb->state = MSB_RP_SEND_OOB_READ; |
|---|
| 410 | | - /* fallthrough */ |
|---|
| 406 | + fallthrough; |
|---|
| 411 | 407 | |
|---|
| 412 | 408 | case MSB_RP_SEND_OOB_READ: |
|---|
| 413 | 409 | if (!msb_read_regs(msb, |
|---|
| .. | .. |
|---|
| 422 | 418 | msb->regs.extra_data = |
|---|
| 423 | 419 | *(struct ms_extra_data_register *) mrq->data; |
|---|
| 424 | 420 | msb->state = MSB_RP_SEND_READ_DATA; |
|---|
| 425 | | - /* fallthrough */ |
|---|
| 421 | + fallthrough; |
|---|
| 426 | 422 | |
|---|
| 427 | 423 | case MSB_RP_SEND_READ_DATA: |
|---|
| 428 | 424 | /* Skip that state if we only read the oob */ |
|---|
| .. | .. |
|---|
| 522 | 518 | msb->state = MSB_WB_RECEIVE_INT_REQ; |
|---|
| 523 | 519 | if (msb_read_int_reg(msb, -1)) |
|---|
| 524 | 520 | return 0; |
|---|
| 525 | | - /* fallthrough */ |
|---|
| 521 | + fallthrough; |
|---|
| 526 | 522 | |
|---|
| 527 | 523 | case MSB_WB_RECEIVE_INT_REQ: |
|---|
| 528 | 524 | intreg = mrq->data[0]; |
|---|
| .. | .. |
|---|
| 553 | 549 | |
|---|
| 554 | 550 | msb->int_polling = false; |
|---|
| 555 | 551 | msb->state = MSB_WB_SEND_WRITE_DATA; |
|---|
| 556 | | - /* fallthrough */ |
|---|
| 552 | + fallthrough; |
|---|
| 557 | 553 | |
|---|
| 558 | 554 | case MSB_WB_SEND_WRITE_DATA: |
|---|
| 559 | 555 | sg_init_table(sg, ARRAY_SIZE(sg)); |
|---|
| .. | .. |
|---|
| 632 | 628 | msb->state = MSB_SC_RECEIVE_INT_REQ; |
|---|
| 633 | 629 | if (msb_read_int_reg(msb, -1)) |
|---|
| 634 | 630 | return 0; |
|---|
| 635 | | - /* fallthrough */ |
|---|
| 631 | + fallthrough; |
|---|
| 636 | 632 | |
|---|
| 637 | 633 | case MSB_SC_RECEIVE_INT_REQ: |
|---|
| 638 | 634 | intreg = mrq->data[0]; |
|---|
| .. | .. |
|---|
| 1091 | 1087 | |
|---|
| 1092 | 1088 | pos %= msb->free_block_count[zone]; |
|---|
| 1093 | 1089 | |
|---|
| 1094 | | - dbg_verbose("have %d choices for a free block, selected randomally: %d", |
|---|
| 1090 | + dbg_verbose("have %d choices for a free block, selected randomly: %d", |
|---|
| 1095 | 1091 | msb->free_block_count[zone], pos); |
|---|
| 1096 | 1092 | |
|---|
| 1097 | 1093 | pba = find_next_zero_bit(msb->used_blocks_bitmap, |
|---|
| .. | .. |
|---|
| 1227 | 1223 | } |
|---|
| 1228 | 1224 | |
|---|
| 1229 | 1225 | if (be16_to_cpu(page->header.block_id) != MS_BLOCK_BOOT_ID) { |
|---|
| 1230 | | - dbg("the pba at %d doesn' contain boot block ID", pba); |
|---|
| 1226 | + dbg("the pba at %d doesn't contain boot block ID", pba); |
|---|
| 1231 | 1227 | continue; |
|---|
| 1232 | 1228 | } |
|---|
| 1233 | 1229 | |
|---|
| .. | .. |
|---|
| 1339 | 1335 | msb->zone_count = msb->block_count / MS_BLOCKS_IN_ZONE; |
|---|
| 1340 | 1336 | msb->logical_block_count = msb->zone_count * 496 - 2; |
|---|
| 1341 | 1337 | |
|---|
| 1342 | | - msb->used_blocks_bitmap = kzalloc(msb->block_count / 8, GFP_KERNEL); |
|---|
| 1343 | | - msb->erased_blocks_bitmap = kzalloc(msb->block_count / 8, GFP_KERNEL); |
|---|
| 1338 | + msb->used_blocks_bitmap = bitmap_zalloc(msb->block_count, GFP_KERNEL); |
|---|
| 1339 | + msb->erased_blocks_bitmap = bitmap_zalloc(msb->block_count, GFP_KERNEL); |
|---|
| 1344 | 1340 | msb->lba_to_pba_table = |
|---|
| 1345 | 1341 | kmalloc_array(msb->logical_block_count, sizeof(u16), |
|---|
| 1346 | 1342 | GFP_KERNEL); |
|---|
| 1347 | 1343 | |
|---|
| 1348 | 1344 | if (!msb->used_blocks_bitmap || !msb->lba_to_pba_table || |
|---|
| 1349 | 1345 | !msb->erased_blocks_bitmap) { |
|---|
| 1350 | | - kfree(msb->used_blocks_bitmap); |
|---|
| 1346 | + bitmap_free(msb->used_blocks_bitmap); |
|---|
| 1347 | + bitmap_free(msb->erased_blocks_bitmap); |
|---|
| 1351 | 1348 | kfree(msb->lba_to_pba_table); |
|---|
| 1352 | | - kfree(msb->erased_blocks_bitmap); |
|---|
| 1353 | 1349 | return -ENOMEM; |
|---|
| 1354 | 1350 | } |
|---|
| 1355 | 1351 | |
|---|
| .. | .. |
|---|
| 1873 | 1869 | struct msb_data *msb = container_of(work, struct msb_data, io_work); |
|---|
| 1874 | 1870 | int page, error, len; |
|---|
| 1875 | 1871 | sector_t lba; |
|---|
| 1876 | | - unsigned long flags; |
|---|
| 1877 | 1872 | struct scatterlist *sg = msb->prealloc_sg; |
|---|
| 1873 | + struct request *req; |
|---|
| 1878 | 1874 | |
|---|
| 1879 | 1875 | dbg_verbose("IO: work started"); |
|---|
| 1880 | 1876 | |
|---|
| 1881 | 1877 | while (1) { |
|---|
| 1882 | | - spin_lock_irqsave(&msb->q_lock, flags); |
|---|
| 1878 | + spin_lock_irq(&msb->q_lock); |
|---|
| 1883 | 1879 | |
|---|
| 1884 | 1880 | if (msb->need_flush_cache) { |
|---|
| 1885 | 1881 | msb->need_flush_cache = false; |
|---|
| 1886 | | - spin_unlock_irqrestore(&msb->q_lock, flags); |
|---|
| 1882 | + spin_unlock_irq(&msb->q_lock); |
|---|
| 1887 | 1883 | msb_cache_flush(msb); |
|---|
| 1888 | 1884 | continue; |
|---|
| 1889 | 1885 | } |
|---|
| 1890 | 1886 | |
|---|
| 1891 | | - if (!msb->req) { |
|---|
| 1892 | | - msb->req = blk_fetch_request(msb->queue); |
|---|
| 1893 | | - if (!msb->req) { |
|---|
| 1894 | | - dbg_verbose("IO: no more requests exiting"); |
|---|
| 1895 | | - spin_unlock_irqrestore(&msb->q_lock, flags); |
|---|
| 1896 | | - return; |
|---|
| 1897 | | - } |
|---|
| 1887 | + req = msb->req; |
|---|
| 1888 | + if (!req) { |
|---|
| 1889 | + dbg_verbose("IO: no more requests exiting"); |
|---|
| 1890 | + spin_unlock_irq(&msb->q_lock); |
|---|
| 1891 | + return; |
|---|
| 1898 | 1892 | } |
|---|
| 1899 | 1893 | |
|---|
| 1900 | | - spin_unlock_irqrestore(&msb->q_lock, flags); |
|---|
| 1901 | | - |
|---|
| 1902 | | - /* If card was removed meanwhile */ |
|---|
| 1903 | | - if (!msb->req) |
|---|
| 1904 | | - return; |
|---|
| 1894 | + spin_unlock_irq(&msb->q_lock); |
|---|
| 1905 | 1895 | |
|---|
| 1906 | 1896 | /* process the request */ |
|---|
| 1907 | 1897 | dbg_verbose("IO: processing new request"); |
|---|
| 1908 | | - blk_rq_map_sg(msb->queue, msb->req, sg); |
|---|
| 1898 | + blk_rq_map_sg(msb->queue, req, sg); |
|---|
| 1909 | 1899 | |
|---|
| 1910 | | - lba = blk_rq_pos(msb->req); |
|---|
| 1900 | + lba = blk_rq_pos(req); |
|---|
| 1911 | 1901 | |
|---|
| 1912 | 1902 | sector_div(lba, msb->page_size / 512); |
|---|
| 1913 | 1903 | page = sector_div(lba, msb->pages_in_block); |
|---|
| 1914 | 1904 | |
|---|
| 1915 | 1905 | if (rq_data_dir(msb->req) == READ) |
|---|
| 1916 | 1906 | error = msb_do_read_request(msb, lba, page, sg, |
|---|
| 1917 | | - blk_rq_bytes(msb->req), &len); |
|---|
| 1907 | + blk_rq_bytes(req), &len); |
|---|
| 1918 | 1908 | else |
|---|
| 1919 | 1909 | error = msb_do_write_request(msb, lba, page, sg, |
|---|
| 1920 | | - blk_rq_bytes(msb->req), &len); |
|---|
| 1910 | + blk_rq_bytes(req), &len); |
|---|
| 1921 | 1911 | |
|---|
| 1922 | | - spin_lock_irqsave(&msb->q_lock, flags); |
|---|
| 1923 | | - |
|---|
| 1924 | | - if (len) |
|---|
| 1925 | | - if (!__blk_end_request(msb->req, BLK_STS_OK, len)) |
|---|
| 1926 | | - msb->req = NULL; |
|---|
| 1912 | + if (len && !blk_update_request(req, BLK_STS_OK, len)) { |
|---|
| 1913 | + __blk_mq_end_request(req, BLK_STS_OK); |
|---|
| 1914 | + spin_lock_irq(&msb->q_lock); |
|---|
| 1915 | + msb->req = NULL; |
|---|
| 1916 | + spin_unlock_irq(&msb->q_lock); |
|---|
| 1917 | + } |
|---|
| 1927 | 1918 | |
|---|
| 1928 | 1919 | if (error && msb->req) { |
|---|
| 1929 | 1920 | blk_status_t ret = errno_to_blk_status(error); |
|---|
| 1921 | + |
|---|
| 1930 | 1922 | dbg_verbose("IO: ending one sector of the request with error"); |
|---|
| 1931 | | - if (!__blk_end_request(msb->req, ret, msb->page_size)) |
|---|
| 1932 | | - msb->req = NULL; |
|---|
| 1923 | + blk_mq_end_request(req, ret); |
|---|
| 1924 | + spin_lock_irq(&msb->q_lock); |
|---|
| 1925 | + msb->req = NULL; |
|---|
| 1926 | + spin_unlock_irq(&msb->q_lock); |
|---|
| 1933 | 1927 | } |
|---|
| 1934 | 1928 | |
|---|
| 1935 | 1929 | if (msb->req) |
|---|
| 1936 | 1930 | dbg_verbose("IO: request still pending"); |
|---|
| 1937 | | - |
|---|
| 1938 | | - spin_unlock_irqrestore(&msb->q_lock, flags); |
|---|
| 1939 | 1931 | } |
|---|
| 1940 | 1932 | } |
|---|
| 1941 | 1933 | |
|---|
| .. | .. |
|---|
| 1961 | 1953 | static void msb_data_clear(struct msb_data *msb) |
|---|
| 1962 | 1954 | { |
|---|
| 1963 | 1955 | kfree(msb->boot_page); |
|---|
| 1964 | | - kfree(msb->used_blocks_bitmap); |
|---|
| 1956 | + bitmap_free(msb->used_blocks_bitmap); |
|---|
| 1957 | + bitmap_free(msb->erased_blocks_bitmap); |
|---|
| 1965 | 1958 | kfree(msb->lba_to_pba_table); |
|---|
| 1966 | 1959 | kfree(msb->cache); |
|---|
| 1967 | 1960 | msb->card = NULL; |
|---|
| .. | .. |
|---|
| 2002 | 1995 | return 0; |
|---|
| 2003 | 1996 | } |
|---|
| 2004 | 1997 | |
|---|
| 2005 | | -static void msb_submit_req(struct request_queue *q) |
|---|
| 1998 | +static blk_status_t msb_queue_rq(struct blk_mq_hw_ctx *hctx, |
|---|
| 1999 | + const struct blk_mq_queue_data *bd) |
|---|
| 2006 | 2000 | { |
|---|
| 2007 | | - struct memstick_dev *card = q->queuedata; |
|---|
| 2001 | + struct memstick_dev *card = hctx->queue->queuedata; |
|---|
| 2008 | 2002 | struct msb_data *msb = memstick_get_drvdata(card); |
|---|
| 2009 | | - struct request *req = NULL; |
|---|
| 2003 | + struct request *req = bd->rq; |
|---|
| 2010 | 2004 | |
|---|
| 2011 | 2005 | dbg_verbose("Submit request"); |
|---|
| 2006 | + |
|---|
| 2007 | + spin_lock_irq(&msb->q_lock); |
|---|
| 2012 | 2008 | |
|---|
| 2013 | 2009 | if (msb->card_dead) { |
|---|
| 2014 | 2010 | dbg("Refusing requests on removed card"); |
|---|
| 2015 | 2011 | |
|---|
| 2016 | 2012 | WARN_ON(!msb->io_queue_stopped); |
|---|
| 2017 | 2013 | |
|---|
| 2018 | | - while ((req = blk_fetch_request(q)) != NULL) |
|---|
| 2019 | | - __blk_end_request_all(req, BLK_STS_IOERR); |
|---|
| 2020 | | - return; |
|---|
| 2014 | + spin_unlock_irq(&msb->q_lock); |
|---|
| 2015 | + blk_mq_start_request(req); |
|---|
| 2016 | + return BLK_STS_IOERR; |
|---|
| 2021 | 2017 | } |
|---|
| 2022 | 2018 | |
|---|
| 2023 | | - if (msb->req) |
|---|
| 2024 | | - return; |
|---|
| 2019 | + if (msb->req) { |
|---|
| 2020 | + spin_unlock_irq(&msb->q_lock); |
|---|
| 2021 | + return BLK_STS_DEV_RESOURCE; |
|---|
| 2022 | + } |
|---|
| 2023 | + |
|---|
| 2024 | + blk_mq_start_request(req); |
|---|
| 2025 | + msb->req = req; |
|---|
| 2025 | 2026 | |
|---|
| 2026 | 2027 | if (!msb->io_queue_stopped) |
|---|
| 2027 | 2028 | queue_work(msb->io_queue, &msb->io_work); |
|---|
| 2029 | + |
|---|
| 2030 | + spin_unlock_irq(&msb->q_lock); |
|---|
| 2031 | + return BLK_STS_OK; |
|---|
| 2028 | 2032 | } |
|---|
| 2029 | 2033 | |
|---|
| 2030 | 2034 | static int msb_check_card(struct memstick_dev *card) |
|---|
| .. | .. |
|---|
| 2040 | 2044 | |
|---|
| 2041 | 2045 | dbg("Stopping all msblock IO"); |
|---|
| 2042 | 2046 | |
|---|
| 2047 | + blk_mq_stop_hw_queues(msb->queue); |
|---|
| 2043 | 2048 | spin_lock_irqsave(&msb->q_lock, flags); |
|---|
| 2044 | | - blk_stop_queue(msb->queue); |
|---|
| 2045 | 2049 | msb->io_queue_stopped = true; |
|---|
| 2046 | 2050 | spin_unlock_irqrestore(&msb->q_lock, flags); |
|---|
| 2047 | 2051 | |
|---|
| 2048 | 2052 | del_timer_sync(&msb->cache_flush_timer); |
|---|
| 2049 | 2053 | flush_workqueue(msb->io_queue); |
|---|
| 2050 | 2054 | |
|---|
| 2055 | + spin_lock_irqsave(&msb->q_lock, flags); |
|---|
| 2051 | 2056 | if (msb->req) { |
|---|
| 2052 | | - spin_lock_irqsave(&msb->q_lock, flags); |
|---|
| 2053 | | - blk_requeue_request(msb->queue, msb->req); |
|---|
| 2057 | + blk_mq_requeue_request(msb->req, false); |
|---|
| 2054 | 2058 | msb->req = NULL; |
|---|
| 2055 | | - spin_unlock_irqrestore(&msb->q_lock, flags); |
|---|
| 2056 | 2059 | } |
|---|
| 2057 | | - |
|---|
| 2060 | + spin_unlock_irqrestore(&msb->q_lock, flags); |
|---|
| 2058 | 2061 | } |
|---|
| 2059 | 2062 | |
|---|
| 2060 | 2063 | static void msb_start(struct memstick_dev *card) |
|---|
| .. | .. |
|---|
| 2077 | 2080 | msb->need_flush_cache = true; |
|---|
| 2078 | 2081 | msb->io_queue_stopped = false; |
|---|
| 2079 | 2082 | |
|---|
| 2080 | | - spin_lock_irqsave(&msb->q_lock, flags); |
|---|
| 2081 | | - blk_start_queue(msb->queue); |
|---|
| 2082 | | - spin_unlock_irqrestore(&msb->q_lock, flags); |
|---|
| 2083 | + blk_mq_start_hw_queues(msb->queue); |
|---|
| 2083 | 2084 | |
|---|
| 2084 | 2085 | queue_work(msb->io_queue, &msb->io_work); |
|---|
| 2085 | 2086 | |
|---|
| .. | .. |
|---|
| 2090 | 2091 | .release = msb_bd_release, |
|---|
| 2091 | 2092 | .getgeo = msb_bd_getgeo, |
|---|
| 2092 | 2093 | .owner = THIS_MODULE |
|---|
| 2094 | +}; |
|---|
| 2095 | + |
|---|
| 2096 | +static const struct blk_mq_ops msb_mq_ops = { |
|---|
| 2097 | + .queue_rq = msb_queue_rq, |
|---|
| 2093 | 2098 | }; |
|---|
| 2094 | 2099 | |
|---|
| 2095 | 2100 | /* Registers the block device */ |
|---|
| .. | .. |
|---|
| 2112 | 2117 | goto out_release_id; |
|---|
| 2113 | 2118 | } |
|---|
| 2114 | 2119 | |
|---|
| 2115 | | - msb->queue = blk_init_queue(msb_submit_req, &msb->q_lock); |
|---|
| 2116 | | - if (!msb->queue) { |
|---|
| 2117 | | - rc = -ENOMEM; |
|---|
| 2120 | + msb->queue = blk_mq_init_sq_queue(&msb->tag_set, &msb_mq_ops, 2, |
|---|
| 2121 | + BLK_MQ_F_SHOULD_MERGE); |
|---|
| 2122 | + if (IS_ERR(msb->queue)) { |
|---|
| 2123 | + rc = PTR_ERR(msb->queue); |
|---|
| 2124 | + msb->queue = NULL; |
|---|
| 2118 | 2125 | goto out_put_disk; |
|---|
| 2119 | 2126 | } |
|---|
| 2120 | 2127 | |
|---|
| .. | .. |
|---|
| 2146 | 2153 | set_disk_ro(msb->disk, 1); |
|---|
| 2147 | 2154 | |
|---|
| 2148 | 2155 | msb_start(card); |
|---|
| 2149 | | - device_add_disk(&card->dev, msb->disk); |
|---|
| 2156 | + device_add_disk(&card->dev, msb->disk, NULL); |
|---|
| 2150 | 2157 | dbg("Disk added"); |
|---|
| 2151 | 2158 | return 0; |
|---|
| 2152 | 2159 | |
|---|
| .. | .. |
|---|
| 2202 | 2209 | /* Take care of unhandled + new requests from now on */ |
|---|
| 2203 | 2210 | spin_lock_irqsave(&msb->q_lock, flags); |
|---|
| 2204 | 2211 | msb->card_dead = true; |
|---|
| 2205 | | - blk_start_queue(msb->queue); |
|---|
| 2206 | 2212 | spin_unlock_irqrestore(&msb->q_lock, flags); |
|---|
| 2213 | + blk_mq_start_hw_queues(msb->queue); |
|---|
| 2207 | 2214 | |
|---|
| 2208 | 2215 | /* Remove the disk */ |
|---|
| 2209 | 2216 | del_gendisk(msb->disk); |
|---|
| 2210 | 2217 | blk_cleanup_queue(msb->queue); |
|---|
| 2218 | + blk_mq_free_tag_set(&msb->tag_set); |
|---|
| 2211 | 2219 | msb->queue = NULL; |
|---|
| 2212 | 2220 | |
|---|
| 2213 | 2221 | mutex_lock(&msb_disk_lock); |
|---|