]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/s390/scsi/zfcp_fc.h
scsi: zfcp: use endianness conversions with common FC(P) struct fields
[mirror_ubuntu-bionic-kernel.git] / drivers / s390 / scsi / zfcp_fc.h
index df2b541c828720718a322003d43f7d54e2aef3eb..41f22d3dc6d1bc3f4917f57fff4ce421f4243899 100644 (file)
@@ -4,7 +4,7 @@
  * Fibre Channel related definitions and inline functions for the zfcp
  * device driver
  *
- * Copyright IBM Corp. 2009
+ * Copyright IBM Corp. 2009, 2017
  */
 
 #ifndef ZFCP_FC_H
@@ -212,6 +212,8 @@ static inline
 void zfcp_fc_scsi_to_fcp(struct fcp_cmnd *fcp, struct scsi_cmnd *scsi,
                         u8 tm_flags)
 {
+       u32 datalen;
+
        int_to_scsilun(scsi->device->lun, (struct scsi_lun *) &fcp->fc_lun);
 
        if (unlikely(tm_flags)) {
@@ -228,10 +230,13 @@ void zfcp_fc_scsi_to_fcp(struct fcp_cmnd *fcp, struct scsi_cmnd *scsi,
 
        memcpy(fcp->fc_cdb, scsi->cmnd, scsi->cmd_len);
 
-       fcp->fc_dl = scsi_bufflen(scsi);
+       datalen = scsi_bufflen(scsi);
+       fcp->fc_dl = cpu_to_be32(datalen);
 
-       if (scsi_get_prot_type(scsi) == SCSI_PROT_DIF_TYPE1)
-               fcp->fc_dl += fcp->fc_dl / scsi->device->sector_size * 8;
+       if (scsi_get_prot_type(scsi) == SCSI_PROT_DIF_TYPE1) {
+               datalen += datalen / scsi->device->sector_size * 8;
+               fcp->fc_dl = cpu_to_be32(datalen);
+       }
 }
 
 /**
@@ -266,19 +271,23 @@ void zfcp_fc_eval_fcp_rsp(struct fcp_resp_with_ext *fcp_rsp,
        if (unlikely(rsp_flags & FCP_SNS_LEN_VAL)) {
                sense = (char *) &fcp_rsp[1];
                if (rsp_flags & FCP_RSP_LEN_VAL)
-                       sense += fcp_rsp->ext.fr_rsp_len;
-               sense_len = min(fcp_rsp->ext.fr_sns_len,
-                               (u32) SCSI_SENSE_BUFFERSIZE);
+                       sense += be32_to_cpu(fcp_rsp->ext.fr_rsp_len);
+               sense_len = min_t(u32, be32_to_cpu(fcp_rsp->ext.fr_sns_len),
+                                 SCSI_SENSE_BUFFERSIZE);
                memcpy(scsi->sense_buffer, sense, sense_len);
        }
 
        if (unlikely(rsp_flags & FCP_RESID_UNDER)) {
-               resid = fcp_rsp->ext.fr_resid;
+               resid = be32_to_cpu(fcp_rsp->ext.fr_resid);
                scsi_set_resid(scsi, resid);
                if (scsi_bufflen(scsi) - resid < scsi->underflow &&
                     !(rsp_flags & FCP_SNS_LEN_VAL) &&
                     fcp_rsp->resp.fr_status == SAM_STAT_GOOD)
                        set_host_byte(scsi, DID_ERROR);
+       } else if (unlikely(rsp_flags & FCP_RESID_OVER)) {
+               /* FCP_DL was not sufficient for SCSI data length */
+               if (fcp_rsp->resp.fr_status == SAM_STAT_GOOD)
+                       set_host_byte(scsi, DID_ERROR);
        }
 }