diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-04 18:15:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-04 18:15:15 -0400 |
commit | 03da30986793385af57eeca3296253c887b742e6 (patch) | |
tree | 9c46dbe51c9d0856990649dd917ab45474b7be87 /drivers/s390/scsi/zfcp_fsf.c | |
parent | 6ba74014c1ab0e37af7de6f64b4eccbbae3cb9e7 (diff) | |
parent | 339f4f4eab80caa6cf0d39fb057ad6ddb84ba91e (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (276 commits)
[SCSI] zfcp: Trigger logging in the FCP channel on qdio error conditions
[SCSI] zfcp: Introduce experimental support for DIF/DIX
[SCSI] zfcp: Enable data division support for FCP devices
[SCSI] zfcp: Prevent access on uninitialized memory.
[SCSI] zfcp: Post events through FC transport class
[SCSI] zfcp: Cleanup QDIO attachment and improve processing.
[SCSI] zfcp: Cleanup function parameters for sbal value.
[SCSI] zfcp: Use correct width for timer_interval field
[SCSI] zfcp: Remove SCSI device when removing unit
[SCSI] zfcp: Use memdup_user and kstrdup
[SCSI] zfcp: Fix retry after failed "open port" erp action
[SCSI] zfcp: Fail erp after timeout
[SCSI] zfcp: Use forced_reopen in terminate_rport_io callback
[SCSI] zfcp: Register SCSI devices after successful fc_remote_port_add
[SCSI] zfcp: Do not try "forced close" when port is already closed
[SCSI] zfcp: Do not unblock rport from REOPEN_PORT_FORCED
[SCSI] sd: add support for runtime PM
[SCSI] implement runtime Power Management
[SCSI] convert to the new PM framework
[SCSI] Unify SAM_ and SAM_STAT_ macros
...
Diffstat (limited to 'drivers/s390/scsi/zfcp_fsf.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 169 |
1 files changed, 113 insertions, 56 deletions
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 71663fb77310..9d1d7d1842ce 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -21,6 +21,7 @@ | |||
21 | static void zfcp_fsf_request_timeout_handler(unsigned long data) | 21 | static void zfcp_fsf_request_timeout_handler(unsigned long data) |
22 | { | 22 | { |
23 | struct zfcp_adapter *adapter = (struct zfcp_adapter *) data; | 23 | struct zfcp_adapter *adapter = (struct zfcp_adapter *) data; |
24 | zfcp_qdio_siosl(adapter); | ||
24 | zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, | 25 | zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, |
25 | "fsrth_1", NULL); | 26 | "fsrth_1", NULL); |
26 | } | 27 | } |
@@ -274,6 +275,7 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req) | |||
274 | break; | 275 | break; |
275 | case FSF_STATUS_READ_LINK_DOWN: | 276 | case FSF_STATUS_READ_LINK_DOWN: |
276 | zfcp_fsf_status_read_link_down(req); | 277 | zfcp_fsf_status_read_link_down(req); |
278 | zfcp_fc_enqueue_event(adapter, FCH_EVT_LINKDOWN, 0); | ||
277 | break; | 279 | break; |
278 | case FSF_STATUS_READ_LINK_UP: | 280 | case FSF_STATUS_READ_LINK_UP: |
279 | dev_info(&adapter->ccw_device->dev, | 281 | dev_info(&adapter->ccw_device->dev, |
@@ -286,6 +288,8 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req) | |||
286 | ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | | 288 | ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | |
287 | ZFCP_STATUS_COMMON_ERP_FAILED, | 289 | ZFCP_STATUS_COMMON_ERP_FAILED, |
288 | "fssrh_2", req); | 290 | "fssrh_2", req); |
291 | zfcp_fc_enqueue_event(adapter, FCH_EVT_LINKUP, 0); | ||
292 | |||
289 | break; | 293 | break; |
290 | case FSF_STATUS_READ_NOTIFICATION_LOST: | 294 | case FSF_STATUS_READ_NOTIFICATION_LOST: |
291 | if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_ACT_UPDATED) | 295 | if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_ACT_UPDATED) |
@@ -323,6 +327,7 @@ static void zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *req) | |||
323 | dev_err(&req->adapter->ccw_device->dev, | 327 | dev_err(&req->adapter->ccw_device->dev, |
324 | "The FCP adapter reported a problem " | 328 | "The FCP adapter reported a problem " |
325 | "that cannot be recovered\n"); | 329 | "that cannot be recovered\n"); |
330 | zfcp_qdio_siosl(req->adapter); | ||
326 | zfcp_erp_adapter_shutdown(req->adapter, 0, "fsfsqe1", req); | 331 | zfcp_erp_adapter_shutdown(req->adapter, 0, "fsfsqe1", req); |
327 | break; | 332 | break; |
328 | } | 333 | } |
@@ -413,6 +418,7 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req) | |||
413 | dev_err(&adapter->ccw_device->dev, | 418 | dev_err(&adapter->ccw_device->dev, |
414 | "0x%x is not a valid transfer protocol status\n", | 419 | "0x%x is not a valid transfer protocol status\n", |
415 | qtcb->prefix.prot_status); | 420 | qtcb->prefix.prot_status); |
421 | zfcp_qdio_siosl(adapter); | ||
416 | zfcp_erp_adapter_shutdown(adapter, 0, "fspse_9", req); | 422 | zfcp_erp_adapter_shutdown(adapter, 0, "fspse_9", req); |
417 | } | 423 | } |
418 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 424 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
@@ -495,7 +501,7 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req) | |||
495 | fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3; | 501 | fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3; |
496 | 502 | ||
497 | adapter->hydra_version = bottom->adapter_type; | 503 | adapter->hydra_version = bottom->adapter_type; |
498 | adapter->timer_ticks = bottom->timer_interval; | 504 | adapter->timer_ticks = bottom->timer_interval & ZFCP_FSF_TIMER_INT_MASK; |
499 | adapter->stat_read_buf_num = max(bottom->status_read_buf_num, | 505 | adapter->stat_read_buf_num = max(bottom->status_read_buf_num, |
500 | (u16)FSF_STATUS_READS_RECOM); | 506 | (u16)FSF_STATUS_READS_RECOM); |
501 | 507 | ||
@@ -523,6 +529,8 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req) | |||
523 | return -EIO; | 529 | return -EIO; |
524 | } | 530 | } |
525 | 531 | ||
532 | zfcp_scsi_set_prot(adapter); | ||
533 | |||
526 | return 0; | 534 | return 0; |
527 | } | 535 | } |
528 | 536 | ||
@@ -732,7 +740,7 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *req) | |||
732 | 740 | ||
733 | zfcp_reqlist_add(adapter->req_list, req); | 741 | zfcp_reqlist_add(adapter->req_list, req); |
734 | 742 | ||
735 | req->qdio_req.qdio_outb_usage = atomic_read(&qdio->req_q.count); | 743 | req->qdio_req.qdio_outb_usage = atomic_read(&qdio->req_q_free); |
736 | req->issued = get_clock(); | 744 | req->issued = get_clock(); |
737 | if (zfcp_qdio_send(qdio, &req->qdio_req)) { | 745 | if (zfcp_qdio_send(qdio, &req->qdio_req)) { |
738 | del_timer(&req->timer); | 746 | del_timer(&req->timer); |
@@ -959,8 +967,7 @@ static void zfcp_fsf_setup_ct_els_unchained(struct zfcp_qdio *qdio, | |||
959 | 967 | ||
960 | static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req, | 968 | static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req, |
961 | struct scatterlist *sg_req, | 969 | struct scatterlist *sg_req, |
962 | struct scatterlist *sg_resp, | 970 | struct scatterlist *sg_resp) |
963 | int max_sbals) | ||
964 | { | 971 | { |
965 | struct zfcp_adapter *adapter = req->adapter; | 972 | struct zfcp_adapter *adapter = req->adapter; |
966 | u32 feat = adapter->adapter_features; | 973 | u32 feat = adapter->adapter_features; |
@@ -983,18 +990,19 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req, | |||
983 | return 0; | 990 | return 0; |
984 | } | 991 | } |
985 | 992 | ||
986 | bytes = zfcp_qdio_sbals_from_sg(adapter->qdio, &req->qdio_req, | 993 | bytes = zfcp_qdio_sbals_from_sg(adapter->qdio, &req->qdio_req, sg_req); |
987 | sg_req, max_sbals); | ||
988 | if (bytes <= 0) | 994 | if (bytes <= 0) |
989 | return -EIO; | 995 | return -EIO; |
996 | zfcp_qdio_set_sbale_last(adapter->qdio, &req->qdio_req); | ||
990 | req->qtcb->bottom.support.req_buf_length = bytes; | 997 | req->qtcb->bottom.support.req_buf_length = bytes; |
991 | zfcp_qdio_skip_to_last_sbale(&req->qdio_req); | 998 | zfcp_qdio_skip_to_last_sbale(&req->qdio_req); |
992 | 999 | ||
993 | bytes = zfcp_qdio_sbals_from_sg(adapter->qdio, &req->qdio_req, | 1000 | bytes = zfcp_qdio_sbals_from_sg(adapter->qdio, &req->qdio_req, |
994 | sg_resp, max_sbals); | 1001 | sg_resp); |
995 | req->qtcb->bottom.support.resp_buf_length = bytes; | 1002 | req->qtcb->bottom.support.resp_buf_length = bytes; |
996 | if (bytes <= 0) | 1003 | if (bytes <= 0) |
997 | return -EIO; | 1004 | return -EIO; |
1005 | zfcp_qdio_set_sbale_last(adapter->qdio, &req->qdio_req); | ||
998 | 1006 | ||
999 | return 0; | 1007 | return 0; |
1000 | } | 1008 | } |
@@ -1002,11 +1010,11 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req, | |||
1002 | static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req, | 1010 | static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req, |
1003 | struct scatterlist *sg_req, | 1011 | struct scatterlist *sg_req, |
1004 | struct scatterlist *sg_resp, | 1012 | struct scatterlist *sg_resp, |
1005 | int max_sbals, unsigned int timeout) | 1013 | unsigned int timeout) |
1006 | { | 1014 | { |
1007 | int ret; | 1015 | int ret; |
1008 | 1016 | ||
1009 | ret = zfcp_fsf_setup_ct_els_sbals(req, sg_req, sg_resp, max_sbals); | 1017 | ret = zfcp_fsf_setup_ct_els_sbals(req, sg_req, sg_resp); |
1010 | if (ret) | 1018 | if (ret) |
1011 | return ret; | 1019 | return ret; |
1012 | 1020 | ||
@@ -1046,8 +1054,7 @@ int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port, | |||
1046 | } | 1054 | } |
1047 | 1055 | ||
1048 | req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; | 1056 | req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; |
1049 | ret = zfcp_fsf_setup_ct_els(req, ct->req, ct->resp, | 1057 | ret = zfcp_fsf_setup_ct_els(req, ct->req, ct->resp, timeout); |
1050 | ZFCP_FSF_MAX_SBALS_PER_REQ, timeout); | ||
1051 | if (ret) | 1058 | if (ret) |
1052 | goto failed_send; | 1059 | goto failed_send; |
1053 | 1060 | ||
@@ -1143,7 +1150,10 @@ int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id, | |||
1143 | } | 1150 | } |
1144 | 1151 | ||
1145 | req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; | 1152 | req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; |
1146 | ret = zfcp_fsf_setup_ct_els(req, els->req, els->resp, 2, timeout); | 1153 | |
1154 | zfcp_qdio_sbal_limit(qdio, &req->qdio_req, 2); | ||
1155 | |||
1156 | ret = zfcp_fsf_setup_ct_els(req, els->req, els->resp, timeout); | ||
1147 | 1157 | ||
1148 | if (ret) | 1158 | if (ret) |
1149 | goto failed_send; | 1159 | goto failed_send; |
@@ -2025,7 +2035,7 @@ static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi) | |||
2025 | blktrc.magic = ZFCP_BLK_DRV_DATA_MAGIC; | 2035 | blktrc.magic = ZFCP_BLK_DRV_DATA_MAGIC; |
2026 | if (req->status & ZFCP_STATUS_FSFREQ_ERROR) | 2036 | if (req->status & ZFCP_STATUS_FSFREQ_ERROR) |
2027 | blktrc.flags |= ZFCP_BLK_REQ_ERROR; | 2037 | blktrc.flags |= ZFCP_BLK_REQ_ERROR; |
2028 | blktrc.inb_usage = req->qdio_req.qdio_inb_usage; | 2038 | blktrc.inb_usage = 0; |
2029 | blktrc.outb_usage = req->qdio_req.qdio_outb_usage; | 2039 | blktrc.outb_usage = req->qdio_req.qdio_outb_usage; |
2030 | 2040 | ||
2031 | if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA && | 2041 | if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA && |
@@ -2035,9 +2045,13 @@ static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi) | |||
2035 | blktrc.fabric_lat = lat_in->fabric_lat * ticks; | 2045 | blktrc.fabric_lat = lat_in->fabric_lat * ticks; |
2036 | 2046 | ||
2037 | switch (req->qtcb->bottom.io.data_direction) { | 2047 | switch (req->qtcb->bottom.io.data_direction) { |
2048 | case FSF_DATADIR_DIF_READ_STRIP: | ||
2049 | case FSF_DATADIR_DIF_READ_CONVERT: | ||
2038 | case FSF_DATADIR_READ: | 2050 | case FSF_DATADIR_READ: |
2039 | lat = &unit->latencies.read; | 2051 | lat = &unit->latencies.read; |
2040 | break; | 2052 | break; |
2053 | case FSF_DATADIR_DIF_WRITE_INSERT: | ||
2054 | case FSF_DATADIR_DIF_WRITE_CONVERT: | ||
2041 | case FSF_DATADIR_WRITE: | 2055 | case FSF_DATADIR_WRITE: |
2042 | lat = &unit->latencies.write; | 2056 | lat = &unit->latencies.write; |
2043 | break; | 2057 | break; |
@@ -2078,6 +2092,21 @@ static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req) | |||
2078 | goto skip_fsfstatus; | 2092 | goto skip_fsfstatus; |
2079 | } | 2093 | } |
2080 | 2094 | ||
2095 | switch (req->qtcb->header.fsf_status) { | ||
2096 | case FSF_INCONSISTENT_PROT_DATA: | ||
2097 | case FSF_INVALID_PROT_PARM: | ||
2098 | set_host_byte(scpnt, DID_ERROR); | ||
2099 | goto skip_fsfstatus; | ||
2100 | case FSF_BLOCK_GUARD_CHECK_FAILURE: | ||
2101 | zfcp_scsi_dif_sense_error(scpnt, 0x1); | ||
2102 | goto skip_fsfstatus; | ||
2103 | case FSF_APP_TAG_CHECK_FAILURE: | ||
2104 | zfcp_scsi_dif_sense_error(scpnt, 0x2); | ||
2105 | goto skip_fsfstatus; | ||
2106 | case FSF_REF_TAG_CHECK_FAILURE: | ||
2107 | zfcp_scsi_dif_sense_error(scpnt, 0x3); | ||
2108 | goto skip_fsfstatus; | ||
2109 | } | ||
2081 | fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp; | 2110 | fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp; |
2082 | zfcp_fc_eval_fcp_rsp(fcp_rsp, scpnt); | 2111 | zfcp_fc_eval_fcp_rsp(fcp_rsp, scpnt); |
2083 | 2112 | ||
@@ -2187,6 +2216,44 @@ skip_fsfstatus: | |||
2187 | } | 2216 | } |
2188 | } | 2217 | } |
2189 | 2218 | ||
2219 | static int zfcp_fsf_set_data_dir(struct scsi_cmnd *scsi_cmnd, u32 *data_dir) | ||
2220 | { | ||
2221 | switch (scsi_get_prot_op(scsi_cmnd)) { | ||
2222 | case SCSI_PROT_NORMAL: | ||
2223 | switch (scsi_cmnd->sc_data_direction) { | ||
2224 | case DMA_NONE: | ||
2225 | *data_dir = FSF_DATADIR_CMND; | ||
2226 | break; | ||
2227 | case DMA_FROM_DEVICE: | ||
2228 | *data_dir = FSF_DATADIR_READ; | ||
2229 | break; | ||
2230 | case DMA_TO_DEVICE: | ||
2231 | *data_dir = FSF_DATADIR_WRITE; | ||
2232 | break; | ||
2233 | case DMA_BIDIRECTIONAL: | ||
2234 | return -EINVAL; | ||
2235 | } | ||
2236 | break; | ||
2237 | |||
2238 | case SCSI_PROT_READ_STRIP: | ||
2239 | *data_dir = FSF_DATADIR_DIF_READ_STRIP; | ||
2240 | break; | ||
2241 | case SCSI_PROT_WRITE_INSERT: | ||
2242 | *data_dir = FSF_DATADIR_DIF_WRITE_INSERT; | ||
2243 | break; | ||
2244 | case SCSI_PROT_READ_PASS: | ||
2245 | *data_dir = FSF_DATADIR_DIF_READ_CONVERT; | ||
2246 | break; | ||
2247 | case SCSI_PROT_WRITE_PASS: | ||
2248 | *data_dir = FSF_DATADIR_DIF_WRITE_CONVERT; | ||
2249 | break; | ||
2250 | default: | ||
2251 | return -EINVAL; | ||
2252 | } | ||
2253 | |||
2254 | return 0; | ||
2255 | } | ||
2256 | |||
2190 | /** | 2257 | /** |
2191 | * zfcp_fsf_send_fcp_command_task - initiate an FCP command (for a SCSI command) | 2258 | * zfcp_fsf_send_fcp_command_task - initiate an FCP command (for a SCSI command) |
2192 | * @unit: unit where command is sent to | 2259 | * @unit: unit where command is sent to |
@@ -2198,16 +2265,17 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit, | |||
2198 | struct zfcp_fsf_req *req; | 2265 | struct zfcp_fsf_req *req; |
2199 | struct fcp_cmnd *fcp_cmnd; | 2266 | struct fcp_cmnd *fcp_cmnd; |
2200 | unsigned int sbtype = SBAL_FLAGS0_TYPE_READ; | 2267 | unsigned int sbtype = SBAL_FLAGS0_TYPE_READ; |
2201 | int real_bytes, retval = -EIO; | 2268 | int real_bytes, retval = -EIO, dix_bytes = 0; |
2202 | struct zfcp_adapter *adapter = unit->port->adapter; | 2269 | struct zfcp_adapter *adapter = unit->port->adapter; |
2203 | struct zfcp_qdio *qdio = adapter->qdio; | 2270 | struct zfcp_qdio *qdio = adapter->qdio; |
2271 | struct fsf_qtcb_bottom_io *io; | ||
2204 | 2272 | ||
2205 | if (unlikely(!(atomic_read(&unit->status) & | 2273 | if (unlikely(!(atomic_read(&unit->status) & |
2206 | ZFCP_STATUS_COMMON_UNBLOCKED))) | 2274 | ZFCP_STATUS_COMMON_UNBLOCKED))) |
2207 | return -EBUSY; | 2275 | return -EBUSY; |
2208 | 2276 | ||
2209 | spin_lock(&qdio->req_q_lock); | 2277 | spin_lock(&qdio->req_q_lock); |
2210 | if (atomic_read(&qdio->req_q.count) <= 0) { | 2278 | if (atomic_read(&qdio->req_q_free) <= 0) { |
2211 | atomic_inc(&qdio->req_q_full); | 2279 | atomic_inc(&qdio->req_q_full); |
2212 | goto out; | 2280 | goto out; |
2213 | } | 2281 | } |
@@ -2223,56 +2291,45 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit, | |||
2223 | goto out; | 2291 | goto out; |
2224 | } | 2292 | } |
2225 | 2293 | ||
2294 | scsi_cmnd->host_scribble = (unsigned char *) req->req_id; | ||
2295 | |||
2296 | io = &req->qtcb->bottom.io; | ||
2226 | req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; | 2297 | req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; |
2227 | req->unit = unit; | 2298 | req->unit = unit; |
2228 | req->data = scsi_cmnd; | 2299 | req->data = scsi_cmnd; |
2229 | req->handler = zfcp_fsf_send_fcp_command_handler; | 2300 | req->handler = zfcp_fsf_send_fcp_command_handler; |
2230 | req->qtcb->header.lun_handle = unit->handle; | 2301 | req->qtcb->header.lun_handle = unit->handle; |
2231 | req->qtcb->header.port_handle = unit->port->handle; | 2302 | req->qtcb->header.port_handle = unit->port->handle; |
2232 | req->qtcb->bottom.io.service_class = FSF_CLASS_3; | 2303 | io->service_class = FSF_CLASS_3; |
2233 | req->qtcb->bottom.io.fcp_cmnd_length = FCP_CMND_LEN; | 2304 | io->fcp_cmnd_length = FCP_CMND_LEN; |
2234 | 2305 | ||
2235 | scsi_cmnd->host_scribble = (unsigned char *) req->req_id; | 2306 | if (scsi_get_prot_op(scsi_cmnd) != SCSI_PROT_NORMAL) { |
2236 | 2307 | io->data_block_length = scsi_cmnd->device->sector_size; | |
2237 | /* | 2308 | io->ref_tag_value = scsi_get_lba(scsi_cmnd) & 0xFFFFFFFF; |
2238 | * set depending on data direction: | ||
2239 | * data direction bits in SBALE (SB Type) | ||
2240 | * data direction bits in QTCB | ||
2241 | */ | ||
2242 | switch (scsi_cmnd->sc_data_direction) { | ||
2243 | case DMA_NONE: | ||
2244 | req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND; | ||
2245 | break; | ||
2246 | case DMA_FROM_DEVICE: | ||
2247 | req->qtcb->bottom.io.data_direction = FSF_DATADIR_READ; | ||
2248 | break; | ||
2249 | case DMA_TO_DEVICE: | ||
2250 | req->qtcb->bottom.io.data_direction = FSF_DATADIR_WRITE; | ||
2251 | break; | ||
2252 | case DMA_BIDIRECTIONAL: | ||
2253 | goto failed_scsi_cmnd; | ||
2254 | } | 2309 | } |
2255 | 2310 | ||
2311 | zfcp_fsf_set_data_dir(scsi_cmnd, &io->data_direction); | ||
2312 | |||
2256 | get_device(&unit->dev); | 2313 | get_device(&unit->dev); |
2257 | 2314 | ||
2258 | fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd; | 2315 | fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd; |
2259 | zfcp_fc_scsi_to_fcp(fcp_cmnd, scsi_cmnd); | 2316 | zfcp_fc_scsi_to_fcp(fcp_cmnd, scsi_cmnd); |
2260 | 2317 | ||
2318 | if (scsi_prot_sg_count(scsi_cmnd)) { | ||
2319 | zfcp_qdio_set_data_div(qdio, &req->qdio_req, | ||
2320 | scsi_prot_sg_count(scsi_cmnd)); | ||
2321 | dix_bytes = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, | ||
2322 | scsi_prot_sglist(scsi_cmnd)); | ||
2323 | io->prot_data_length = dix_bytes; | ||
2324 | } | ||
2325 | |||
2261 | real_bytes = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, | 2326 | real_bytes = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, |
2262 | scsi_sglist(scsi_cmnd), | 2327 | scsi_sglist(scsi_cmnd)); |
2263 | ZFCP_FSF_MAX_SBALS_PER_REQ); | 2328 | |
2264 | if (unlikely(real_bytes < 0)) { | 2329 | if (unlikely(real_bytes < 0) || unlikely(dix_bytes < 0)) |
2265 | if (req->qdio_req.sbal_number >= ZFCP_FSF_MAX_SBALS_PER_REQ) { | ||
2266 | dev_err(&adapter->ccw_device->dev, | ||
2267 | "Oversize data package, unit 0x%016Lx " | ||
2268 | "on port 0x%016Lx closed\n", | ||
2269 | (unsigned long long)unit->fcp_lun, | ||
2270 | (unsigned long long)unit->port->wwpn); | ||
2271 | zfcp_erp_unit_shutdown(unit, 0, "fssfct1", req); | ||
2272 | retval = -EINVAL; | ||
2273 | } | ||
2274 | goto failed_scsi_cmnd; | 2330 | goto failed_scsi_cmnd; |
2275 | } | 2331 | |
2332 | zfcp_qdio_set_sbale_last(adapter->qdio, &req->qdio_req); | ||
2276 | 2333 | ||
2277 | retval = zfcp_fsf_req_send(req); | 2334 | retval = zfcp_fsf_req_send(req); |
2278 | if (unlikely(retval)) | 2335 | if (unlikely(retval)) |
@@ -2391,13 +2448,13 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, | |||
2391 | bottom->operation_subtype = FSF_CFDC_OPERATION_SUBTYPE; | 2448 | bottom->operation_subtype = FSF_CFDC_OPERATION_SUBTYPE; |
2392 | bottom->option = fsf_cfdc->option; | 2449 | bottom->option = fsf_cfdc->option; |
2393 | 2450 | ||
2394 | bytes = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, | 2451 | bytes = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, fsf_cfdc->sg); |
2395 | fsf_cfdc->sg, | 2452 | |
2396 | ZFCP_FSF_MAX_SBALS_PER_REQ); | ||
2397 | if (bytes != ZFCP_CFDC_MAX_SIZE) { | 2453 | if (bytes != ZFCP_CFDC_MAX_SIZE) { |
2398 | zfcp_fsf_req_free(req); | 2454 | zfcp_fsf_req_free(req); |
2399 | goto out; | 2455 | goto out; |
2400 | } | 2456 | } |
2457 | zfcp_qdio_set_sbale_last(adapter->qdio, &req->qdio_req); | ||
2401 | 2458 | ||
2402 | zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); | 2459 | zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); |
2403 | retval = zfcp_fsf_req_send(req); | 2460 | retval = zfcp_fsf_req_send(req); |
@@ -2419,7 +2476,7 @@ out: | |||
2419 | void zfcp_fsf_reqid_check(struct zfcp_qdio *qdio, int sbal_idx) | 2476 | void zfcp_fsf_reqid_check(struct zfcp_qdio *qdio, int sbal_idx) |
2420 | { | 2477 | { |
2421 | struct zfcp_adapter *adapter = qdio->adapter; | 2478 | struct zfcp_adapter *adapter = qdio->adapter; |
2422 | struct qdio_buffer *sbal = qdio->resp_q.sbal[sbal_idx]; | 2479 | struct qdio_buffer *sbal = qdio->res_q[sbal_idx]; |
2423 | struct qdio_buffer_element *sbale; | 2480 | struct qdio_buffer_element *sbale; |
2424 | struct zfcp_fsf_req *fsf_req; | 2481 | struct zfcp_fsf_req *fsf_req; |
2425 | unsigned long req_id; | 2482 | unsigned long req_id; |
@@ -2431,17 +2488,17 @@ void zfcp_fsf_reqid_check(struct zfcp_qdio *qdio, int sbal_idx) | |||
2431 | req_id = (unsigned long) sbale->addr; | 2488 | req_id = (unsigned long) sbale->addr; |
2432 | fsf_req = zfcp_reqlist_find_rm(adapter->req_list, req_id); | 2489 | fsf_req = zfcp_reqlist_find_rm(adapter->req_list, req_id); |
2433 | 2490 | ||
2434 | if (!fsf_req) | 2491 | if (!fsf_req) { |
2435 | /* | 2492 | /* |
2436 | * Unknown request means that we have potentially memory | 2493 | * Unknown request means that we have potentially memory |
2437 | * corruption and must stop the machine immediately. | 2494 | * corruption and must stop the machine immediately. |
2438 | */ | 2495 | */ |
2496 | zfcp_qdio_siosl(adapter); | ||
2439 | panic("error: unknown req_id (%lx) on adapter %s.\n", | 2497 | panic("error: unknown req_id (%lx) on adapter %s.\n", |
2440 | req_id, dev_name(&adapter->ccw_device->dev)); | 2498 | req_id, dev_name(&adapter->ccw_device->dev)); |
2499 | } | ||
2441 | 2500 | ||
2442 | fsf_req->qdio_req.sbal_response = sbal_idx; | 2501 | fsf_req->qdio_req.sbal_response = sbal_idx; |
2443 | fsf_req->qdio_req.qdio_inb_usage = | ||
2444 | atomic_read(&qdio->resp_q.count); | ||
2445 | zfcp_fsf_req_complete(fsf_req); | 2502 | zfcp_fsf_req_complete(fsf_req); |
2446 | 2503 | ||
2447 | if (likely(sbale->flags & SBAL_FLAGS_LAST_ENTRY)) | 2504 | if (likely(sbale->flags & SBAL_FLAGS_LAST_ENTRY)) |