scsi: Fix incorrect reporting of host protection capabilities
PATCH 1/1 scsi: Fix incorrect reporting of host protection capabilities
The advent of DIF Type 2 devices exposed these missing break statements.
---
include/scsi/scsi_host.h +3 -0
@@ -801,12 +801,15 @@ static inline unsigned int scsi_host_dif_capable(struct Scsi_Host *shost, unsigncase 1 :if (shost->prot_capabilities &SHOST_DIF_TYPE1_PROTECTION )return target_type; +break ;case 2 :if (shost->prot_capabilities &SHOST_DIF_TYPE2_PROTECTION )return target_type; +break ;case 3 :if (shost->prot_capabilities &SHOST_DIF_TYPE3_PROTECTION )return target_type; +break ; }return 0 ;
Quoted 2 lines · Martin K. Petersen
The advent of DIF Type 2 devices exposed these missing break statements.
Is there not a similar problem in scsi_host_dix_capable()?
And are these performance path? If not, it might be nice to move them out of line and code them like this:
unsigned scsi_host_dif_capable(struct Scsi_Host *shost, unsigned target_type)
{
static unsigned cap[4] = {
0, SHOST_DIF_TYPE1_PROTECTION,
SHOST_DIF_TYPE2_PROTECTION, SHOST_DIF_TYPE3_PROTECTION
};
unsigned type = cap[target_type];
return (shost->prot_capabilities & type) ? 1 : 0;
}unsigned scsi_host_dix_capable(struct Scsi_Host *shost, unsigned target_type)
{
static unsigned cap[4] = {
SHOST_DIX_TYPE0_PROTECTION, SHOST_DIX_TYPE1_PROTECTION,
SHOST_DIF_TYPE2_PROTECTION, SHOST_DIF_TYPE3_PROTECTION
};
unsigned type = cap[target_type];
return (shost->prot_capabilities & type) ? 1 : 0;
}Signature · 4 lines
Matthew Wilcox Intel Open Source Technology Centre "Bill, look, we understand that you're interested in selling us this operating system, but compare it to ours. We can't possibly take such a retrograde step."
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
"Matthew" == Matthew Wilcox <[email protected]> writes:
Matthew> And are these performance path? If not, it might be nice to Matthew> move them out of line and code them like this:
I compared the object files for the two approaches and it looks like indexing into the array is a clear win compared to the switch statement.
Also, the DIF case must return the chosen protection type and not true/false.
scsi: Fix incorrect reporting of host protection capabilities
The advent of DIF Type 2 devices exposed some missing break statements in the protection mask switch constructs. However, rewriting the code to use an index into a small static array seemed like a more elegant solution.
include/scsi/scsi_host.h +11 -18
@@ -797,30 +797,23 @@ static inline unsigned int scsi_host_get_prot(struct Scsi_Host *shost)static inline unsigned int scsi_host_dif_capable (struct Scsi_Host *shost,unsigned int target_type) { -switch (target_type) { -case 1 : -if (shost->prot_capabilities &SHOST_DIF_TYPE1_PROTECTION ) -return target_type; -case 2 : -if (shost->prot_capabilities &SHOST_DIF_TYPE2_PROTECTION ) -return target_type; -case 3 : -if (shost->prot_capabilities &SHOST_DIF_TYPE3_PROTECTION ) -return target_type; - } +static unsigned char cap[] = {0 , +SHOST_DIF_TYPE1_PROTECTION , +SHOST_DIF_TYPE2_PROTECTION , +SHOST_DIF_TYPE3_PROTECTION }; -return 0 ; +return shost->prot_capabilities & cap[target_type] ? target_type :0 ; }static inline unsigned int scsi_host_dix_capable (struct Scsi_Host *shost,unsigned int target_type) {#if defined(CONFIG_BLK_DEV_INTEGRITY ) -switch (target_type) { -case 0 :return shost->prot_capabilities &SHOST_DIX_TYPE0_PROTECTION ; -case 1 :return shost->prot_capabilities &SHOST_DIX_TYPE1_PROTECTION ; -case 2 :return shost->prot_capabilities &SHOST_DIX_TYPE2_PROTECTION ; -case 3 :return shost->prot_capabilities &SHOST_DIX_TYPE3_PROTECTION ; - } +static unsigned char cap[] = {SHOST_DIX_TYPE0_PROTECTION , +SHOST_DIX_TYPE1_PROTECTION , +SHOST_DIX_TYPE2_PROTECTION , +SHOST_DIX_TYPE3_PROTECTION }; + +return shost->prot_capabilities & cap[target_type];#endif return 0 ; }