aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_fsf.c
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_fsf.c
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_fsf.c')
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c97
1 files changed, 18 insertions, 79 deletions
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))