Message ID | 40585ae835f02d3b5550a32553b2189754e365b6.1459448160.git.jpinto@synopsys.com (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
On Thu, 2016-03-31 at 19:57 +0100, Joao Pinto wrote: > Adding UFS 2.0 support to the UFS core driver. > > Signed-off-by: Joao Pinto <jpinto@synopsys.com> Looks good to me, though not tested yet Tomas > --- > Changes v11->v12 (Tomas Winkler): > - devicetree binding tweak was moved to a separated patch > - unipro tweaks were moved to a separated patch > - ufshcd_compose_upiu was decomposed in 2 functions > - UTP_CMD_TYPE_UFS_STORAGE is now 0x1 (previously was 0x11) > Changes v8->v11: > - Nothing changed (just to keep up with patch set version). > Changes v7->v8: > - Added "jedec, ufs-2.0" to the ufschd-platform compatibility strings > Changes v0->v7: > - Nothing changed (just to keep up with patch set version). > > drivers/scsi/ufs/ufshcd.c | 90 ++++++++++++++++++++++++++----------- > ---------- > drivers/scsi/ufs/ufshci.h | 5 +++ > 2 files changed, 54 insertions(+), 41 deletions(-) > > diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c > index 9c1b94b..a69d637 100644 > --- a/drivers/scsi/ufs/ufshcd.c > +++ b/drivers/scsi/ufs/ufshcd.c > @@ -1127,7 +1127,7 @@ static void ufshcd_disable_intr(struct ufs_hba > *hba, u32 intrs) > * @cmd_dir: requests data direction > */ > 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; > u32 data_direction; > @@ -1253,47 +1253,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 > * @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; > int ret = 0; > > - switch (lrbp->command_type) { > - case UTP_CMD_TYPE_SCSI: > - 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; > - } > - break; > - case UTP_CMD_TYPE_DEV_MANAGE: > - ufshcd_prepare_req_desc_hdr(lrbp, &upiu_flags, > DMA_NONE); > - if (hba->dev_cmd.type == DEV_CMD_TYPE_QUERY) > - ufshcd_prepare_utp_query_req_upiu( > - hba, lrbp, upiu_flags); > - else if (hba->dev_cmd.type == DEV_CMD_TYPE_NOP) > - ufshcd_prepare_utp_nop_upiu(lrbp); > - else > - ret = -EINVAL; > - break; > - case UTP_CMD_TYPE_UFS: > - /* For UFS native command implementation */ > - ret = -ENOTSUPP; > - dev_err(hba->dev, "%s: UFS native command are not > supported\n", > - __func__); > - break; > - default: > - ret = -ENOTSUPP; > - dev_err(hba->dev, "%s: unknown command type: > 0x%x\n", > - __func__, lrbp->command_type); > - break; > - } /* end of switch */ > + if (hba->ufs_version == UFSHCI_VERSION_20) > + lrbp->command_type = UTP_CMD_TYPE_UFS_STORAGE; > + else > + lrbp->command_type = UTP_CMD_TYPE_DEV_MANAGE; > + > + ufshcd_prepare_req_desc_hdr(lrbp, &upiu_flags, DMA_NONE); > + if (hba->dev_cmd.type == DEV_CMD_TYPE_QUERY) > + ufshcd_prepare_utp_query_req_upiu(hba, lrbp, > upiu_flags); > + else if (hba->dev_cmd.type == DEV_CMD_TYPE_NOP) > + ufshcd_prepare_utp_nop_upiu(lrbp); > + else > + ret = -EINVAL; > + > + return ret; > +} > + > +/** > + * ufshcd_comp_scsi_upiu - UFS Protocol Information Unit(UPIU) > + * for SCSI Purposes > + * @hba - per adapter instance > + * @lrb - pointer to local reference block > + */ > +static int ufshcd_comp_scsi_upiu(struct ufs_hba *hba, struct > ufshcd_lrb *lrbp) > +{ > + u32 upiu_flags; > + int ret = 0; > + > + if (hba->ufs_version == UFSHCI_VERSION_20) > + lrbp->command_type = UTP_CMD_TYPE_UFS_STORAGE; > + else > + lrbp->command_type = UTP_CMD_TYPE_SCSI; > + > + 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; > } > @@ -1405,10 +1414,9 @@ static int ufshcd_queuecommand(struct > Scsi_Host *host, struct scsi_cmnd *cmd) > lrbp->task_tag = tag; > lrbp->lun = ufshcd_scsi_to_upiu_lun(cmd->device->lun); > 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_compose_upiu(hba, lrbp); > + ufshcd_comp_scsi_upiu(hba, lrbp); > + > err = ufshcd_map_sg(lrbp); > if (err) { > lrbp->cmd = NULL; > @@ -1433,11 +1441,10 @@ static int ufshcd_compose_dev_cmd(struct > ufs_hba *hba, > lrbp->sense_buffer = NULL; > lrbp->task_tag = tag; > 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 */ > hba->dev_cmd.type = cmd_type; > > - return ufshcd_compose_upiu(hba, lrbp); > + return ufshcd_comp_devman_upiu(hba, lrbp); > } > > static int > @@ -3403,7 +3410,8 @@ static void ufshcd_transfer_req_compl(struct > ufs_hba *hba) > /* Do not touch lrbp after scsi done */ > cmd->scsi_done(cmd); > __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) > complete(hba->dev_cmd.complete); > } > diff --git a/drivers/scsi/ufs/ufshci.h b/drivers/scsi/ufs/ufshci.h > index 0ae0967..20ece18 100644 > --- a/drivers/scsi/ufs/ufshci.h > +++ b/drivers/scsi/ufs/ufshci.h > @@ -275,6 +275,11 @@ enum { > UTP_CMD_TYPE_DEV_MANAGE = 0x2, > }; > > +/* To accomodate UFS2.0 required Command type */ > +enum { > + UTP_CMD_TYPE_UFS_STORAGE = 0x1, > +}; > + > enum { > UTP_SCSI_COMMAND = 0x00000000, > UTP_NATIVE_UFS_COMMAND = 0x10000000,
On 3/31/2016 9:27 PM, Winkler, Tomas wrote: > On Thu, 2016-03-31 at 19:57 +0100, Joao Pinto wrote: >> Adding UFS 2.0 support to the UFS core driver. >> >> Signed-off-by: Joao Pinto <jpinto@synopsys.com> > > Looks good to me, though not tested yet > Tomas I have tested the build in a x86 and ARC. Also tested the functionality by using a HAPS-DX FPGA with the UFS 2.0 design + MPHY G210. > >> --- >> Changes v11->v12 (Tomas Winkler): >> - devicetree binding tweak was moved to a separated patch >> - unipro tweaks were moved to a separated patch >> - ufshcd_compose_upiu was decomposed in 2 functions [snip] >> +enum { >> + UTP_CMD_TYPE_UFS_STORAGE = 0x1, >> +}; >> + >> enum { >> UTP_SCSI_COMMAND = 0x00000000, >> UTP_NATIVE_UFS_COMMAND = 0x10000000, If you need anything else, please let me know. Thanks. Joao -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 9c1b94b..a69d637 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -1127,7 +1127,7 @@ static void ufshcd_disable_intr(struct ufs_hba *hba, u32 intrs) * @cmd_dir: requests data direction */ 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; u32 data_direction; @@ -1253,47 +1253,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 * @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; int ret = 0; - switch (lrbp->command_type) { - case UTP_CMD_TYPE_SCSI: - 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; - } - break; - case UTP_CMD_TYPE_DEV_MANAGE: - ufshcd_prepare_req_desc_hdr(lrbp, &upiu_flags, DMA_NONE); - if (hba->dev_cmd.type == DEV_CMD_TYPE_QUERY) - ufshcd_prepare_utp_query_req_upiu( - hba, lrbp, upiu_flags); - else if (hba->dev_cmd.type == DEV_CMD_TYPE_NOP) - ufshcd_prepare_utp_nop_upiu(lrbp); - else - ret = -EINVAL; - break; - case UTP_CMD_TYPE_UFS: - /* For UFS native command implementation */ - ret = -ENOTSUPP; - dev_err(hba->dev, "%s: UFS native command are not supported\n", - __func__); - break; - default: - ret = -ENOTSUPP; - dev_err(hba->dev, "%s: unknown command type: 0x%x\n", - __func__, lrbp->command_type); - break; - } /* end of switch */ + if (hba->ufs_version == UFSHCI_VERSION_20) + lrbp->command_type = UTP_CMD_TYPE_UFS_STORAGE; + else + lrbp->command_type = UTP_CMD_TYPE_DEV_MANAGE; + + ufshcd_prepare_req_desc_hdr(lrbp, &upiu_flags, DMA_NONE); + if (hba->dev_cmd.type == DEV_CMD_TYPE_QUERY) + ufshcd_prepare_utp_query_req_upiu(hba, lrbp, upiu_flags); + else if (hba->dev_cmd.type == DEV_CMD_TYPE_NOP) + ufshcd_prepare_utp_nop_upiu(lrbp); + else + ret = -EINVAL; + + return ret; +} + +/** + * ufshcd_comp_scsi_upiu - UFS Protocol Information Unit(UPIU) + * for SCSI Purposes + * @hba - per adapter instance + * @lrb - pointer to local reference block + */ +static int ufshcd_comp_scsi_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) +{ + u32 upiu_flags; + int ret = 0; + + if (hba->ufs_version == UFSHCI_VERSION_20) + lrbp->command_type = UTP_CMD_TYPE_UFS_STORAGE; + else + lrbp->command_type = UTP_CMD_TYPE_SCSI; + + 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; } @@ -1405,10 +1414,9 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) lrbp->task_tag = tag; lrbp->lun = ufshcd_scsi_to_upiu_lun(cmd->device->lun); 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_compose_upiu(hba, lrbp); + ufshcd_comp_scsi_upiu(hba, lrbp); + err = ufshcd_map_sg(lrbp); if (err) { lrbp->cmd = NULL; @@ -1433,11 +1441,10 @@ static int ufshcd_compose_dev_cmd(struct ufs_hba *hba, lrbp->sense_buffer = NULL; lrbp->task_tag = tag; 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 */ hba->dev_cmd.type = cmd_type; - return ufshcd_compose_upiu(hba, lrbp); + return ufshcd_comp_devman_upiu(hba, lrbp); } static int @@ -3403,7 +3410,8 @@ static void ufshcd_transfer_req_compl(struct ufs_hba *hba) /* Do not touch lrbp after scsi done */ cmd->scsi_done(cmd); __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) complete(hba->dev_cmd.complete); } diff --git a/drivers/scsi/ufs/ufshci.h b/drivers/scsi/ufs/ufshci.h index 0ae0967..20ece18 100644 --- a/drivers/scsi/ufs/ufshci.h +++ b/drivers/scsi/ufs/ufshci.h @@ -275,6 +275,11 @@ enum { UTP_CMD_TYPE_DEV_MANAGE = 0x2, }; +/* To accomodate UFS2.0 required Command type */ +enum { + UTP_CMD_TYPE_UFS_STORAGE = 0x1, +}; + enum { UTP_SCSI_COMMAND = 0x00000000, UTP_NATIVE_UFS_COMMAND = 0x10000000,
Adding UFS 2.0 support to the UFS core driver. Signed-off-by: Joao Pinto <jpinto@synopsys.com> --- Changes v11->v12 (Tomas Winkler): - devicetree binding tweak was moved to a separated patch - unipro tweaks were moved to a separated patch - ufshcd_compose_upiu was decomposed in 2 functions - UTP_CMD_TYPE_UFS_STORAGE is now 0x1 (previously was 0x11) Changes v8->v11: - Nothing changed (just to keep up with patch set version). Changes v7->v8: - Added "jedec, ufs-2.0" to the ufschd-platform compatibility strings Changes v0->v7: - Nothing changed (just to keep up with patch set version). drivers/scsi/ufs/ufshcd.c | 90 ++++++++++++++++++++++++++--------------------- drivers/scsi/ufs/ufshci.h | 5 +++ 2 files changed, 54 insertions(+), 41 deletions(-)