mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git
synced 2026-04-18 03:23:53 -04:00
scsi: ufs: core: Allow UFS host drivers to override the sg entry size
Modify the UFSHCD core to allow 'struct ufshcd_sg_entry' to be variable-length. The default is the standard length, but variants can override ufs_hba::sg_entry_size with a larger value if there are vendor-specific fields following the standard ones. This is needed to support inline encryption with ufs-exynos (FMP). Cc: Eric Biggers <ebiggers@google.com> Reviewed-by: Avri Altman <avri.altman@wdc.com> Signed-off-by: Eric Biggers <ebiggers@google.com> [ bvanassche: edited commit message and introduced CONFIG_SCSI_UFS_VARIABLE_SG_ENTRY_SIZE ] Signed-off-by: Bart Van Assche <bvanassche@acm.org> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
committed by
Martin K. Petersen
parent
b434ecfb73
commit
ada1e653a5
@@ -754,6 +754,7 @@ struct ufs_hba_monitor {
|
||||
* @vops: pointer to variant specific operations
|
||||
* @vps: pointer to variant specific parameters
|
||||
* @priv: pointer to variant specific private data
|
||||
* @sg_entry_size: size of struct ufshcd_sg_entry (may include variant fields)
|
||||
* @irq: Irq number of the controller
|
||||
* @is_irq_enabled: whether or not the UFS controller interrupt is enabled.
|
||||
* @dev_ref_clk_freq: reference clock frequency
|
||||
@@ -877,6 +878,9 @@ struct ufs_hba {
|
||||
const struct ufs_hba_variant_ops *vops;
|
||||
struct ufs_hba_variant_params *vps;
|
||||
void *priv;
|
||||
#ifdef CONFIG_SCSI_UFS_VARIABLE_SG_ENTRY_SIZE
|
||||
size_t sg_entry_size;
|
||||
#endif
|
||||
unsigned int irq;
|
||||
bool is_irq_enabled;
|
||||
enum ufs_ref_clk_freq dev_ref_clk_freq;
|
||||
@@ -980,6 +984,32 @@ struct ufs_hba {
|
||||
bool complete_put;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SCSI_UFS_VARIABLE_SG_ENTRY_SIZE
|
||||
static inline size_t ufshcd_sg_entry_size(const struct ufs_hba *hba)
|
||||
{
|
||||
return hba->sg_entry_size;
|
||||
}
|
||||
|
||||
static inline void ufshcd_set_sg_entry_size(struct ufs_hba *hba, size_t sg_entry_size)
|
||||
{
|
||||
WARN_ON_ONCE(sg_entry_size < sizeof(struct ufshcd_sg_entry));
|
||||
hba->sg_entry_size = sg_entry_size;
|
||||
}
|
||||
#else
|
||||
static inline size_t ufshcd_sg_entry_size(const struct ufs_hba *hba)
|
||||
{
|
||||
return sizeof(struct ufshcd_sg_entry);
|
||||
}
|
||||
|
||||
#define ufshcd_set_sg_entry_size(hba, sg_entry_size) \
|
||||
({ (void)(hba); BUILD_BUG_ON(sg_entry_size != sizeof(struct ufshcd_sg_entry)); })
|
||||
#endif
|
||||
|
||||
static inline size_t sizeof_utp_transfer_cmd_desc(const struct ufs_hba *hba)
|
||||
{
|
||||
return sizeof(struct utp_transfer_cmd_desc) + SG_ALL * ufshcd_sg_entry_size(hba);
|
||||
}
|
||||
|
||||
/* Returns true if clocks can be gated. Otherwise false */
|
||||
static inline bool ufshcd_is_clkgating_allowed(struct ufs_hba *hba)
|
||||
{
|
||||
|
||||
@@ -422,18 +422,23 @@ struct ufshcd_sg_entry {
|
||||
__le64 addr;
|
||||
__le32 reserved;
|
||||
__le32 size;
|
||||
/*
|
||||
* followed by variant-specific fields if
|
||||
* CONFIG_SCSI_UFS_VARIABLE_SG_ENTRY_SIZE has been defined.
|
||||
*/
|
||||
};
|
||||
|
||||
/**
|
||||
* struct utp_transfer_cmd_desc - UTP Command Descriptor (UCD)
|
||||
* @command_upiu: Command UPIU Frame address
|
||||
* @response_upiu: Response UPIU Frame address
|
||||
* @prd_table: Physical Region Descriptor
|
||||
* @prd_table: Physical Region Descriptor: an array of SG_ALL struct
|
||||
* ufshcd_sg_entry's. Variant-specific fields may be present after each.
|
||||
*/
|
||||
struct utp_transfer_cmd_desc {
|
||||
u8 command_upiu[ALIGNED_UPIU_SIZE];
|
||||
u8 response_upiu[ALIGNED_UPIU_SIZE];
|
||||
struct ufshcd_sg_entry prd_table[SG_ALL];
|
||||
u8 prd_table[];
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user