@@ -645,40 +645,6 @@ static inline int ufshcd_get_tr_ocs(struct ufshcd_lrb *lrbp)
645645 return le32_to_cpu (lrbp -> utr_descriptor_ptr -> header .dword_2 ) & MASK_OCS ;
646646}
647647
648- /**
649- * ufshcd_get_tm_free_slot - get a free slot for task management request
650- * @hba: per adapter instance
651- * @free_slot: pointer to variable with available slot value
652- *
653- * Get a free tag and lock it until ufshcd_put_tm_slot() is called.
654- * Returns 0 if free slot is not available, else return 1 with tag value
655- * in @free_slot.
656- */
657- static bool ufshcd_get_tm_free_slot (struct ufs_hba * hba , int * free_slot )
658- {
659- int tag ;
660- bool ret = false;
661-
662- if (!free_slot )
663- goto out ;
664-
665- do {
666- tag = find_first_zero_bit (& hba -> tm_slots_in_use , hba -> nutmrs );
667- if (tag >= hba -> nutmrs )
668- goto out ;
669- } while (test_and_set_bit_lock (tag , & hba -> tm_slots_in_use ));
670-
671- * free_slot = tag ;
672- ret = true;
673- out :
674- return ret ;
675- }
676-
677- static inline void ufshcd_put_tm_slot (struct ufs_hba * hba , int slot )
678- {
679- clear_bit_unlock (slot , & hba -> tm_slots_in_use );
680- }
681-
682648/**
683649 * ufshcd_utrl_clear - Clear a bit in UTRLCLR register
684650 * @hba: per adapter instance
@@ -5570,6 +5536,27 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba)
55705536 return retval ;
55715537}
55725538
5539+ struct ctm_info {
5540+ struct ufs_hba * hba ;
5541+ unsigned long pending ;
5542+ unsigned int ncpl ;
5543+ };
5544+
5545+ static bool ufshcd_compl_tm (struct request * req , void * priv , bool reserved )
5546+ {
5547+ struct ctm_info * const ci = priv ;
5548+ struct completion * c ;
5549+
5550+ WARN_ON_ONCE (reserved );
5551+ if (test_bit (req -> tag , & ci -> pending ))
5552+ return true;
5553+ ci -> ncpl ++ ;
5554+ c = req -> end_io_data ;
5555+ if (c )
5556+ complete (c );
5557+ return true;
5558+ }
5559+
55735560/**
55745561 * ufshcd_tmc_handler - handle task management function completion
55755562 * @hba: per adapter instance
@@ -5580,16 +5567,14 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba)
55805567 */
55815568static irqreturn_t ufshcd_tmc_handler (struct ufs_hba * hba )
55825569{
5583- u32 tm_doorbell ;
5570+ struct request_queue * q = hba -> tmf_queue ;
5571+ struct ctm_info ci = {
5572+ .hba = hba ,
5573+ .pending = ufshcd_readl (hba , REG_UTP_TASK_REQ_DOOR_BELL ),
5574+ };
55845575
5585- tm_doorbell = ufshcd_readl (hba , REG_UTP_TASK_REQ_DOOR_BELL );
5586- hba -> tm_condition = tm_doorbell ^ hba -> outstanding_tasks ;
5587- if (hba -> tm_condition ) {
5588- wake_up (& hba -> tm_wq );
5589- return IRQ_HANDLED ;
5590- } else {
5591- return IRQ_NONE ;
5592- }
5576+ blk_mq_tagset_busy_iter (q -> tag_set , ufshcd_compl_tm , & ci );
5577+ return ci .ncpl ? IRQ_HANDLED : IRQ_NONE ;
55935578}
55945579
55955580/**
@@ -5695,7 +5680,10 @@ static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int tag)
56955680static int __ufshcd_issue_tm_cmd (struct ufs_hba * hba ,
56965681 struct utp_task_req_desc * treq , u8 tm_function )
56975682{
5683+ struct request_queue * q = hba -> tmf_queue ;
56985684 struct Scsi_Host * host = hba -> host ;
5685+ DECLARE_COMPLETION_ONSTACK (wait );
5686+ struct request * req ;
56995687 unsigned long flags ;
57005688 int free_slot , task_tag , err ;
57015689
@@ -5704,7 +5692,10 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba,
57045692 * Even though we use wait_event() which sleeps indefinitely,
57055693 * the maximum wait time is bounded by %TM_CMD_TIMEOUT.
57065694 */
5707- wait_event (hba -> tm_tag_wq , ufshcd_get_tm_free_slot (hba , & free_slot ));
5695+ req = blk_get_request (q , REQ_OP_DRV_OUT , BLK_MQ_REQ_RESERVED );
5696+ req -> end_io_data = & wait ;
5697+ free_slot = req -> tag ;
5698+ WARN_ON_ONCE (free_slot < 0 || free_slot >= hba -> nutmrs );
57085699 ufshcd_hold (hba , false);
57095700
57105701 spin_lock_irqsave (host -> host_lock , flags );
@@ -5730,10 +5721,14 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba,
57305721 ufshcd_add_tm_upiu_trace (hba , task_tag , "tm_send" );
57315722
57325723 /* wait until the task management command is completed */
5733- err = wait_event_timeout (hba -> tm_wq ,
5734- test_bit (free_slot , & hba -> tm_condition ),
5724+ err = wait_for_completion_io_timeout (& wait ,
57355725 msecs_to_jiffies (TM_CMD_TIMEOUT ));
57365726 if (!err ) {
5727+ /*
5728+ * Make sure that ufshcd_compl_tm() does not trigger a
5729+ * use-after-free.
5730+ */
5731+ req -> end_io_data = NULL ;
57375732 ufshcd_add_tm_upiu_trace (hba , task_tag , "tm_complete_err" );
57385733 dev_err (hba -> dev , "%s: task management cmd 0x%.2x timed-out\n" ,
57395734 __func__ , tm_function );
@@ -5752,9 +5747,7 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba,
57525747 __clear_bit (free_slot , & hba -> outstanding_tasks );
57535748 spin_unlock_irqrestore (hba -> host -> host_lock , flags );
57545749
5755- clear_bit (free_slot , & hba -> tm_condition );
5756- ufshcd_put_tm_slot (hba , free_slot );
5757- wake_up (& hba -> tm_tag_wq );
5750+ blk_put_request (req );
57585751
57595752 ufshcd_release (hba );
57605753 return err ;
@@ -8219,6 +8212,8 @@ void ufshcd_remove(struct ufs_hba *hba)
82198212{
82208213 ufs_bsg_remove (hba );
82218214 ufs_sysfs_remove_nodes (hba -> dev );
8215+ blk_cleanup_queue (hba -> tmf_queue );
8216+ blk_mq_free_tag_set (& hba -> tmf_tag_set );
82228217 blk_cleanup_queue (hba -> cmd_queue );
82238218 scsi_remove_host (hba -> host );
82248219 /* disable interrupts */
@@ -8298,6 +8293,18 @@ int ufshcd_alloc_host(struct device *dev, struct ufs_hba **hba_handle)
82988293}
82998294EXPORT_SYMBOL (ufshcd_alloc_host );
83008295
8296+ /* This function exists because blk_mq_alloc_tag_set() requires this. */
8297+ static blk_status_t ufshcd_queue_tmf (struct blk_mq_hw_ctx * hctx ,
8298+ const struct blk_mq_queue_data * qd )
8299+ {
8300+ WARN_ON_ONCE (true);
8301+ return BLK_STS_NOTSUPP ;
8302+ }
8303+
8304+ static const struct blk_mq_ops ufshcd_tmf_ops = {
8305+ .queue_rq = ufshcd_queue_tmf ,
8306+ };
8307+
83018308/**
83028309 * ufshcd_init - Driver initialization routine
83038310 * @hba: per-adapter instance
@@ -8367,10 +8374,6 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
83678374
83688375 hba -> max_pwr_info .is_valid = false;
83698376
8370- /* Initailize wait queue for task management */
8371- init_waitqueue_head (& hba -> tm_wq );
8372- init_waitqueue_head (& hba -> tm_tag_wq );
8373-
83748377 /* Initialize work queues */
83758378 INIT_WORK (& hba -> eh_work , ufshcd_err_handler );
83768379 INIT_WORK (& hba -> eeh_work , ufshcd_exception_event_handler );
@@ -8422,6 +8425,21 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
84228425 goto out_remove_scsi_host ;
84238426 }
84248427
8428+ hba -> tmf_tag_set = (struct blk_mq_tag_set ) {
8429+ .nr_hw_queues = 1 ,
8430+ .queue_depth = hba -> nutmrs ,
8431+ .ops = & ufshcd_tmf_ops ,
8432+ .flags = BLK_MQ_F_NO_SCHED ,
8433+ };
8434+ err = blk_mq_alloc_tag_set (& hba -> tmf_tag_set );
8435+ if (err < 0 )
8436+ goto free_cmd_queue ;
8437+ hba -> tmf_queue = blk_mq_init_queue (& hba -> tmf_tag_set );
8438+ if (IS_ERR (hba -> tmf_queue )) {
8439+ err = PTR_ERR (hba -> tmf_queue );
8440+ goto free_tmf_tag_set ;
8441+ }
8442+
84258443 /* Reset the attached device */
84268444 ufshcd_vops_device_reset (hba );
84278445
@@ -8431,7 +8449,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
84318449 dev_err (hba -> dev , "Host controller enable failed\n" );
84328450 ufshcd_print_host_regs (hba );
84338451 ufshcd_print_host_state (hba );
8434- goto free_cmd_queue ;
8452+ goto free_tmf_queue ;
84358453 }
84368454
84378455 /*
@@ -8468,6 +8486,10 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
84688486
84698487 return 0 ;
84708488
8489+ free_tmf_queue :
8490+ blk_cleanup_queue (hba -> tmf_queue );
8491+ free_tmf_tag_set :
8492+ blk_mq_free_tag_set (& hba -> tmf_tag_set );
84718493free_cmd_queue :
84728494 blk_cleanup_queue (hba -> cmd_queue );
84738495out_remove_scsi_host :
0 commit comments