.. | .. |
---|
| 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 | |
---|