aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
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
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')
-rw-r--r--drivers/s390/scsi/zfcp_dbf.c35
-rw-r--r--drivers/s390/scsi/zfcp_dbf.h3
-rw-r--r--drivers/s390/scsi/zfcp_def.h57
-rw-r--r--drivers/s390/scsi/zfcp_ext.h1
-rw-r--r--drivers/s390/scsi/zfcp_fc.h112
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c97
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c20
7 files changed, 156 insertions, 169 deletions
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index fe818cd29dc1..21e5316e5003 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -870,8 +870,9 @@ void _zfcp_dbf_scsi(const char *tag, const char *tag2, int level,
870 struct zfcp_dbf_scsi_record *rec = &dbf->scsi_buf; 870 struct zfcp_dbf_scsi_record *rec = &dbf->scsi_buf;
871 struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec; 871 struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec;
872 unsigned long flags; 872 unsigned long flags;
873 struct fcp_rsp_iu *fcp_rsp; 873 struct fcp_resp_with_ext *fcp_rsp;
874 char *fcp_rsp_info = NULL, *fcp_sns_info = NULL; 874 struct fcp_resp_rsp_info *fcp_rsp_info = NULL;
875 char *fcp_sns_info = NULL;
875 int offset = 0, buflen = 0; 876 int offset = 0, buflen = 0;
876 877
877 spin_lock_irqsave(&dbf->scsi_lock, flags); 878 spin_lock_irqsave(&dbf->scsi_lock, flags);
@@ -895,20 +896,22 @@ void _zfcp_dbf_scsi(const char *tag, const char *tag2, int level,
895 rec->scsi_allowed = scsi_cmnd->allowed; 896 rec->scsi_allowed = scsi_cmnd->allowed;
896 } 897 }
897 if (fsf_req != NULL) { 898 if (fsf_req != NULL) {
898 fcp_rsp = (struct fcp_rsp_iu *) 899 fcp_rsp = (struct fcp_resp_with_ext *)
899 &(fsf_req->qtcb->bottom.io.fcp_rsp); 900 &(fsf_req->qtcb->bottom.io.fcp_rsp);
900 fcp_rsp_info = (unsigned char *) &fcp_rsp[1]; 901 fcp_rsp_info = (struct fcp_resp_rsp_info *)
901 fcp_sns_info = 902 &fcp_rsp[1];
902 zfcp_get_fcp_sns_info_ptr(fcp_rsp); 903 fcp_sns_info = (char *) &fcp_rsp[1];
903 904 if (fcp_rsp->resp.fr_flags & FCP_RSP_LEN_VAL)
904 rec->rsp_validity = fcp_rsp->validity.value; 905 fcp_sns_info += fcp_rsp->ext.fr_sns_len;
905 rec->rsp_scsi_status = fcp_rsp->scsi_status; 906
906 rec->rsp_resid = fcp_rsp->fcp_resid; 907 rec->rsp_validity = fcp_rsp->resp.fr_flags;
907 if (fcp_rsp->validity.bits.fcp_rsp_len_valid) 908 rec->rsp_scsi_status = fcp_rsp->resp.fr_status;
908 rec->rsp_code = *(fcp_rsp_info + 3); 909 rec->rsp_resid = fcp_rsp->ext.fr_resid;
909 if (fcp_rsp->validity.bits.fcp_sns_len_valid) { 910 if (fcp_rsp->resp.fr_flags & FCP_RSP_LEN_VAL)
910 buflen = min((int)fcp_rsp->fcp_sns_len, 911 rec->rsp_code = fcp_rsp_info->rsp_code;
911 ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO); 912 if (fcp_rsp->resp.fr_flags & FCP_SNS_LEN_VAL) {
913 buflen = min(fcp_rsp->ext.fr_sns_len,
914 (u32)ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO);
912 rec->sns_info_len = buflen; 915 rec->sns_info_len = buflen;
913 memcpy(rec->sns_info, fcp_sns_info, 916 memcpy(rec->sns_info, fcp_sns_info,
914 min(buflen, 917 min(buflen,
diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h
index 6b1461e8f847..c3e25702df5b 100644
--- a/drivers/s390/scsi/zfcp_dbf.h
+++ b/drivers/s390/scsi/zfcp_dbf.h
@@ -22,6 +22,7 @@
22#ifndef ZFCP_DBF_H 22#ifndef ZFCP_DBF_H
23#define ZFCP_DBF_H 23#define ZFCP_DBF_H
24 24
25#include <scsi/fc/fc_fcp.h>
25#include "zfcp_ext.h" 26#include "zfcp_ext.h"
26#include "zfcp_fsf.h" 27#include "zfcp_fsf.h"
27#include "zfcp_def.h" 28#include "zfcp_def.h"
@@ -343,7 +344,7 @@ static inline
343void zfcp_dbf_scsi_devreset(const char *tag, u8 flag, struct zfcp_unit *unit, 344void zfcp_dbf_scsi_devreset(const char *tag, u8 flag, struct zfcp_unit *unit,
344 struct scsi_cmnd *scsi_cmnd) 345 struct scsi_cmnd *scsi_cmnd)
345{ 346{
346 zfcp_dbf_scsi(flag == FCP_TARGET_RESET ? "trst" : "lrst", tag, 1, 347 zfcp_dbf_scsi(flag == FCP_TMF_TGT_RESET ? "trst" : "lrst", tag, 1,
347 unit->port->adapter->dbf, scsi_cmnd, NULL, 0); 348 unit->port->adapter->dbf, scsi_cmnd, NULL, 0);
348} 349}
349 350
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 08fa31302f75..0317e7f20850 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -73,65 +73,8 @@
73 73
74/*************** FIBRE CHANNEL PROTOCOL SPECIFIC DEFINES ********************/ 74/*************** FIBRE CHANNEL PROTOCOL SPECIFIC DEFINES ********************/
75 75
76/* task attribute values in FCP-2 FCP_CMND IU */
77#define SIMPLE_Q 0
78#define HEAD_OF_Q 1
79#define ORDERED_Q 2
80#define ACA_Q 4
81#define UNTAGGED 5
82
83/* task management flags in FCP-2 FCP_CMND IU */
84#define FCP_CLEAR_ACA 0x40
85#define FCP_TARGET_RESET 0x20
86#define FCP_LOGICAL_UNIT_RESET 0x10
87#define FCP_CLEAR_TASK_SET 0x04
88#define FCP_ABORT_TASK_SET 0x02
89
90#define FCP_CDB_LENGTH 16
91
92#define ZFCP_DID_MASK 0x00FFFFFF 76#define ZFCP_DID_MASK 0x00FFFFFF
93 77
94/* FCP(-2) FCP_CMND IU */
95struct fcp_cmnd_iu {
96 u64 fcp_lun; /* FCP logical unit number */
97 u8 crn; /* command reference number */
98 u8 reserved0:5; /* reserved */
99 u8 task_attribute:3; /* task attribute */
100 u8 task_management_flags; /* task management flags */
101 u8 add_fcp_cdb_length:6; /* additional FCP_CDB length */
102 u8 rddata:1; /* read data */
103 u8 wddata:1; /* write data */
104 u8 fcp_cdb[FCP_CDB_LENGTH];
105} __attribute__((packed));
106
107/* FCP(-2) FCP_RSP IU */
108struct fcp_rsp_iu {
109 u8 reserved0[10];
110 union {
111 struct {
112 u8 reserved1:3;
113 u8 fcp_conf_req:1;
114 u8 fcp_resid_under:1;
115 u8 fcp_resid_over:1;
116 u8 fcp_sns_len_valid:1;
117 u8 fcp_rsp_len_valid:1;
118 } bits;
119 u8 value;
120 } validity;
121 u8 scsi_status;
122 u32 fcp_resid;
123 u32 fcp_sns_len;
124 u32 fcp_rsp_len;
125} __attribute__((packed));
126
127
128#define RSP_CODE_GOOD 0
129#define RSP_CODE_LENGTH_MISMATCH 1
130#define RSP_CODE_FIELD_INVALID 2
131#define RSP_CODE_RO_MISMATCH 3
132#define RSP_CODE_TASKMAN_UNSUPP 4
133#define RSP_CODE_TASKMAN_FAILED 5
134
135/* see fc-fs */ 78/* see fc-fs */
136#define LS_RSCN 0x61 79#define LS_RSCN 0x61
137#define LS_LOGO 0x05 80#define LS_LOGO 0x05
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index d372146af38d..3832fe0ae2e4 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -154,7 +154,6 @@ extern void zfcp_qdio_close(struct zfcp_qdio *);
154extern struct zfcp_data zfcp_data; 154extern struct zfcp_data zfcp_data;
155extern int zfcp_adapter_scsi_register(struct zfcp_adapter *); 155extern int zfcp_adapter_scsi_register(struct zfcp_adapter *);
156extern void zfcp_adapter_scsi_unregister(struct zfcp_adapter *); 156extern void zfcp_adapter_scsi_unregister(struct zfcp_adapter *);
157extern char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *);
158extern struct fc_function_template zfcp_transport_functions; 157extern struct fc_function_template zfcp_transport_functions;
159extern void zfcp_scsi_rport_work(struct work_struct *); 158extern void zfcp_scsi_rport_work(struct work_struct *);
160extern void zfcp_scsi_schedule_rport_register(struct zfcp_port *); 159extern void zfcp_scsi_schedule_rport_register(struct zfcp_port *);
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
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index b6f12c826b79..5f4cd03797e9 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -11,6 +11,7 @@
11 11
12#include <linux/blktrace_api.h> 12#include <linux/blktrace_api.h>
13#include "zfcp_ext.h" 13#include "zfcp_ext.h"
14#include "zfcp_fc.h"
14#include "zfcp_dbf.h" 15#include "zfcp_dbf.h"
15 16
16static void zfcp_fsf_request_timeout_handler(unsigned long data) 17static void zfcp_fsf_request_timeout_handler(unsigned long data)
@@ -2159,10 +2160,7 @@ static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi)
2159static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req) 2160static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req)
2160{ 2161{
2161 struct scsi_cmnd *scpnt; 2162 struct scsi_cmnd *scpnt;
2162 struct fcp_rsp_iu *fcp_rsp_iu = (struct fcp_rsp_iu *) 2163 struct fcp_resp_with_ext *fcp_rsp;
2163 &(req->qtcb->bottom.io.fcp_rsp);
2164 u32 sns_len;
2165 char *fcp_rsp_info = (unsigned char *) &fcp_rsp_iu[1];
2166 unsigned long flags; 2164 unsigned long flags;
2167 2165
2168 read_lock_irqsave(&req->adapter->abort_lock, flags); 2166 read_lock_irqsave(&req->adapter->abort_lock, flags);
@@ -2183,37 +2181,11 @@ static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req)
2183 goto skip_fsfstatus; 2181 goto skip_fsfstatus;
2184 } 2182 }
2185 2183
2186 set_msg_byte(scpnt, COMMAND_COMPLETE); 2184 fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp;
2187 2185 zfcp_fc_eval_fcp_rsp(fcp_rsp, scpnt);
2188 scpnt->result |= fcp_rsp_iu->scsi_status;
2189 2186
2190 zfcp_fsf_req_trace(req, scpnt); 2187 zfcp_fsf_req_trace(req, scpnt);
2191 2188
2192 if (unlikely(fcp_rsp_iu->validity.bits.fcp_rsp_len_valid)) {
2193 if (fcp_rsp_info[3] == RSP_CODE_GOOD)
2194 set_host_byte(scpnt, DID_OK);
2195 else {
2196 set_host_byte(scpnt, DID_ERROR);
2197 goto skip_fsfstatus;
2198 }
2199 }
2200
2201 if (unlikely(fcp_rsp_iu->validity.bits.fcp_sns_len_valid)) {
2202 sns_len = FSF_FCP_RSP_SIZE - sizeof(struct fcp_rsp_iu) +
2203 fcp_rsp_iu->fcp_rsp_len;
2204 sns_len = min(sns_len, (u32) SCSI_SENSE_BUFFERSIZE);
2205 sns_len = min(sns_len, fcp_rsp_iu->fcp_sns_len);
2206
2207 memcpy(scpnt->sense_buffer,
2208 zfcp_get_fcp_sns_info_ptr(fcp_rsp_iu), sns_len);
2209 }
2210
2211 if (unlikely(fcp_rsp_iu->validity.bits.fcp_resid_under)) {
2212 scsi_set_resid(scpnt, fcp_rsp_iu->fcp_resid);
2213 if (scsi_bufflen(scpnt) - scsi_get_resid(scpnt) <
2214 scpnt->underflow)
2215 set_host_byte(scpnt, DID_ERROR);
2216 }
2217skip_fsfstatus: 2189skip_fsfstatus:
2218 if (scpnt->result != 0) 2190 if (scpnt->result != 0)
2219 zfcp_dbf_scsi_result("erro", 3, req->adapter->dbf, scpnt, req); 2191 zfcp_dbf_scsi_result("erro", 3, req->adapter->dbf, scpnt, req);
@@ -2235,11 +2207,13 @@ skip_fsfstatus:
2235 2207
2236static void zfcp_fsf_send_fcp_ctm_handler(struct zfcp_fsf_req *req) 2208static void zfcp_fsf_send_fcp_ctm_handler(struct zfcp_fsf_req *req)
2237{ 2209{
2238 struct fcp_rsp_iu *fcp_rsp_iu = (struct fcp_rsp_iu *) 2210 struct fcp_resp_with_ext *fcp_rsp;
2239 &(req->qtcb->bottom.io.fcp_rsp); 2211 struct fcp_resp_rsp_info *rsp_info;
2240 char *fcp_rsp_info = (unsigned char *) &fcp_rsp_iu[1];
2241 2212
2242 if ((fcp_rsp_info[3] != RSP_CODE_GOOD) || 2213 fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp;
2214 rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1];
2215
2216 if ((rsp_info->rsp_code != FCP_TMF_CMPL) ||
2243 (req->status & ZFCP_STATUS_FSFREQ_ERROR)) 2217 (req->status & ZFCP_STATUS_FSFREQ_ERROR))
2244 req->status |= ZFCP_STATUS_FSFREQ_TMFUNCFAILED; 2218 req->status |= ZFCP_STATUS_FSFREQ_TMFUNCFAILED;
2245} 2219}
@@ -2324,20 +2298,6 @@ skip_fsfstatus:
2324 } 2298 }
2325} 2299}
2326 2300
2327static void zfcp_set_fcp_dl(struct fcp_cmnd_iu *fcp_cmd, u32 fcp_dl)
2328{
2329 u32 *fcp_dl_ptr;
2330
2331 /*
2332 * fcp_dl_addr = start address of fcp_cmnd structure +
2333 * size of fixed part + size of dynamically sized add_dcp_cdb field
2334 * SEE FCP-2 documentation
2335 */
2336 fcp_dl_ptr = (u32 *) ((unsigned char *) &fcp_cmd[1] +
2337 (fcp_cmd->add_fcp_cdb_length << 2));
2338 *fcp_dl_ptr = fcp_dl;
2339}
2340
2341/** 2301/**
2342 * zfcp_fsf_send_fcp_command_task - initiate an FCP command (for a SCSI command) 2302 * zfcp_fsf_send_fcp_command_task - initiate an FCP command (for a SCSI command)
2343 * @unit: unit where command is sent to 2303 * @unit: unit where command is sent to
@@ -2347,7 +2307,7 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit,
2347 struct scsi_cmnd *scsi_cmnd) 2307 struct scsi_cmnd *scsi_cmnd)
2348{ 2308{
2349 struct zfcp_fsf_req *req; 2309 struct zfcp_fsf_req *req;
2350 struct fcp_cmnd_iu *fcp_cmnd_iu; 2310 struct fcp_cmnd *fcp_cmnd;
2351 unsigned int sbtype = SBAL_FLAGS0_TYPE_READ; 2311 unsigned int sbtype = SBAL_FLAGS0_TYPE_READ;
2352 int real_bytes, retval = -EIO; 2312 int real_bytes, retval = -EIO;
2353 struct zfcp_adapter *adapter = unit->port->adapter; 2313 struct zfcp_adapter *adapter = unit->port->adapter;
@@ -2379,16 +2339,14 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit,
2379 req->qtcb->header.lun_handle = unit->handle; 2339 req->qtcb->header.lun_handle = unit->handle;
2380 req->qtcb->header.port_handle = unit->port->handle; 2340 req->qtcb->header.port_handle = unit->port->handle;
2381 req->qtcb->bottom.io.service_class = FSF_CLASS_3; 2341 req->qtcb->bottom.io.service_class = FSF_CLASS_3;
2342 req->qtcb->bottom.io.fcp_cmnd_length = FCP_CMND_LEN;
2382 2343
2383 scsi_cmnd->host_scribble = (unsigned char *) req->req_id; 2344 scsi_cmnd->host_scribble = (unsigned char *) req->req_id;
2384 2345
2385 fcp_cmnd_iu = (struct fcp_cmnd_iu *) &(req->qtcb->bottom.io.fcp_cmnd);
2386 fcp_cmnd_iu->fcp_lun = unit->fcp_lun;
2387 /* 2346 /*
2388 * set depending on data direction: 2347 * set depending on data direction:
2389 * data direction bits in SBALE (SB Type) 2348 * data direction bits in SBALE (SB Type)
2390 * data direction bits in QTCB 2349 * data direction bits in QTCB
2391 * data direction bits in FCP_CMND IU
2392 */ 2350 */
2393 switch (scsi_cmnd->sc_data_direction) { 2351 switch (scsi_cmnd->sc_data_direction) {
2394 case DMA_NONE: 2352 case DMA_NONE:
@@ -2396,32 +2354,17 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit,
2396 break; 2354 break;
2397 case DMA_FROM_DEVICE: 2355 case DMA_FROM_DEVICE:
2398 req->qtcb->bottom.io.data_direction = FSF_DATADIR_READ; 2356 req->qtcb->bottom.io.data_direction = FSF_DATADIR_READ;
2399 fcp_cmnd_iu->rddata = 1;
2400 break; 2357 break;
2401 case DMA_TO_DEVICE: 2358 case DMA_TO_DEVICE:
2402 req->qtcb->bottom.io.data_direction = FSF_DATADIR_WRITE; 2359 req->qtcb->bottom.io.data_direction = FSF_DATADIR_WRITE;
2403 sbtype = SBAL_FLAGS0_TYPE_WRITE; 2360 sbtype = SBAL_FLAGS0_TYPE_WRITE;
2404 fcp_cmnd_iu->wddata = 1;
2405 break; 2361 break;
2406 case DMA_BIDIRECTIONAL: 2362 case DMA_BIDIRECTIONAL:
2407 goto failed_scsi_cmnd; 2363 goto failed_scsi_cmnd;
2408 } 2364 }
2409 2365
2410 if (likely((scsi_cmnd->device->simple_tags) || 2366 fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd;
2411 ((atomic_read(&unit->status) & ZFCP_STATUS_UNIT_READONLY) && 2367 zfcp_fc_scsi_to_fcp(fcp_cmnd, scsi_cmnd);
2412 (atomic_read(&unit->status) & ZFCP_STATUS_UNIT_SHARED))))
2413 fcp_cmnd_iu->task_attribute = SIMPLE_Q;
2414 else
2415 fcp_cmnd_iu->task_attribute = UNTAGGED;
2416
2417 if (unlikely(scsi_cmnd->cmd_len > FCP_CDB_LENGTH))
2418 fcp_cmnd_iu->add_fcp_cdb_length =
2419 (scsi_cmnd->cmd_len - FCP_CDB_LENGTH) >> 2;
2420
2421 memcpy(fcp_cmnd_iu->fcp_cdb, scsi_cmnd->cmnd, scsi_cmnd->cmd_len);
2422
2423 req->qtcb->bottom.io.fcp_cmnd_length = sizeof(struct fcp_cmnd_iu) +
2424 fcp_cmnd_iu->add_fcp_cdb_length + sizeof(u32);
2425 2368
2426 real_bytes = zfcp_qdio_sbals_from_sg(qdio, &req->queue_req, sbtype, 2369 real_bytes = zfcp_qdio_sbals_from_sg(qdio, &req->queue_req, sbtype,
2427 scsi_sglist(scsi_cmnd), 2370 scsi_sglist(scsi_cmnd),
@@ -2439,8 +2382,6 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit,
2439 goto failed_scsi_cmnd; 2382 goto failed_scsi_cmnd;
2440 } 2383 }
2441 2384
2442 zfcp_set_fcp_dl(fcp_cmnd_iu, real_bytes);
2443
2444 retval = zfcp_fsf_req_send(req); 2385 retval = zfcp_fsf_req_send(req);
2445 if (unlikely(retval)) 2386 if (unlikely(retval))
2446 goto failed_scsi_cmnd; 2387 goto failed_scsi_cmnd;
@@ -2466,7 +2407,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *unit, u8 tm_flags)
2466{ 2407{
2467 struct qdio_buffer_element *sbale; 2408 struct qdio_buffer_element *sbale;
2468 struct zfcp_fsf_req *req = NULL; 2409 struct zfcp_fsf_req *req = NULL;
2469 struct fcp_cmnd_iu *fcp_cmnd_iu; 2410 struct fcp_cmnd *fcp_cmnd;
2470 struct zfcp_qdio *qdio = unit->port->adapter->qdio; 2411 struct zfcp_qdio *qdio = unit->port->adapter->qdio;
2471 2412
2472 if (unlikely(!(atomic_read(&unit->status) & 2413 if (unlikely(!(atomic_read(&unit->status) &
@@ -2492,16 +2433,14 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *unit, u8 tm_flags)
2492 req->qtcb->header.port_handle = unit->port->handle; 2433 req->qtcb->header.port_handle = unit->port->handle;
2493 req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND; 2434 req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND;
2494 req->qtcb->bottom.io.service_class = FSF_CLASS_3; 2435 req->qtcb->bottom.io.service_class = FSF_CLASS_3;
2495 req->qtcb->bottom.io.fcp_cmnd_length = sizeof(struct fcp_cmnd_iu) + 2436 req->qtcb->bottom.io.fcp_cmnd_length = FCP_CMND_LEN;
2496 sizeof(u32);
2497 2437
2498 sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req); 2438 sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req);
2499 sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE; 2439 sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE;
2500 sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; 2440 sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
2501 2441
2502 fcp_cmnd_iu = (struct fcp_cmnd_iu *) &req->qtcb->bottom.io.fcp_cmnd; 2442 fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd;
2503 fcp_cmnd_iu->fcp_lun = unit->fcp_lun; 2443 zfcp_fc_fcp_tm(fcp_cmnd, unit->device, tm_flags);
2504 fcp_cmnd_iu->task_management_flags = tm_flags;
2505 2444
2506 zfcp_fsf_start_timer(req, ZFCP_SCSI_ER_TIMEOUT); 2445 zfcp_fsf_start_timer(req, ZFCP_SCSI_ER_TIMEOUT);
2507 if (!zfcp_fsf_req_send(req)) 2446 if (!zfcp_fsf_req_send(req))
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 0ecec9c1b490..3d168410036b 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -9,6 +9,8 @@
9#define KMSG_COMPONENT "zfcp" 9#define KMSG_COMPONENT "zfcp"
10#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 10#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
11 11
12#include <linux/types.h>
13#include <scsi/fc/fc_fcp.h>
12#include <asm/atomic.h> 14#include <asm/atomic.h>
13#include "zfcp_ext.h" 15#include "zfcp_ext.h"
14#include "zfcp_dbf.h" 16#include "zfcp_dbf.h"
@@ -17,18 +19,6 @@ static unsigned int default_depth = 32;
17module_param_named(queue_depth, default_depth, uint, 0600); 19module_param_named(queue_depth, default_depth, uint, 0600);
18MODULE_PARM_DESC(queue_depth, "Default queue depth for new SCSI devices"); 20MODULE_PARM_DESC(queue_depth, "Default queue depth for new SCSI devices");
19 21
20/* Find start of Sense Information in FCP response unit*/
21char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *fcp_rsp_iu)
22{
23 char *fcp_sns_info_ptr;
24
25 fcp_sns_info_ptr = (unsigned char *) &fcp_rsp_iu[1];
26 if (fcp_rsp_iu->validity.bits.fcp_rsp_len_valid)
27 fcp_sns_info_ptr += fcp_rsp_iu->fcp_rsp_len;
28
29 return fcp_sns_info_ptr;
30}
31
32static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth, 22static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth,
33 int reason) 23 int reason)
34{ 24{
@@ -283,12 +273,12 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
283 273
284static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt) 274static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
285{ 275{
286 return zfcp_task_mgmt_function(scpnt, FCP_LOGICAL_UNIT_RESET); 276 return zfcp_task_mgmt_function(scpnt, FCP_TMF_LUN_RESET);
287} 277}
288 278
289static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt) 279static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt)
290{ 280{
291 return zfcp_task_mgmt_function(scpnt, FCP_TARGET_RESET); 281 return zfcp_task_mgmt_function(scpnt, FCP_TMF_TGT_RESET);
292} 282}
293 283
294static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt) 284static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
@@ -325,7 +315,7 @@ int zfcp_adapter_scsi_register(struct zfcp_adapter *adapter)
325 adapter->scsi_host->max_lun = 1; 315 adapter->scsi_host->max_lun = 1;
326 adapter->scsi_host->max_channel = 0; 316 adapter->scsi_host->max_channel = 0;
327 adapter->scsi_host->unique_id = dev_id.devno; 317 adapter->scsi_host->unique_id = dev_id.devno;
328 adapter->scsi_host->max_cmd_len = 255; 318 adapter->scsi_host->max_cmd_len = 16; /* in struct fcp_cmnd */
329 adapter->scsi_host->transportt = zfcp_data.scsi_transport_template; 319 adapter->scsi_host->transportt = zfcp_data.scsi_transport_template;
330 320
331 adapter->scsi_host->hostdata[0] = (unsigned long) adapter; 321 adapter->scsi_host->hostdata[0] = (unsigned long) adapter;