diff options
author | Christof Schmitt <christof.schmitt@de.ibm.com> | 2009-11-24 10:54:08 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-12-04 13:02:10 -0500 |
commit | 4318e08c84e4916ac463002ffb7f9901ddb3c385 (patch) | |
tree | ebce82e85a0d2010c98d0585a5b94113981ee357 /drivers/s390 | |
parent | 8830271c4819d86d8e87202a1fe8da0bb58912a2 (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.c | 35 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_dbf.h | 3 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_def.h | 57 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_ext.h | 1 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fc.h | 112 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 97 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_scsi.c | 20 |
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 | |||
343 | void zfcp_dbf_scsi_devreset(const char *tag, u8 flag, struct zfcp_unit *unit, | 344 | void 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 */ | ||
95 | struct 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 */ | ||
108 | struct 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 *); | |||
154 | extern struct zfcp_data zfcp_data; | 154 | extern struct zfcp_data zfcp_data; |
155 | extern int zfcp_adapter_scsi_register(struct zfcp_adapter *); | 155 | extern int zfcp_adapter_scsi_register(struct zfcp_adapter *); |
156 | extern void zfcp_adapter_scsi_unregister(struct zfcp_adapter *); | 156 | extern void zfcp_adapter_scsi_unregister(struct zfcp_adapter *); |
157 | extern char *zfcp_get_fcp_sns_info_ptr(struct fcp_rsp_iu *); | ||
158 | extern struct fc_function_template zfcp_transport_functions; | 157 | extern struct fc_function_template zfcp_transport_functions; |
159 | extern void zfcp_scsi_rport_work(struct work_struct *); | 158 | extern void zfcp_scsi_rport_work(struct work_struct *); |
160 | extern void zfcp_scsi_schedule_rport_register(struct zfcp_port *); | 159 | extern 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 | */ | ||
22 | static inline | ||
23 | void 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 | */ | ||
57 | static inline | ||
58 | void 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 | */ | ||
69 | static inline | ||
70 | void 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 | ||
16 | static void zfcp_fsf_request_timeout_handler(unsigned long data) | 17 | static 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) | |||
2159 | static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req) | 2160 | static 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 | } | ||
2217 | skip_fsfstatus: | 2189 | skip_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 | ||
2236 | static void zfcp_fsf_send_fcp_ctm_handler(struct zfcp_fsf_req *req) | 2208 | static 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 | ||
2327 | static 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; | |||
17 | module_param_named(queue_depth, default_depth, uint, 0600); | 19 | module_param_named(queue_depth, default_depth, uint, 0600); |
18 | MODULE_PARM_DESC(queue_depth, "Default queue depth for new SCSI devices"); | 20 | MODULE_PARM_DESC(queue_depth, "Default queue depth for new SCSI devices"); |
19 | 21 | ||
20 | /* Find start of Sense Information in FCP response unit*/ | ||
21 | char *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 | |||
32 | static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth, | 22 | static 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 | ||
284 | static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt) | 274 | static 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 | ||
289 | static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt) | 279 | static 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 | ||
294 | static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt) | 284 | static 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; |