aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_fc.h
diff options
context:
space:
mode:
authorChristof Schmitt <christof.schmitt@de.ibm.com>2009-11-24 10:54:08 -0500
committerJames Bottomley <James.Bottomley@suse.de>2009-12-04 13:02:10 -0500
commit4318e08c84e4916ac463002ffb7f9901ddb3c385 (patch)
treeebce82e85a0d2010c98d0585a5b94113981ee357 /drivers/s390/scsi/zfcp_fc.h
parent8830271c4819d86d8e87202a1fe8da0bb58912a2 (diff)
[SCSI] zfcp: Update FCP protocol related code
Use common data structures for FCP CMND, FCP RSP and related definitions and remove zfcp private definitions. Split the FCP CMND setup and FCP RSP evaluation code in seperate functions. Use inline functions to not negatively impact the I/O path. Reviewed-by: Swen Schillig <swen@vnet.ibm.com> Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/s390/scsi/zfcp_fc.h')
-rw-r--r--drivers/s390/scsi/zfcp_fc.h112
1 files changed, 112 insertions, 0 deletions
diff --git a/drivers/s390/scsi/zfcp_fc.h b/drivers/s390/scsi/zfcp_fc.h
new file mode 100644
index 000000000000..814fc2d2525a
--- /dev/null
+++ b/drivers/s390/scsi/zfcp_fc.h
@@ -0,0 +1,112 @@
1/*
2 * zfcp device driver
3 *
4 * Fibre Channel related definitions and inline functions for the zfcp
5 * device driver
6 *
7 * Copyright IBM Corporation 2009
8 */
9
10#ifndef ZFCP_FC_H
11#define ZFCP_FC_H
12
13#include <scsi/fc/fc_fcp.h>
14#include <scsi/scsi_cmnd.h>
15#include <scsi/scsi_tcq.h>
16
17/**
18 * zfcp_fc_scsi_to_fcp - setup FCP command with data from scsi_cmnd
19 * @fcp: fcp_cmnd to setup
20 * @scsi: scsi_cmnd where to get LUN, task attributes/flags and CDB
21 */
22static inline
23void zfcp_fc_scsi_to_fcp(struct fcp_cmnd *fcp, struct scsi_cmnd *scsi)
24{
25 char tag[2];
26
27 int_to_scsilun(scsi->device->lun, (struct scsi_lun *) &fcp->fc_lun);
28
29 if (scsi_populate_tag_msg(scsi, tag)) {
30 switch (tag[0]) {
31 case MSG_ORDERED_TAG:
32 fcp->fc_pri_ta |= FCP_PTA_ORDERED;
33 break;
34 case MSG_SIMPLE_TAG:
35 fcp->fc_pri_ta |= FCP_PTA_SIMPLE;
36 break;
37 };
38 } else
39 fcp->fc_pri_ta = FCP_PTA_SIMPLE;
40
41 if (scsi->sc_data_direction == DMA_FROM_DEVICE)
42 fcp->fc_flags |= FCP_CFL_RDDATA;
43 if (scsi->sc_data_direction == DMA_TO_DEVICE)
44 fcp->fc_flags |= FCP_CFL_WRDATA;
45
46 memcpy(fcp->fc_cdb, scsi->cmnd, scsi->cmd_len);
47
48 fcp->fc_dl = scsi_bufflen(scsi);
49}
50
51/**
52 * zfcp_fc_fcp_tm - setup FCP command as task management command
53 * @fcp: fcp_cmnd to setup
54 * @dev: scsi_device where to send the task management command
55 * @tm: task management flags to setup tm command
56 */
57static inline
58void zfcp_fc_fcp_tm(struct fcp_cmnd *fcp, struct scsi_device *dev, u8 tm_flags)
59{
60 int_to_scsilun(dev->lun, (struct scsi_lun *) &fcp->fc_lun);
61 fcp->fc_tm_flags |= tm_flags;
62}
63
64/**
65 * zfcp_fc_evap_fcp_rsp - evaluate FCP RSP IU and update scsi_cmnd accordingly
66 * @fcp_rsp: FCP RSP IU to evaluate
67 * @scsi: SCSI command where to update status and sense buffer
68 */
69static inline
70void zfcp_fc_eval_fcp_rsp(struct fcp_resp_with_ext *fcp_rsp,
71 struct scsi_cmnd *scsi)
72{
73 struct fcp_resp_rsp_info *rsp_info;
74 char *sense;
75 u32 sense_len, resid;
76 u8 rsp_flags;
77
78 set_msg_byte(scsi, COMMAND_COMPLETE);
79 scsi->result |= fcp_rsp->resp.fr_status;
80
81 rsp_flags = fcp_rsp->resp.fr_flags;
82
83 if (unlikely(rsp_flags & FCP_RSP_LEN_VAL)) {
84 rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1];
85 if (rsp_info->rsp_code == FCP_TMF_CMPL)
86 set_host_byte(scsi, DID_OK);
87 else {
88 set_host_byte(scsi, DID_ERROR);
89 return;
90 }
91 }
92
93 if (unlikely(rsp_flags & FCP_SNS_LEN_VAL)) {
94 sense = (char *) &fcp_rsp[1];
95 if (rsp_flags & FCP_RSP_LEN_VAL)
96 sense += fcp_rsp->ext.fr_sns_len;
97 sense_len = min(fcp_rsp->ext.fr_sns_len,
98 (u32) SCSI_SENSE_BUFFERSIZE);
99 memcpy(scsi->sense_buffer, sense, sense_len);
100 }
101
102 if (unlikely(rsp_flags & FCP_RESID_UNDER)) {
103 resid = fcp_rsp->ext.fr_resid;
104 scsi_set_resid(scsi, resid);
105 if (scsi_bufflen(scsi) - resid < scsi->underflow &&
106 !(rsp_flags & FCP_SNS_LEN_VAL) &&
107 fcp_rsp->resp.fr_status == SAM_STAT_GOOD)
108 set_host_byte(scsi, DID_ERROR);
109 }
110}
111
112#endif