Skip to content

Commit c6049cd

Browse files
Christoph Hellwigmartinkpetersen
authored andcommitted
scsi: ufs: add a low-level __ufshcd_issue_tm_cmd helper
Add a helper that takes a utp_task_req_desc and issues it, which will be useful for UFS bsg support. Rewrite ufshcd_issue_tm_cmd0x to use this new helper. Signed-off-by: Christoph Hellwig <[email protected]> Signed-off-by: Avri Altman <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 391e388 commit c6049cd

File tree

1 file changed

+61
-80
lines changed

1 file changed

+61
-80
lines changed

drivers/scsi/ufs/ufshcd.c

Lines changed: 61 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -633,19 +633,6 @@ static inline int ufshcd_get_tr_ocs(struct ufshcd_lrb *lrbp)
633633
return le32_to_cpu(lrbp->utr_descriptor_ptr->header.dword_2) & MASK_OCS;
634634
}
635635

636-
/**
637-
* ufshcd_get_tmr_ocs - Get the UTMRD Overall Command Status
638-
* @task_req_descp: pointer to utp_task_req_desc structure
639-
*
640-
* This function is used to get the OCS field from UTMRD
641-
* Returns the OCS field in the UTMRD
642-
*/
643-
static inline int
644-
ufshcd_get_tmr_ocs(struct utp_task_req_desc *task_req_descp)
645-
{
646-
return le32_to_cpu(task_req_descp->header.dword_2) & MASK_OCS;
647-
}
648-
649636
/**
650637
* ufshcd_get_tm_free_slot - get a free slot for task management request
651638
* @hba: per adapter instance
@@ -4616,37 +4603,6 @@ static void ufshcd_slave_destroy(struct scsi_device *sdev)
46164603
}
46174604
}
46184605

4619-
/**
4620-
* ufshcd_task_req_compl - handle task management request completion
4621-
* @hba: per adapter instance
4622-
* @index: index of the completed request
4623-
* @resp: task management service response
4624-
*
4625-
* Returns non-zero value on error, zero on success
4626-
*/
4627-
static int ufshcd_task_req_compl(struct ufs_hba *hba, u32 index, u8 *resp)
4628-
{
4629-
struct utp_task_req_desc *treq = hba->utmrdl_base_addr + index;
4630-
unsigned long flags;
4631-
int ocs_value;
4632-
4633-
spin_lock_irqsave(hba->host->host_lock, flags);
4634-
4635-
/* Clear completed tasks from outstanding_tasks */
4636-
__clear_bit(index, &hba->outstanding_tasks);
4637-
4638-
ocs_value = ufshcd_get_tmr_ocs(treq);
4639-
4640-
if (ocs_value != OCS_SUCCESS)
4641-
dev_err(hba->dev, "%s: failed, ocs = 0x%x\n",
4642-
__func__, ocs_value);
4643-
else if (resp)
4644-
*resp = be32_to_cpu(treq->output_param1) & MASK_TM_SERVICE_RESP;
4645-
spin_unlock_irqrestore(hba->host->host_lock, flags);
4646-
4647-
return ocs_value;
4648-
}
4649-
46504606
/**
46514607
* ufshcd_scsi_cmd_status - Update SCSI command result based on SCSI status
46524608
* @lrbp: pointer to local reference block of completed command
@@ -5604,27 +5560,12 @@ static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int tag)
56045560
return err;
56055561
}
56065562

5607-
/**
5608-
* ufshcd_issue_tm_cmd - issues task management commands to controller
5609-
* @hba: per adapter instance
5610-
* @lun_id: LUN ID to which TM command is sent
5611-
* @task_id: task ID to which the TM command is applicable
5612-
* @tm_function: task management function opcode
5613-
* @tm_response: task management service response return value
5614-
*
5615-
* Returns non-zero value on error, zero on success.
5616-
*/
5617-
static int ufshcd_issue_tm_cmd(struct ufs_hba *hba, int lun_id, int task_id,
5618-
u8 tm_function, u8 *tm_response)
5563+
static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba,
5564+
struct utp_task_req_desc *treq, u8 tm_function)
56195565
{
5620-
struct utp_task_req_desc *treq;
5621-
struct Scsi_Host *host;
5566+
struct Scsi_Host *host = hba->host;
56225567
unsigned long flags;
5623-
int free_slot;
5624-
int err;
5625-
int task_tag;
5626-
5627-
host = hba->host;
5568+
int free_slot, task_tag, err;
56285569

56295570
/*
56305571
* Get free slot, sleep if slots are unavailable.
@@ -5635,24 +5576,11 @@ static int ufshcd_issue_tm_cmd(struct ufs_hba *hba, int lun_id, int task_id,
56355576
ufshcd_hold(hba, false);
56365577

56375578
spin_lock_irqsave(host->host_lock, flags);
5638-
treq = hba->utmrdl_base_addr + free_slot;
5639-
5640-
/* Configure task request descriptor */
5641-
treq->header.dword_0 = cpu_to_le32(UTP_REQ_DESC_INT_CMD);
5642-
treq->header.dword_2 = cpu_to_le32(OCS_INVALID_COMMAND_STATUS);
5643-
5644-
/* Configure task request UPIU */
56455579
task_tag = hba->nutrs + free_slot;
5646-
treq->req_header.dword_0 = UPIU_HEADER_DWORD(UPIU_TRANSACTION_TASK_REQ,
5647-
0, lun_id, task_tag);
5648-
treq->req_header.dword_1 = UPIU_HEADER_DWORD(0, tm_function, 0, 0);
5649-
/*
5650-
* The host shall provide the same value for LUN field in the basic
5651-
* header and for Input Parameter.
5652-
*/
5653-
treq->input_param1 = cpu_to_be32(lun_id);
5654-
treq->input_param2 = cpu_to_be32(task_id);
56555580

5581+
treq->req_header.dword_0 |= cpu_to_be32(task_tag);
5582+
5583+
memcpy(hba->utmrdl_base_addr + free_slot, treq, sizeof(*treq));
56565584
ufshcd_vops_setup_task_mgmt(hba, free_slot, tm_function);
56575585

56585586
/* send command to the controller */
@@ -5682,8 +5610,15 @@ static int ufshcd_issue_tm_cmd(struct ufs_hba *hba, int lun_id, int task_id,
56825610
__func__, free_slot);
56835611
err = -ETIMEDOUT;
56845612
} else {
5685-
err = ufshcd_task_req_compl(hba, free_slot, tm_response);
5613+
err = 0;
5614+
memcpy(treq, hba->utmrdl_base_addr + free_slot, sizeof(*treq));
5615+
56865616
ufshcd_add_tm_upiu_trace(hba, task_tag, "tm_complete");
5617+
5618+
spin_lock_irqsave(hba->host->host_lock, flags);
5619+
__clear_bit(free_slot, &hba->outstanding_tasks);
5620+
spin_unlock_irqrestore(hba->host->host_lock, flags);
5621+
56875622
}
56885623

56895624
clear_bit(free_slot, &hba->tm_condition);
@@ -5694,6 +5629,52 @@ static int ufshcd_issue_tm_cmd(struct ufs_hba *hba, int lun_id, int task_id,
56945629
return err;
56955630
}
56965631

5632+
/**
5633+
* ufshcd_issue_tm_cmd - issues task management commands to controller
5634+
* @hba: per adapter instance
5635+
* @lun_id: LUN ID to which TM command is sent
5636+
* @task_id: task ID to which the TM command is applicable
5637+
* @tm_function: task management function opcode
5638+
* @tm_response: task management service response return value
5639+
*
5640+
* Returns non-zero value on error, zero on success.
5641+
*/
5642+
static int ufshcd_issue_tm_cmd(struct ufs_hba *hba, int lun_id, int task_id,
5643+
u8 tm_function, u8 *tm_response)
5644+
{
5645+
struct utp_task_req_desc treq = { { 0 }, };
5646+
int ocs_value, err;
5647+
5648+
/* Configure task request descriptor */
5649+
treq.header.dword_0 = cpu_to_le32(UTP_REQ_DESC_INT_CMD);
5650+
treq.header.dword_2 = cpu_to_le32(OCS_INVALID_COMMAND_STATUS);
5651+
5652+
/* Configure task request UPIU */
5653+
treq.req_header.dword_0 = cpu_to_be32(lun_id << 8) |
5654+
cpu_to_be32(UPIU_TRANSACTION_TASK_REQ << 24);
5655+
treq.req_header.dword_1 = cpu_to_be32(tm_function << 16);
5656+
5657+
/*
5658+
* The host shall provide the same value for LUN field in the basic
5659+
* header and for Input Parameter.
5660+
*/
5661+
treq.input_param1 = cpu_to_be32(lun_id);
5662+
treq.input_param2 = cpu_to_be32(task_id);
5663+
5664+
err = __ufshcd_issue_tm_cmd(hba, &treq, tm_function);
5665+
if (err == -ETIMEDOUT)
5666+
return err;
5667+
5668+
ocs_value = le32_to_cpu(treq.header.dword_2) & MASK_OCS;
5669+
if (ocs_value != OCS_SUCCESS)
5670+
dev_err(hba->dev, "%s: failed, ocs = 0x%x\n",
5671+
__func__, ocs_value);
5672+
else if (tm_response)
5673+
*tm_response = be32_to_cpu(treq.output_param1) &
5674+
MASK_TM_SERVICE_RESP;
5675+
return err;
5676+
}
5677+
56975678
/**
56985679
* ufshcd_eh_device_reset_handler - device reset handler registered to
56995680
* scsi layer.

0 commit comments

Comments
 (0)