aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c147
1 files changed, 72 insertions, 75 deletions
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 48aa16a40d93..2b9dfea9f254 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -2080,73 +2080,7 @@ static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi)
2080 sizeof(blktrc)); 2080 sizeof(blktrc));
2081} 2081}
2082 2082
2083static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req) 2083static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req)
2084{
2085 struct scsi_cmnd *scpnt;
2086 struct fcp_resp_with_ext *fcp_rsp;
2087 unsigned long flags;
2088
2089 read_lock_irqsave(&req->adapter->abort_lock, flags);
2090
2091 scpnt = req->data;
2092 if (unlikely(!scpnt)) {
2093 read_unlock_irqrestore(&req->adapter->abort_lock, flags);
2094 return;
2095 }
2096
2097 if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) {
2098 set_host_byte(scpnt, DID_TRANSPORT_DISRUPTED);
2099 goto skip_fsfstatus;
2100 }
2101
2102 switch (req->qtcb->header.fsf_status) {
2103 case FSF_INCONSISTENT_PROT_DATA:
2104 case FSF_INVALID_PROT_PARM:
2105 set_host_byte(scpnt, DID_ERROR);
2106 goto skip_fsfstatus;
2107 case FSF_BLOCK_GUARD_CHECK_FAILURE:
2108 zfcp_scsi_dif_sense_error(scpnt, 0x1);
2109 goto skip_fsfstatus;
2110 case FSF_APP_TAG_CHECK_FAILURE:
2111 zfcp_scsi_dif_sense_error(scpnt, 0x2);
2112 goto skip_fsfstatus;
2113 case FSF_REF_TAG_CHECK_FAILURE:
2114 zfcp_scsi_dif_sense_error(scpnt, 0x3);
2115 goto skip_fsfstatus;
2116 }
2117 fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp;
2118 zfcp_fc_eval_fcp_rsp(fcp_rsp, scpnt);
2119
2120skip_fsfstatus:
2121 zfcp_fsf_req_trace(req, scpnt);
2122 zfcp_dbf_scsi_result(req->adapter->dbf, scpnt, req);
2123
2124 scpnt->host_scribble = NULL;
2125 (scpnt->scsi_done) (scpnt);
2126 /*
2127 * We must hold this lock until scsi_done has been called.
2128 * Otherwise we may call scsi_done after abort regarding this
2129 * command has completed.
2130 * Note: scsi_done must not block!
2131 */
2132 read_unlock_irqrestore(&req->adapter->abort_lock, flags);
2133}
2134
2135static void zfcp_fsf_send_fcp_ctm_handler(struct zfcp_fsf_req *req)
2136{
2137 struct fcp_resp_with_ext *fcp_rsp;
2138 struct fcp_resp_rsp_info *rsp_info;
2139
2140 fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp;
2141 rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1];
2142
2143 if ((rsp_info->rsp_code != FCP_TMF_CMPL) ||
2144 (req->status & ZFCP_STATUS_FSFREQ_ERROR))
2145 req->status |= ZFCP_STATUS_FSFREQ_TMFUNCFAILED;
2146}
2147
2148
2149static void zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *req)
2150{ 2084{
2151 struct scsi_cmnd *scmnd = req->data; 2085 struct scsi_cmnd *scmnd = req->data;
2152 struct scsi_device *sdev = scmnd->device; 2086 struct scsi_device *sdev = scmnd->device;
@@ -2154,7 +2088,7 @@ static void zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *req)
2154 struct fsf_qtcb_header *header = &req->qtcb->header; 2088 struct fsf_qtcb_header *header = &req->qtcb->header;
2155 2089
2156 if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) 2090 if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR))
2157 goto skip_fsfstatus; 2091 return;
2158 2092
2159 switch (header->fsf_status) { 2093 switch (header->fsf_status) {
2160 case FSF_HANDLE_MISMATCH: 2094 case FSF_HANDLE_MISMATCH:
@@ -2211,12 +2145,60 @@ static void zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *req)
2211 req->status |= ZFCP_STATUS_FSFREQ_ERROR; 2145 req->status |= ZFCP_STATUS_FSFREQ_ERROR;
2212 break; 2146 break;
2213 } 2147 }
2214skip_fsfstatus: 2148}
2215 if (req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT) 2149
2216 zfcp_fsf_send_fcp_ctm_handler(req); 2150static void zfcp_fsf_fcp_cmnd_handler(struct zfcp_fsf_req *req)
2217 else { 2151{
2218 zfcp_fsf_send_fcp_command_task_handler(req); 2152 struct scsi_cmnd *scpnt;
2153 struct fcp_resp_with_ext *fcp_rsp;
2154 unsigned long flags;
2155
2156 zfcp_fsf_fcp_handler_common(req);
2157
2158 read_lock_irqsave(&req->adapter->abort_lock, flags);
2159
2160 scpnt = req->data;
2161 if (unlikely(!scpnt)) {
2162 read_unlock_irqrestore(&req->adapter->abort_lock, flags);
2163 return;
2219 } 2164 }
2165
2166 if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) {
2167 set_host_byte(scpnt, DID_TRANSPORT_DISRUPTED);
2168 goto skip_fsfstatus;
2169 }
2170
2171 switch (req->qtcb->header.fsf_status) {
2172 case FSF_INCONSISTENT_PROT_DATA:
2173 case FSF_INVALID_PROT_PARM:
2174 set_host_byte(scpnt, DID_ERROR);
2175 goto skip_fsfstatus;
2176 case FSF_BLOCK_GUARD_CHECK_FAILURE:
2177 zfcp_scsi_dif_sense_error(scpnt, 0x1);
2178 goto skip_fsfstatus;
2179 case FSF_APP_TAG_CHECK_FAILURE:
2180 zfcp_scsi_dif_sense_error(scpnt, 0x2);
2181 goto skip_fsfstatus;
2182 case FSF_REF_TAG_CHECK_FAILURE:
2183 zfcp_scsi_dif_sense_error(scpnt, 0x3);
2184 goto skip_fsfstatus;
2185 }
2186 fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp;
2187 zfcp_fc_eval_fcp_rsp(fcp_rsp, scpnt);
2188
2189skip_fsfstatus:
2190 zfcp_fsf_req_trace(req, scpnt);
2191 zfcp_dbf_scsi_result(req->adapter->dbf, scpnt, req);
2192
2193 scpnt->host_scribble = NULL;
2194 (scpnt->scsi_done) (scpnt);
2195 /*
2196 * We must hold this lock until scsi_done has been called.
2197 * Otherwise we may call scsi_done after abort regarding this
2198 * command has completed.
2199 * Note: scsi_done must not block!
2200 */
2201 read_unlock_irqrestore(&req->adapter->abort_lock, flags);
2220} 2202}
2221 2203
2222static int zfcp_fsf_set_data_dir(struct scsi_cmnd *scsi_cmnd, u32 *data_dir) 2204static int zfcp_fsf_set_data_dir(struct scsi_cmnd *scsi_cmnd, u32 *data_dir)
@@ -2299,7 +2281,7 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *scsi_cmnd)
2299 io = &req->qtcb->bottom.io; 2281 io = &req->qtcb->bottom.io;
2300 req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; 2282 req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
2301 req->data = scsi_cmnd; 2283 req->data = scsi_cmnd;
2302 req->handler = zfcp_fsf_send_fcp_command_handler; 2284 req->handler = zfcp_fsf_fcp_cmnd_handler;
2303 req->qtcb->header.lun_handle = zfcp_sdev->lun_handle; 2285 req->qtcb->header.lun_handle = zfcp_sdev->lun_handle;
2304 req->qtcb->header.port_handle = zfcp_sdev->port->handle; 2286 req->qtcb->header.port_handle = zfcp_sdev->port->handle;
2305 io->service_class = FSF_CLASS_3; 2287 io->service_class = FSF_CLASS_3;
@@ -2345,6 +2327,21 @@ out:
2345 return retval; 2327 return retval;
2346} 2328}
2347 2329
2330static void zfcp_fsf_fcp_task_mgmt_handler(struct zfcp_fsf_req *req)
2331{
2332 struct fcp_resp_with_ext *fcp_rsp;
2333 struct fcp_resp_rsp_info *rsp_info;
2334
2335 zfcp_fsf_fcp_handler_common(req);
2336
2337 fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp;
2338 rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1];
2339
2340 if ((rsp_info->rsp_code != FCP_TMF_CMPL) ||
2341 (req->status & ZFCP_STATUS_FSFREQ_ERROR))
2342 req->status |= ZFCP_STATUS_FSFREQ_TMFUNCFAILED;
2343}
2344
2348/** 2345/**
2349 * zfcp_fsf_fcp_task_mgmt - send SCSI task management command 2346 * zfcp_fsf_fcp_task_mgmt - send SCSI task management command
2350 * @scmnd: SCSI command to send the task management command for 2347 * @scmnd: SCSI command to send the task management command for
@@ -2378,7 +2375,7 @@ struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_cmnd *scmnd,
2378 2375
2379 req->status |= ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT; 2376 req->status |= ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT;
2380 req->data = scmnd; 2377 req->data = scmnd;
2381 req->handler = zfcp_fsf_send_fcp_command_handler; 2378 req->handler = zfcp_fsf_fcp_task_mgmt_handler;
2382 req->qtcb->header.lun_handle = zfcp_sdev->lun_handle; 2379 req->qtcb->header.lun_handle = zfcp_sdev->lun_handle;
2383 req->qtcb->header.port_handle = zfcp_sdev->port->handle; 2380 req->qtcb->header.port_handle = zfcp_sdev->port->handle;
2384 req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND; 2381 req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND;