| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Sony MemoryStick Pro storage support |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2007 Alex Dubov <oakad@yahoo.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 | * Special thanks to Carlos Corbacho for providing various MemoryStick cards |
|---|
| 11 | 8 | * that made this driver possible. |
|---|
| 12 | | - * |
|---|
| 13 | 9 | */ |
|---|
| 14 | 10 | |
|---|
| 15 | | -#include <linux/blkdev.h> |
|---|
| 11 | +#include <linux/blk-mq.h> |
|---|
| 16 | 12 | #include <linux/idr.h> |
|---|
| 17 | 13 | #include <linux/hdreg.h> |
|---|
| 18 | 14 | #include <linux/kthread.h> |
|---|
| .. | .. |
|---|
| 142 | 138 | struct gendisk *disk; |
|---|
| 143 | 139 | struct request_queue *queue; |
|---|
| 144 | 140 | struct request *block_req; |
|---|
| 141 | + struct blk_mq_tag_set tag_set; |
|---|
| 145 | 142 | spinlock_t q_lock; |
|---|
| 146 | 143 | |
|---|
| 147 | 144 | unsigned short page_size; |
|---|
| .. | .. |
|---|
| 152 | 149 | unsigned char system; |
|---|
| 153 | 150 | unsigned char read_only:1, |
|---|
| 154 | 151 | eject:1, |
|---|
| 155 | | - has_request:1, |
|---|
| 156 | 152 | data_dir:1, |
|---|
| 157 | 153 | active:1; |
|---|
| 158 | 154 | unsigned char transfer_cmd; |
|---|
| .. | .. |
|---|
| 694 | 690 | |
|---|
| 695 | 691 | /*** Data transfer ***/ |
|---|
| 696 | 692 | |
|---|
| 697 | | -static int mspro_block_issue_req(struct memstick_dev *card, int chunk) |
|---|
| 693 | +static int mspro_block_issue_req(struct memstick_dev *card) |
|---|
| 698 | 694 | { |
|---|
| 699 | 695 | struct mspro_block_data *msb = memstick_get_drvdata(card); |
|---|
| 700 | 696 | u64 t_off; |
|---|
| 701 | 697 | unsigned int count; |
|---|
| 702 | 698 | |
|---|
| 703 | | -try_again: |
|---|
| 704 | | - while (chunk) { |
|---|
| 699 | + while (true) { |
|---|
| 705 | 700 | msb->current_page = 0; |
|---|
| 706 | 701 | msb->current_seg = 0; |
|---|
| 707 | 702 | msb->seg_count = blk_rq_map_sg(msb->block_req->q, |
|---|
| .. | .. |
|---|
| 709 | 704 | msb->req_sg); |
|---|
| 710 | 705 | |
|---|
| 711 | 706 | if (!msb->seg_count) { |
|---|
| 712 | | - chunk = __blk_end_request_cur(msb->block_req, |
|---|
| 713 | | - BLK_STS_RESOURCE); |
|---|
| 714 | | - continue; |
|---|
| 707 | + unsigned int bytes = blk_rq_cur_bytes(msb->block_req); |
|---|
| 708 | + bool chunk; |
|---|
| 709 | + |
|---|
| 710 | + chunk = blk_update_request(msb->block_req, |
|---|
| 711 | + BLK_STS_RESOURCE, |
|---|
| 712 | + bytes); |
|---|
| 713 | + if (chunk) |
|---|
| 714 | + continue; |
|---|
| 715 | + __blk_mq_end_request(msb->block_req, |
|---|
| 716 | + BLK_STS_RESOURCE); |
|---|
| 717 | + msb->block_req = NULL; |
|---|
| 718 | + return -EAGAIN; |
|---|
| 715 | 719 | } |
|---|
| 716 | 720 | |
|---|
| 717 | 721 | t_off = blk_rq_pos(msb->block_req); |
|---|
| .. | .. |
|---|
| 728 | 732 | memstick_new_req(card->host); |
|---|
| 729 | 733 | return 0; |
|---|
| 730 | 734 | } |
|---|
| 731 | | - |
|---|
| 732 | | - dev_dbg(&card->dev, "blk_fetch\n"); |
|---|
| 733 | | - msb->block_req = blk_fetch_request(msb->queue); |
|---|
| 734 | | - if (!msb->block_req) { |
|---|
| 735 | | - dev_dbg(&card->dev, "issue end\n"); |
|---|
| 736 | | - return -EAGAIN; |
|---|
| 737 | | - } |
|---|
| 738 | | - |
|---|
| 739 | | - dev_dbg(&card->dev, "trying again\n"); |
|---|
| 740 | | - chunk = 1; |
|---|
| 741 | | - goto try_again; |
|---|
| 742 | 735 | } |
|---|
| 743 | 736 | |
|---|
| 744 | 737 | static int mspro_block_complete_req(struct memstick_dev *card, int error) |
|---|
| 745 | 738 | { |
|---|
| 746 | 739 | struct mspro_block_data *msb = memstick_get_drvdata(card); |
|---|
| 747 | | - int chunk, cnt; |
|---|
| 740 | + int cnt; |
|---|
| 741 | + bool chunk; |
|---|
| 748 | 742 | unsigned int t_len = 0; |
|---|
| 749 | 743 | unsigned long flags; |
|---|
| 750 | 744 | |
|---|
| 751 | 745 | spin_lock_irqsave(&msb->q_lock, flags); |
|---|
| 752 | | - dev_dbg(&card->dev, "complete %d, %d\n", msb->has_request ? 1 : 0, |
|---|
| 746 | + dev_dbg(&card->dev, "complete %d, %d\n", msb->block_req ? 1 : 0, |
|---|
| 753 | 747 | error); |
|---|
| 754 | 748 | |
|---|
| 755 | | - if (msb->has_request) { |
|---|
| 749 | + if (msb->block_req) { |
|---|
| 756 | 750 | /* Nothing to do - not really an error */ |
|---|
| 757 | 751 | if (error == -EAGAIN) |
|---|
| 758 | 752 | error = 0; |
|---|
| .. | .. |
|---|
| 777 | 771 | if (error && !t_len) |
|---|
| 778 | 772 | t_len = blk_rq_cur_bytes(msb->block_req); |
|---|
| 779 | 773 | |
|---|
| 780 | | - chunk = __blk_end_request(msb->block_req, |
|---|
| 774 | + chunk = blk_update_request(msb->block_req, |
|---|
| 781 | 775 | errno_to_blk_status(error), t_len); |
|---|
| 782 | | - |
|---|
| 783 | | - error = mspro_block_issue_req(card, chunk); |
|---|
| 784 | | - |
|---|
| 785 | | - if (!error) |
|---|
| 786 | | - goto out; |
|---|
| 787 | | - else |
|---|
| 788 | | - msb->has_request = 0; |
|---|
| 776 | + if (chunk) { |
|---|
| 777 | + error = mspro_block_issue_req(card); |
|---|
| 778 | + if (!error) |
|---|
| 779 | + goto out; |
|---|
| 780 | + } else { |
|---|
| 781 | + __blk_mq_end_request(msb->block_req, |
|---|
| 782 | + errno_to_blk_status(error)); |
|---|
| 783 | + msb->block_req = NULL; |
|---|
| 784 | + } |
|---|
| 789 | 785 | } else { |
|---|
| 790 | 786 | if (!error) |
|---|
| 791 | 787 | error = -EAGAIN; |
|---|
| .. | .. |
|---|
| 806 | 802 | |
|---|
| 807 | 803 | while (1) { |
|---|
| 808 | 804 | spin_lock_irqsave(&msb->q_lock, flags); |
|---|
| 809 | | - if (!msb->has_request) { |
|---|
| 810 | | - blk_stop_queue(msb->queue); |
|---|
| 805 | + if (!msb->block_req) { |
|---|
| 806 | + blk_mq_stop_hw_queues(msb->queue); |
|---|
| 811 | 807 | rc = 1; |
|---|
| 812 | 808 | } |
|---|
| 813 | 809 | spin_unlock_irqrestore(&msb->q_lock, flags); |
|---|
| .. | .. |
|---|
| 822 | 818 | static void mspro_block_start(struct memstick_dev *card) |
|---|
| 823 | 819 | { |
|---|
| 824 | 820 | struct mspro_block_data *msb = memstick_get_drvdata(card); |
|---|
| 825 | | - unsigned long flags; |
|---|
| 826 | 821 | |
|---|
| 827 | | - spin_lock_irqsave(&msb->q_lock, flags); |
|---|
| 828 | | - blk_start_queue(msb->queue); |
|---|
| 829 | | - spin_unlock_irqrestore(&msb->q_lock, flags); |
|---|
| 822 | + blk_mq_start_hw_queues(msb->queue); |
|---|
| 830 | 823 | } |
|---|
| 831 | 824 | |
|---|
| 832 | | -static void mspro_block_submit_req(struct request_queue *q) |
|---|
| 825 | +static blk_status_t mspro_queue_rq(struct blk_mq_hw_ctx *hctx, |
|---|
| 826 | + const struct blk_mq_queue_data *bd) |
|---|
| 833 | 827 | { |
|---|
| 834 | | - struct memstick_dev *card = q->queuedata; |
|---|
| 828 | + struct memstick_dev *card = hctx->queue->queuedata; |
|---|
| 835 | 829 | struct mspro_block_data *msb = memstick_get_drvdata(card); |
|---|
| 836 | | - struct request *req = NULL; |
|---|
| 837 | 830 | |
|---|
| 838 | | - if (msb->has_request) |
|---|
| 839 | | - return; |
|---|
| 831 | + spin_lock_irq(&msb->q_lock); |
|---|
| 840 | 832 | |
|---|
| 841 | | - if (msb->eject) { |
|---|
| 842 | | - while ((req = blk_fetch_request(q)) != NULL) |
|---|
| 843 | | - __blk_end_request_all(req, BLK_STS_IOERR); |
|---|
| 844 | | - |
|---|
| 845 | | - return; |
|---|
| 833 | + if (msb->block_req) { |
|---|
| 834 | + spin_unlock_irq(&msb->q_lock); |
|---|
| 835 | + return BLK_STS_DEV_RESOURCE; |
|---|
| 846 | 836 | } |
|---|
| 847 | 837 | |
|---|
| 848 | | - msb->has_request = 1; |
|---|
| 849 | | - if (mspro_block_issue_req(card, 0)) |
|---|
| 850 | | - msb->has_request = 0; |
|---|
| 838 | + if (msb->eject) { |
|---|
| 839 | + spin_unlock_irq(&msb->q_lock); |
|---|
| 840 | + blk_mq_start_request(bd->rq); |
|---|
| 841 | + return BLK_STS_IOERR; |
|---|
| 842 | + } |
|---|
| 843 | + |
|---|
| 844 | + msb->block_req = bd->rq; |
|---|
| 845 | + blk_mq_start_request(bd->rq); |
|---|
| 846 | + |
|---|
| 847 | + if (mspro_block_issue_req(card)) |
|---|
| 848 | + msb->block_req = NULL; |
|---|
| 849 | + |
|---|
| 850 | + spin_unlock_irq(&msb->q_lock); |
|---|
| 851 | + return BLK_STS_OK; |
|---|
| 851 | 852 | } |
|---|
| 852 | 853 | |
|---|
| 853 | 854 | /*** Initialization ***/ |
|---|
| .. | .. |
|---|
| 1167 | 1168 | |
|---|
| 1168 | 1169 | } |
|---|
| 1169 | 1170 | |
|---|
| 1171 | +static const struct blk_mq_ops mspro_mq_ops = { |
|---|
| 1172 | + .queue_rq = mspro_queue_rq, |
|---|
| 1173 | +}; |
|---|
| 1174 | + |
|---|
| 1170 | 1175 | static int mspro_block_init_disk(struct memstick_dev *card) |
|---|
| 1171 | 1176 | { |
|---|
| 1172 | 1177 | struct mspro_block_data *msb = memstick_get_drvdata(card); |
|---|
| .. | .. |
|---|
| 1206 | 1211 | goto out_release_id; |
|---|
| 1207 | 1212 | } |
|---|
| 1208 | 1213 | |
|---|
| 1209 | | - msb->queue = blk_init_queue(mspro_block_submit_req, &msb->q_lock); |
|---|
| 1210 | | - if (!msb->queue) { |
|---|
| 1211 | | - rc = -ENOMEM; |
|---|
| 1214 | + msb->queue = blk_mq_init_sq_queue(&msb->tag_set, &mspro_mq_ops, 2, |
|---|
| 1215 | + BLK_MQ_F_SHOULD_MERGE); |
|---|
| 1216 | + if (IS_ERR(msb->queue)) { |
|---|
| 1217 | + rc = PTR_ERR(msb->queue); |
|---|
| 1218 | + msb->queue = NULL; |
|---|
| 1212 | 1219 | goto out_put_disk; |
|---|
| 1213 | 1220 | } |
|---|
| 1214 | 1221 | |
|---|
| .. | .. |
|---|
| 1236 | 1243 | set_capacity(msb->disk, capacity); |
|---|
| 1237 | 1244 | dev_dbg(&card->dev, "capacity set %ld\n", capacity); |
|---|
| 1238 | 1245 | |
|---|
| 1239 | | - device_add_disk(&card->dev, msb->disk); |
|---|
| 1246 | + device_add_disk(&card->dev, msb->disk, NULL); |
|---|
| 1240 | 1247 | msb->active = 1; |
|---|
| 1241 | 1248 | return 0; |
|---|
| 1242 | 1249 | |
|---|
| .. | .. |
|---|
| 1318 | 1325 | |
|---|
| 1319 | 1326 | spin_lock_irqsave(&msb->q_lock, flags); |
|---|
| 1320 | 1327 | msb->eject = 1; |
|---|
| 1321 | | - blk_start_queue(msb->queue); |
|---|
| 1322 | 1328 | spin_unlock_irqrestore(&msb->q_lock, flags); |
|---|
| 1329 | + blk_mq_start_hw_queues(msb->queue); |
|---|
| 1323 | 1330 | |
|---|
| 1324 | 1331 | del_gendisk(msb->disk); |
|---|
| 1325 | 1332 | dev_dbg(&card->dev, "mspro block remove\n"); |
|---|
| 1326 | 1333 | |
|---|
| 1327 | 1334 | blk_cleanup_queue(msb->queue); |
|---|
| 1335 | + blk_mq_free_tag_set(&msb->tag_set); |
|---|
| 1328 | 1336 | msb->queue = NULL; |
|---|
| 1329 | 1337 | |
|---|
| 1330 | 1338 | sysfs_remove_group(&card->dev.kobj, &msb->attr_group); |
|---|
| .. | .. |
|---|
| 1344 | 1352 | struct mspro_block_data *msb = memstick_get_drvdata(card); |
|---|
| 1345 | 1353 | unsigned long flags; |
|---|
| 1346 | 1354 | |
|---|
| 1355 | + blk_mq_stop_hw_queues(msb->queue); |
|---|
| 1356 | + |
|---|
| 1347 | 1357 | spin_lock_irqsave(&msb->q_lock, flags); |
|---|
| 1348 | | - blk_stop_queue(msb->queue); |
|---|
| 1349 | 1358 | msb->active = 0; |
|---|
| 1350 | 1359 | spin_unlock_irqrestore(&msb->q_lock, flags); |
|---|
| 1351 | 1360 | |
|---|
| .. | .. |
|---|
| 1355 | 1364 | static int mspro_block_resume(struct memstick_dev *card) |
|---|
| 1356 | 1365 | { |
|---|
| 1357 | 1366 | struct mspro_block_data *msb = memstick_get_drvdata(card); |
|---|
| 1358 | | - unsigned long flags; |
|---|
| 1359 | 1367 | int rc = 0; |
|---|
| 1360 | 1368 | |
|---|
| 1361 | 1369 | #ifdef CONFIG_MEMSTICK_UNSAFE_RESUME |
|---|
| .. | .. |
|---|
| 1401 | 1409 | |
|---|
| 1402 | 1410 | #endif /* CONFIG_MEMSTICK_UNSAFE_RESUME */ |
|---|
| 1403 | 1411 | |
|---|
| 1404 | | - spin_lock_irqsave(&msb->q_lock, flags); |
|---|
| 1405 | | - blk_start_queue(msb->queue); |
|---|
| 1406 | | - spin_unlock_irqrestore(&msb->q_lock, flags); |
|---|
| 1412 | + blk_mq_start_hw_queues(msb->queue); |
|---|
| 1407 | 1413 | return rc; |
|---|
| 1408 | 1414 | } |
|---|
| 1409 | 1415 | |
|---|