Commit 300bb13f authored by Joao Pinto's avatar Joao Pinto Committed by Martin K. Petersen

ufs: add UFS 2.0 capabilities

Add UFS 2.0 support to the UFS core driver.
Signed-off-by: default avatarJoao Pinto <jpinto@synopsys.com>
Acked-by: default avatarArnd Bergmann <arnd@arndb.de>
Acked-by: default avatarTomas Winkler <tomas.winkler@intel.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent b1d78f27
...@@ -1173,7 +1173,7 @@ static void ufshcd_disable_intr(struct ufs_hba *hba, u32 intrs) ...@@ -1173,7 +1173,7 @@ static void ufshcd_disable_intr(struct ufs_hba *hba, u32 intrs)
* @cmd_dir: requests data direction * @cmd_dir: requests data direction
*/ */
static void ufshcd_prepare_req_desc_hdr(struct ufshcd_lrb *lrbp, static void ufshcd_prepare_req_desc_hdr(struct ufshcd_lrb *lrbp,
u32 *upiu_flags, enum dma_data_direction cmd_dir) u32 *upiu_flags, enum dma_data_direction cmd_dir)
{ {
struct utp_transfer_req_desc *req_desc = lrbp->utr_descriptor_ptr; struct utp_transfer_req_desc *req_desc = lrbp->utr_descriptor_ptr;
u32 data_direction; u32 data_direction;
...@@ -1299,47 +1299,55 @@ static inline void ufshcd_prepare_utp_nop_upiu(struct ufshcd_lrb *lrbp) ...@@ -1299,47 +1299,55 @@ static inline void ufshcd_prepare_utp_nop_upiu(struct ufshcd_lrb *lrbp)
} }
/** /**
* ufshcd_compose_upiu - form UFS Protocol Information Unit(UPIU) * ufshcd_comp_devman_upiu - UFS Protocol Information Unit(UPIU)
* for Device Management Purposes
* @hba - per adapter instance * @hba - per adapter instance
* @lrb - pointer to local reference block * @lrb - pointer to local reference block
*/ */
static int ufshcd_compose_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) static int ufshcd_comp_devman_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
{ {
u32 upiu_flags; u32 upiu_flags;
int ret = 0; int ret = 0;
switch (lrbp->command_type) { if (hba->ufs_version == UFSHCI_VERSION_20)
case UTP_CMD_TYPE_SCSI: lrbp->command_type = UTP_CMD_TYPE_UFS_STORAGE;
if (likely(lrbp->cmd)) { else
ufshcd_prepare_req_desc_hdr(lrbp, &upiu_flags, lrbp->command_type = UTP_CMD_TYPE_DEV_MANAGE;
lrbp->cmd->sc_data_direction);
ufshcd_prepare_utp_scsi_cmd_upiu(lrbp, upiu_flags); ufshcd_prepare_req_desc_hdr(lrbp, &upiu_flags, DMA_NONE);
} else { if (hba->dev_cmd.type == DEV_CMD_TYPE_QUERY)
ret = -EINVAL; ufshcd_prepare_utp_query_req_upiu(hba, lrbp, upiu_flags);
} else if (hba->dev_cmd.type == DEV_CMD_TYPE_NOP)
break; ufshcd_prepare_utp_nop_upiu(lrbp);
case UTP_CMD_TYPE_DEV_MANAGE: else
ufshcd_prepare_req_desc_hdr(lrbp, &upiu_flags, DMA_NONE); ret = -EINVAL;
if (hba->dev_cmd.type == DEV_CMD_TYPE_QUERY)
ufshcd_prepare_utp_query_req_upiu( return ret;
hba, lrbp, upiu_flags); }
else if (hba->dev_cmd.type == DEV_CMD_TYPE_NOP)
ufshcd_prepare_utp_nop_upiu(lrbp); /**
else * ufshcd_comp_scsi_upiu - UFS Protocol Information Unit(UPIU)
ret = -EINVAL; * for SCSI Purposes
break; * @hba - per adapter instance
case UTP_CMD_TYPE_UFS: * @lrb - pointer to local reference block
/* For UFS native command implementation */ */
ret = -ENOTSUPP; static int ufshcd_comp_scsi_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
dev_err(hba->dev, "%s: UFS native command are not supported\n", {
__func__); u32 upiu_flags;
break; int ret = 0;
default:
ret = -ENOTSUPP; if (hba->ufs_version == UFSHCI_VERSION_20)
dev_err(hba->dev, "%s: unknown command type: 0x%x\n", lrbp->command_type = UTP_CMD_TYPE_UFS_STORAGE;
__func__, lrbp->command_type); else
break; lrbp->command_type = UTP_CMD_TYPE_SCSI;
} /* end of switch */
if (likely(lrbp->cmd)) {
ufshcd_prepare_req_desc_hdr(lrbp, &upiu_flags,
lrbp->cmd->sc_data_direction);
ufshcd_prepare_utp_scsi_cmd_upiu(lrbp, upiu_flags);
} else {
ret = -EINVAL;
}
return ret; return ret;
} }
...@@ -1451,10 +1459,9 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) ...@@ -1451,10 +1459,9 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
lrbp->task_tag = tag; lrbp->task_tag = tag;
lrbp->lun = ufshcd_scsi_to_upiu_lun(cmd->device->lun); lrbp->lun = ufshcd_scsi_to_upiu_lun(cmd->device->lun);
lrbp->intr_cmd = !ufshcd_is_intr_aggr_allowed(hba) ? true : false; lrbp->intr_cmd = !ufshcd_is_intr_aggr_allowed(hba) ? true : false;
lrbp->command_type = UTP_CMD_TYPE_SCSI;
/* form UPIU before issuing the command */ ufshcd_comp_scsi_upiu(hba, lrbp);
ufshcd_compose_upiu(hba, lrbp);
err = ufshcd_map_sg(lrbp); err = ufshcd_map_sg(lrbp);
if (err) { if (err) {
lrbp->cmd = NULL; lrbp->cmd = NULL;
...@@ -1479,11 +1486,10 @@ static int ufshcd_compose_dev_cmd(struct ufs_hba *hba, ...@@ -1479,11 +1486,10 @@ static int ufshcd_compose_dev_cmd(struct ufs_hba *hba,
lrbp->sense_buffer = NULL; lrbp->sense_buffer = NULL;
lrbp->task_tag = tag; lrbp->task_tag = tag;
lrbp->lun = 0; /* device management cmd is not specific to any LUN */ lrbp->lun = 0; /* device management cmd is not specific to any LUN */
lrbp->command_type = UTP_CMD_TYPE_DEV_MANAGE;
lrbp->intr_cmd = true; /* No interrupt aggregation */ lrbp->intr_cmd = true; /* No interrupt aggregation */
hba->dev_cmd.type = cmd_type; hba->dev_cmd.type = cmd_type;
return ufshcd_compose_upiu(hba, lrbp); return ufshcd_comp_devman_upiu(hba, lrbp);
} }
static int static int
...@@ -3539,7 +3545,8 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba, ...@@ -3539,7 +3545,8 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba,
/* Do not touch lrbp after scsi done */ /* Do not touch lrbp after scsi done */
cmd->scsi_done(cmd); cmd->scsi_done(cmd);
__ufshcd_release(hba); __ufshcd_release(hba);
} else if (lrbp->command_type == UTP_CMD_TYPE_DEV_MANAGE) { } else if (lrbp->command_type == UTP_CMD_TYPE_DEV_MANAGE ||
lrbp->command_type == UTP_CMD_TYPE_UFS_STORAGE) {
if (hba->dev_cmd.complete) if (hba->dev_cmd.complete)
complete(hba->dev_cmd.complete); complete(hba->dev_cmd.complete);
} }
......
...@@ -279,6 +279,11 @@ enum { ...@@ -279,6 +279,11 @@ enum {
UTP_CMD_TYPE_DEV_MANAGE = 0x2, UTP_CMD_TYPE_DEV_MANAGE = 0x2,
}; };
/* To accommodate UFS2.0 required Command type */
enum {
UTP_CMD_TYPE_UFS_STORAGE = 0x1,
};
enum { enum {
UTP_SCSI_COMMAND = 0x00000000, UTP_SCSI_COMMAND = 0x00000000,
UTP_NATIVE_UFS_COMMAND = 0x10000000, UTP_NATIVE_UFS_COMMAND = 0x10000000,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment