diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_fsf.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 367 |
1 files changed, 135 insertions, 232 deletions
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 4e41baa0c141..482dcd97aa5d 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -10,7 +10,9 @@ | |||
10 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | 10 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt |
11 | 11 | ||
12 | #include <linux/blktrace_api.h> | 12 | #include <linux/blktrace_api.h> |
13 | #include <scsi/fc/fc_els.h> | ||
13 | #include "zfcp_ext.h" | 14 | #include "zfcp_ext.h" |
15 | #include "zfcp_fc.h" | ||
14 | #include "zfcp_dbf.h" | 16 | #include "zfcp_dbf.h" |
15 | 17 | ||
16 | static void zfcp_fsf_request_timeout_handler(unsigned long data) | 18 | static void zfcp_fsf_request_timeout_handler(unsigned long data) |
@@ -122,36 +124,32 @@ void zfcp_fsf_req_free(struct zfcp_fsf_req *req) | |||
122 | 124 | ||
123 | static void zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *req) | 125 | static void zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *req) |
124 | { | 126 | { |
127 | unsigned long flags; | ||
125 | struct fsf_status_read_buffer *sr_buf = req->data; | 128 | struct fsf_status_read_buffer *sr_buf = req->data; |
126 | struct zfcp_adapter *adapter = req->adapter; | 129 | struct zfcp_adapter *adapter = req->adapter; |
127 | struct zfcp_port *port; | 130 | struct zfcp_port *port; |
128 | int d_id = sr_buf->d_id & ZFCP_DID_MASK; | 131 | int d_id = ntoh24(sr_buf->d_id); |
129 | unsigned long flags; | ||
130 | 132 | ||
131 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 133 | read_lock_irqsave(&adapter->port_list_lock, flags); |
132 | list_for_each_entry(port, &adapter->port_list_head, list) | 134 | list_for_each_entry(port, &adapter->port_list, list) |
133 | if (port->d_id == d_id) { | 135 | if (port->d_id == d_id) { |
134 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | ||
135 | zfcp_erp_port_reopen(port, 0, "fssrpc1", req); | 136 | zfcp_erp_port_reopen(port, 0, "fssrpc1", req); |
136 | return; | 137 | break; |
137 | } | 138 | } |
138 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | 139 | read_unlock_irqrestore(&adapter->port_list_lock, flags); |
139 | } | 140 | } |
140 | 141 | ||
141 | static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *req, char *id, | 142 | static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *req, char *id, |
142 | struct fsf_link_down_info *link_down) | 143 | struct fsf_link_down_info *link_down) |
143 | { | 144 | { |
144 | struct zfcp_adapter *adapter = req->adapter; | 145 | struct zfcp_adapter *adapter = req->adapter; |
145 | unsigned long flags; | ||
146 | 146 | ||
147 | if (atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED) | 147 | if (atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED) |
148 | return; | 148 | return; |
149 | 149 | ||
150 | atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status); | 150 | atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status); |
151 | 151 | ||
152 | read_lock_irqsave(&zfcp_data.config_lock, flags); | ||
153 | zfcp_scsi_schedule_rports_block(adapter); | 152 | zfcp_scsi_schedule_rports_block(adapter); |
154 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | ||
155 | 153 | ||
156 | if (!link_down) | 154 | if (!link_down) |
157 | goto out; | 155 | goto out; |
@@ -291,7 +289,7 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req) | |||
291 | zfcp_erp_adapter_access_changed(adapter, "fssrh_3", | 289 | zfcp_erp_adapter_access_changed(adapter, "fssrh_3", |
292 | req); | 290 | req); |
293 | if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_INCOMING_ELS) | 291 | if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_INCOMING_ELS) |
294 | schedule_work(&adapter->scan_work); | 292 | queue_work(adapter->work_queue, &adapter->scan_work); |
295 | break; | 293 | break; |
296 | case FSF_STATUS_READ_CFDC_UPDATED: | 294 | case FSF_STATUS_READ_CFDC_UPDATED: |
297 | zfcp_erp_adapter_access_changed(adapter, "fssrh_4", req); | 295 | zfcp_erp_adapter_access_changed(adapter, "fssrh_4", req); |
@@ -317,7 +315,6 @@ static void zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *req) | |||
317 | case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: | 315 | case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: |
318 | return; | 316 | return; |
319 | case FSF_SQ_COMMAND_ABORTED: | 317 | case FSF_SQ_COMMAND_ABORTED: |
320 | req->status |= ZFCP_STATUS_FSFREQ_ABORTED; | ||
321 | break; | 318 | break; |
322 | case FSF_SQ_NO_RECOM: | 319 | case FSF_SQ_NO_RECOM: |
323 | dev_err(&req->adapter->ccw_device->dev, | 320 | dev_err(&req->adapter->ccw_device->dev, |
@@ -358,8 +355,7 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req) | |||
358 | zfcp_dbf_hba_fsf_response(req); | 355 | zfcp_dbf_hba_fsf_response(req); |
359 | 356 | ||
360 | if (req->status & ZFCP_STATUS_FSFREQ_DISMISSED) { | 357 | if (req->status & ZFCP_STATUS_FSFREQ_DISMISSED) { |
361 | req->status |= ZFCP_STATUS_FSFREQ_ERROR | | 358 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
362 | ZFCP_STATUS_FSFREQ_RETRY; /* only for SCSI cmnds. */ | ||
363 | return; | 359 | return; |
364 | } | 360 | } |
365 | 361 | ||
@@ -377,7 +373,7 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req) | |||
377 | case FSF_PROT_ERROR_STATE: | 373 | case FSF_PROT_ERROR_STATE: |
378 | case FSF_PROT_SEQ_NUMB_ERROR: | 374 | case FSF_PROT_SEQ_NUMB_ERROR: |
379 | zfcp_erp_adapter_reopen(adapter, 0, "fspse_2", req); | 375 | zfcp_erp_adapter_reopen(adapter, 0, "fspse_2", req); |
380 | req->status |= ZFCP_STATUS_FSFREQ_RETRY; | 376 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
381 | break; | 377 | break; |
382 | case FSF_PROT_UNSUPP_QTCB_TYPE: | 378 | case FSF_PROT_UNSUPP_QTCB_TYPE: |
383 | dev_err(&adapter->ccw_device->dev, | 379 | dev_err(&adapter->ccw_device->dev, |
@@ -480,20 +476,27 @@ void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter) | |||
480 | 476 | ||
481 | static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req) | 477 | static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req) |
482 | { | 478 | { |
483 | struct fsf_qtcb_bottom_config *bottom; | 479 | struct fsf_qtcb_bottom_config *bottom = &req->qtcb->bottom.config; |
484 | struct zfcp_adapter *adapter = req->adapter; | 480 | struct zfcp_adapter *adapter = req->adapter; |
485 | struct Scsi_Host *shost = adapter->scsi_host; | 481 | struct Scsi_Host *shost = adapter->scsi_host; |
482 | struct fc_els_flogi *nsp, *plogi; | ||
486 | 483 | ||
487 | bottom = &req->qtcb->bottom.config; | 484 | /* adjust pointers for missing command code */ |
485 | nsp = (struct fc_els_flogi *) ((u8 *)&bottom->nport_serv_param | ||
486 | - sizeof(u32)); | ||
487 | plogi = (struct fc_els_flogi *) ((u8 *)&bottom->plogi_payload | ||
488 | - sizeof(u32)); | ||
488 | 489 | ||
489 | if (req->data) | 490 | if (req->data) |
490 | memcpy(req->data, bottom, sizeof(*bottom)); | 491 | memcpy(req->data, bottom, sizeof(*bottom)); |
491 | 492 | ||
492 | fc_host_node_name(shost) = bottom->nport_serv_param.wwnn; | 493 | fc_host_port_name(shost) = nsp->fl_wwpn; |
493 | fc_host_port_name(shost) = bottom->nport_serv_param.wwpn; | 494 | fc_host_node_name(shost) = nsp->fl_wwnn; |
494 | fc_host_port_id(shost) = bottom->s_id & ZFCP_DID_MASK; | 495 | fc_host_port_id(shost) = ntoh24(bottom->s_id); |
495 | fc_host_speed(shost) = bottom->fc_link_speed; | 496 | fc_host_speed(shost) = bottom->fc_link_speed; |
496 | fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3; | 497 | fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3; |
498 | fc_host_supported_fc4s(shost)[2] = 1; /* FCP */ | ||
499 | fc_host_active_fc4s(shost)[2] = 1; /* FCP */ | ||
497 | 500 | ||
498 | adapter->hydra_version = bottom->adapter_type; | 501 | adapter->hydra_version = bottom->adapter_type; |
499 | adapter->timer_ticks = bottom->timer_interval; | 502 | adapter->timer_ticks = bottom->timer_interval; |
@@ -503,9 +506,9 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req) | |||
503 | 506 | ||
504 | switch (bottom->fc_topology) { | 507 | switch (bottom->fc_topology) { |
505 | case FSF_TOPO_P2P: | 508 | case FSF_TOPO_P2P: |
506 | adapter->peer_d_id = bottom->peer_d_id & ZFCP_DID_MASK; | 509 | adapter->peer_d_id = ntoh24(bottom->peer_d_id); |
507 | adapter->peer_wwpn = bottom->plogi_payload.wwpn; | 510 | adapter->peer_wwpn = plogi->fl_wwpn; |
508 | adapter->peer_wwnn = bottom->plogi_payload.wwnn; | 511 | adapter->peer_wwnn = plogi->fl_wwnn; |
509 | fc_host_port_type(shost) = FC_PORTTYPE_PTP; | 512 | fc_host_port_type(shost) = FC_PORTTYPE_PTP; |
510 | break; | 513 | break; |
511 | case FSF_TOPO_FABRIC: | 514 | case FSF_TOPO_FABRIC: |
@@ -881,13 +884,11 @@ static void zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *req) | |||
881 | break; | 884 | break; |
882 | case FSF_PORT_BOXED: | 885 | case FSF_PORT_BOXED: |
883 | zfcp_erp_port_boxed(unit->port, "fsafch3", req); | 886 | zfcp_erp_port_boxed(unit->port, "fsafch3", req); |
884 | req->status |= ZFCP_STATUS_FSFREQ_ERROR | | 887 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
885 | ZFCP_STATUS_FSFREQ_RETRY; | ||
886 | break; | 888 | break; |
887 | case FSF_LUN_BOXED: | 889 | case FSF_LUN_BOXED: |
888 | zfcp_erp_unit_boxed(unit, "fsafch4", req); | 890 | zfcp_erp_unit_boxed(unit, "fsafch4", req); |
889 | req->status |= ZFCP_STATUS_FSFREQ_ERROR | | 891 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
890 | ZFCP_STATUS_FSFREQ_RETRY; | ||
891 | break; | 892 | break; |
892 | case FSF_ADAPTER_STATUS_AVAILABLE: | 893 | case FSF_ADAPTER_STATUS_AVAILABLE: |
893 | switch (fsq->word[0]) { | 894 | switch (fsq->word[0]) { |
@@ -958,10 +959,10 @@ out: | |||
958 | static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req) | 959 | static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req) |
959 | { | 960 | { |
960 | struct zfcp_adapter *adapter = req->adapter; | 961 | struct zfcp_adapter *adapter = req->adapter; |
961 | struct zfcp_send_ct *send_ct = req->data; | 962 | struct zfcp_fsf_ct_els *ct = req->data; |
962 | struct fsf_qtcb_header *header = &req->qtcb->header; | 963 | struct fsf_qtcb_header *header = &req->qtcb->header; |
963 | 964 | ||
964 | send_ct->status = -EINVAL; | 965 | ct->status = -EINVAL; |
965 | 966 | ||
966 | if (req->status & ZFCP_STATUS_FSFREQ_ERROR) | 967 | if (req->status & ZFCP_STATUS_FSFREQ_ERROR) |
967 | goto skip_fsfstatus; | 968 | goto skip_fsfstatus; |
@@ -969,7 +970,7 @@ static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req) | |||
969 | switch (header->fsf_status) { | 970 | switch (header->fsf_status) { |
970 | case FSF_GOOD: | 971 | case FSF_GOOD: |
971 | zfcp_dbf_san_ct_response(req); | 972 | zfcp_dbf_san_ct_response(req); |
972 | send_ct->status = 0; | 973 | ct->status = 0; |
973 | break; | 974 | break; |
974 | case FSF_SERVICE_CLASS_NOT_SUPPORTED: | 975 | case FSF_SERVICE_CLASS_NOT_SUPPORTED: |
975 | zfcp_fsf_class_not_supp(req); | 976 | zfcp_fsf_class_not_supp(req); |
@@ -985,8 +986,7 @@ static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req) | |||
985 | case FSF_ACCESS_DENIED: | 986 | case FSF_ACCESS_DENIED: |
986 | break; | 987 | break; |
987 | case FSF_PORT_BOXED: | 988 | case FSF_PORT_BOXED: |
988 | req->status |= ZFCP_STATUS_FSFREQ_ERROR | | 989 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
989 | ZFCP_STATUS_FSFREQ_RETRY; | ||
990 | break; | 990 | break; |
991 | case FSF_PORT_HANDLE_NOT_VALID: | 991 | case FSF_PORT_HANDLE_NOT_VALID: |
992 | zfcp_erp_adapter_reopen(adapter, 0, "fsscth1", req); | 992 | zfcp_erp_adapter_reopen(adapter, 0, "fsscth1", req); |
@@ -1001,8 +1001,8 @@ static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req) | |||
1001 | } | 1001 | } |
1002 | 1002 | ||
1003 | skip_fsfstatus: | 1003 | skip_fsfstatus: |
1004 | if (send_ct->handler) | 1004 | if (ct->handler) |
1005 | send_ct->handler(send_ct->handler_data); | 1005 | ct->handler(ct->handler_data); |
1006 | } | 1006 | } |
1007 | 1007 | ||
1008 | static void zfcp_fsf_setup_ct_els_unchained(struct qdio_buffer_element *sbale, | 1008 | static void zfcp_fsf_setup_ct_els_unchained(struct qdio_buffer_element *sbale, |
@@ -1071,15 +1071,17 @@ static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req, | |||
1071 | int max_sbals) | 1071 | int max_sbals) |
1072 | { | 1072 | { |
1073 | int ret; | 1073 | int ret; |
1074 | unsigned int fcp_chan_timeout; | ||
1074 | 1075 | ||
1075 | ret = zfcp_fsf_setup_ct_els_sbals(req, sg_req, sg_resp, max_sbals); | 1076 | ret = zfcp_fsf_setup_ct_els_sbals(req, sg_req, sg_resp, max_sbals); |
1076 | if (ret) | 1077 | if (ret) |
1077 | return ret; | 1078 | return ret; |
1078 | 1079 | ||
1079 | /* common settings for ct/gs and els requests */ | 1080 | /* common settings for ct/gs and els requests */ |
1081 | fcp_chan_timeout = 2 * FC_DEF_R_A_TOV / 1000; | ||
1080 | req->qtcb->bottom.support.service_class = FSF_CLASS_3; | 1082 | req->qtcb->bottom.support.service_class = FSF_CLASS_3; |
1081 | req->qtcb->bottom.support.timeout = 2 * R_A_TOV; | 1083 | req->qtcb->bottom.support.timeout = fcp_chan_timeout; |
1082 | zfcp_fsf_start_timer(req, (2 * R_A_TOV + 10) * HZ); | 1084 | zfcp_fsf_start_timer(req, (fcp_chan_timeout + 10) * HZ); |
1083 | 1085 | ||
1084 | return 0; | 1086 | return 0; |
1085 | } | 1087 | } |
@@ -1089,9 +1091,9 @@ static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req, | |||
1089 | * @ct: pointer to struct zfcp_send_ct with data for request | 1091 | * @ct: pointer to struct zfcp_send_ct with data for request |
1090 | * @pool: if non-null this mempool is used to allocate struct zfcp_fsf_req | 1092 | * @pool: if non-null this mempool is used to allocate struct zfcp_fsf_req |
1091 | */ | 1093 | */ |
1092 | int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool) | 1094 | int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port, |
1095 | struct zfcp_fsf_ct_els *ct, mempool_t *pool) | ||
1093 | { | 1096 | { |
1094 | struct zfcp_wka_port *wka_port = ct->wka_port; | ||
1095 | struct zfcp_qdio *qdio = wka_port->adapter->qdio; | 1097 | struct zfcp_qdio *qdio = wka_port->adapter->qdio; |
1096 | struct zfcp_fsf_req *req; | 1098 | struct zfcp_fsf_req *req; |
1097 | int ret = -EIO; | 1099 | int ret = -EIO; |
@@ -1117,7 +1119,7 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool) | |||
1117 | req->qtcb->header.port_handle = wka_port->handle; | 1119 | req->qtcb->header.port_handle = wka_port->handle; |
1118 | req->data = ct; | 1120 | req->data = ct; |
1119 | 1121 | ||
1120 | zfcp_dbf_san_ct_request(req); | 1122 | zfcp_dbf_san_ct_request(req, wka_port->d_id); |
1121 | 1123 | ||
1122 | ret = zfcp_fsf_req_send(req); | 1124 | ret = zfcp_fsf_req_send(req); |
1123 | if (ret) | 1125 | if (ret) |
@@ -1134,7 +1136,7 @@ out: | |||
1134 | 1136 | ||
1135 | static void zfcp_fsf_send_els_handler(struct zfcp_fsf_req *req) | 1137 | static void zfcp_fsf_send_els_handler(struct zfcp_fsf_req *req) |
1136 | { | 1138 | { |
1137 | struct zfcp_send_els *send_els = req->data; | 1139 | struct zfcp_fsf_ct_els *send_els = req->data; |
1138 | struct zfcp_port *port = send_els->port; | 1140 | struct zfcp_port *port = send_els->port; |
1139 | struct fsf_qtcb_header *header = &req->qtcb->header; | 1141 | struct fsf_qtcb_header *header = &req->qtcb->header; |
1140 | 1142 | ||
@@ -1154,9 +1156,6 @@ static void zfcp_fsf_send_els_handler(struct zfcp_fsf_req *req) | |||
1154 | case FSF_ADAPTER_STATUS_AVAILABLE: | 1156 | case FSF_ADAPTER_STATUS_AVAILABLE: |
1155 | switch (header->fsf_status_qual.word[0]){ | 1157 | switch (header->fsf_status_qual.word[0]){ |
1156 | case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: | 1158 | case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: |
1157 | if (port && (send_els->ls_code != ZFCP_LS_ADISC)) | ||
1158 | zfcp_fc_test_link(port); | ||
1159 | /*fall through */ | ||
1160 | case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: | 1159 | case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: |
1161 | case FSF_SQ_RETRY_IF_POSSIBLE: | 1160 | case FSF_SQ_RETRY_IF_POSSIBLE: |
1162 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 1161 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
@@ -1188,10 +1187,11 @@ skip_fsfstatus: | |||
1188 | * zfcp_fsf_send_els - initiate an ELS command (FC-FS) | 1187 | * zfcp_fsf_send_els - initiate an ELS command (FC-FS) |
1189 | * @els: pointer to struct zfcp_send_els with data for the command | 1188 | * @els: pointer to struct zfcp_send_els with data for the command |
1190 | */ | 1189 | */ |
1191 | int zfcp_fsf_send_els(struct zfcp_send_els *els) | 1190 | int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id, |
1191 | struct zfcp_fsf_ct_els *els) | ||
1192 | { | 1192 | { |
1193 | struct zfcp_fsf_req *req; | 1193 | struct zfcp_fsf_req *req; |
1194 | struct zfcp_qdio *qdio = els->adapter->qdio; | 1194 | struct zfcp_qdio *qdio = adapter->qdio; |
1195 | int ret = -EIO; | 1195 | int ret = -EIO; |
1196 | 1196 | ||
1197 | spin_lock_bh(&qdio->req_q_lock); | 1197 | spin_lock_bh(&qdio->req_q_lock); |
@@ -1211,7 +1211,7 @@ int zfcp_fsf_send_els(struct zfcp_send_els *els) | |||
1211 | if (ret) | 1211 | if (ret) |
1212 | goto failed_send; | 1212 | goto failed_send; |
1213 | 1213 | ||
1214 | req->qtcb->bottom.support.d_id = els->d_id; | 1214 | hton24(req->qtcb->bottom.support.d_id, d_id); |
1215 | req->handler = zfcp_fsf_send_els_handler; | 1215 | req->handler = zfcp_fsf_send_els_handler; |
1216 | req->data = els; | 1216 | req->data = els; |
1217 | 1217 | ||
@@ -1422,7 +1422,7 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req) | |||
1422 | { | 1422 | { |
1423 | struct zfcp_port *port = req->data; | 1423 | struct zfcp_port *port = req->data; |
1424 | struct fsf_qtcb_header *header = &req->qtcb->header; | 1424 | struct fsf_qtcb_header *header = &req->qtcb->header; |
1425 | struct fsf_plogi *plogi; | 1425 | struct fc_els_flogi *plogi; |
1426 | 1426 | ||
1427 | if (req->status & ZFCP_STATUS_FSFREQ_ERROR) | 1427 | if (req->status & ZFCP_STATUS_FSFREQ_ERROR) |
1428 | goto out; | 1428 | goto out; |
@@ -1472,23 +1472,10 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req) | |||
1472 | * another GID_PN straight after a port has been opened. | 1472 | * another GID_PN straight after a port has been opened. |
1473 | * Alternately, an ADISC/PDISC ELS should suffice, as well. | 1473 | * Alternately, an ADISC/PDISC ELS should suffice, as well. |
1474 | */ | 1474 | */ |
1475 | plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els; | 1475 | plogi = (struct fc_els_flogi *) req->qtcb->bottom.support.els; |
1476 | if (req->qtcb->bottom.support.els1_length >= | 1476 | if (req->qtcb->bottom.support.els1_length >= |
1477 | FSF_PLOGI_MIN_LEN) { | 1477 | FSF_PLOGI_MIN_LEN) |
1478 | if (plogi->serv_param.wwpn != port->wwpn) { | ||
1479 | port->d_id = 0; | ||
1480 | dev_warn(&port->adapter->ccw_device->dev, | ||
1481 | "A port opened with WWPN 0x%016Lx " | ||
1482 | "returned data that identifies it as " | ||
1483 | "WWPN 0x%016Lx\n", | ||
1484 | (unsigned long long) port->wwpn, | ||
1485 | (unsigned long long) | ||
1486 | plogi->serv_param.wwpn); | ||
1487 | } else { | ||
1488 | port->wwnn = plogi->serv_param.wwnn; | ||
1489 | zfcp_fc_plogi_evaluate(port, plogi); | 1478 | zfcp_fc_plogi_evaluate(port, plogi); |
1490 | } | ||
1491 | } | ||
1492 | break; | 1479 | break; |
1493 | case FSF_UNKNOWN_OP_SUBTYPE: | 1480 | case FSF_UNKNOWN_OP_SUBTYPE: |
1494 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 1481 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
@@ -1496,7 +1483,7 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req) | |||
1496 | } | 1483 | } |
1497 | 1484 | ||
1498 | out: | 1485 | out: |
1499 | zfcp_port_put(port); | 1486 | put_device(&port->sysfs_device); |
1500 | } | 1487 | } |
1501 | 1488 | ||
1502 | /** | 1489 | /** |
@@ -1530,18 +1517,18 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) | |||
1530 | sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; | 1517 | sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; |
1531 | 1518 | ||
1532 | req->handler = zfcp_fsf_open_port_handler; | 1519 | req->handler = zfcp_fsf_open_port_handler; |
1533 | req->qtcb->bottom.support.d_id = port->d_id; | 1520 | hton24(req->qtcb->bottom.support.d_id, port->d_id); |
1534 | req->data = port; | 1521 | req->data = port; |
1535 | req->erp_action = erp_action; | 1522 | req->erp_action = erp_action; |
1536 | erp_action->fsf_req = req; | 1523 | erp_action->fsf_req = req; |
1537 | zfcp_port_get(port); | 1524 | get_device(&port->sysfs_device); |
1538 | 1525 | ||
1539 | zfcp_fsf_start_erp_timer(req); | 1526 | zfcp_fsf_start_erp_timer(req); |
1540 | retval = zfcp_fsf_req_send(req); | 1527 | retval = zfcp_fsf_req_send(req); |
1541 | if (retval) { | 1528 | if (retval) { |
1542 | zfcp_fsf_req_free(req); | 1529 | zfcp_fsf_req_free(req); |
1543 | erp_action->fsf_req = NULL; | 1530 | erp_action->fsf_req = NULL; |
1544 | zfcp_port_put(port); | 1531 | put_device(&port->sysfs_device); |
1545 | } | 1532 | } |
1546 | out: | 1533 | out: |
1547 | spin_unlock_bh(&qdio->req_q_lock); | 1534 | spin_unlock_bh(&qdio->req_q_lock); |
@@ -1618,11 +1605,11 @@ out: | |||
1618 | 1605 | ||
1619 | static void zfcp_fsf_open_wka_port_handler(struct zfcp_fsf_req *req) | 1606 | static void zfcp_fsf_open_wka_port_handler(struct zfcp_fsf_req *req) |
1620 | { | 1607 | { |
1621 | struct zfcp_wka_port *wka_port = req->data; | 1608 | struct zfcp_fc_wka_port *wka_port = req->data; |
1622 | struct fsf_qtcb_header *header = &req->qtcb->header; | 1609 | struct fsf_qtcb_header *header = &req->qtcb->header; |
1623 | 1610 | ||
1624 | if (req->status & ZFCP_STATUS_FSFREQ_ERROR) { | 1611 | if (req->status & ZFCP_STATUS_FSFREQ_ERROR) { |
1625 | wka_port->status = ZFCP_WKA_PORT_OFFLINE; | 1612 | wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE; |
1626 | goto out; | 1613 | goto out; |
1627 | } | 1614 | } |
1628 | 1615 | ||
@@ -1635,13 +1622,13 @@ static void zfcp_fsf_open_wka_port_handler(struct zfcp_fsf_req *req) | |||
1635 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 1622 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
1636 | /* fall through */ | 1623 | /* fall through */ |
1637 | case FSF_ACCESS_DENIED: | 1624 | case FSF_ACCESS_DENIED: |
1638 | wka_port->status = ZFCP_WKA_PORT_OFFLINE; | 1625 | wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE; |
1639 | break; | 1626 | break; |
1640 | case FSF_GOOD: | 1627 | case FSF_GOOD: |
1641 | wka_port->handle = header->port_handle; | 1628 | wka_port->handle = header->port_handle; |
1642 | /* fall through */ | 1629 | /* fall through */ |
1643 | case FSF_PORT_ALREADY_OPEN: | 1630 | case FSF_PORT_ALREADY_OPEN: |
1644 | wka_port->status = ZFCP_WKA_PORT_ONLINE; | 1631 | wka_port->status = ZFCP_FC_WKA_PORT_ONLINE; |
1645 | } | 1632 | } |
1646 | out: | 1633 | out: |
1647 | wake_up(&wka_port->completion_wq); | 1634 | wake_up(&wka_port->completion_wq); |
@@ -1649,10 +1636,10 @@ out: | |||
1649 | 1636 | ||
1650 | /** | 1637 | /** |
1651 | * zfcp_fsf_open_wka_port - create and send open wka-port request | 1638 | * zfcp_fsf_open_wka_port - create and send open wka-port request |
1652 | * @wka_port: pointer to struct zfcp_wka_port | 1639 | * @wka_port: pointer to struct zfcp_fc_wka_port |
1653 | * Returns: 0 on success, error otherwise | 1640 | * Returns: 0 on success, error otherwise |
1654 | */ | 1641 | */ |
1655 | int zfcp_fsf_open_wka_port(struct zfcp_wka_port *wka_port) | 1642 | int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port) |
1656 | { | 1643 | { |
1657 | struct qdio_buffer_element *sbale; | 1644 | struct qdio_buffer_element *sbale; |
1658 | struct zfcp_qdio *qdio = wka_port->adapter->qdio; | 1645 | struct zfcp_qdio *qdio = wka_port->adapter->qdio; |
@@ -1677,7 +1664,7 @@ int zfcp_fsf_open_wka_port(struct zfcp_wka_port *wka_port) | |||
1677 | sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; | 1664 | sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; |
1678 | 1665 | ||
1679 | req->handler = zfcp_fsf_open_wka_port_handler; | 1666 | req->handler = zfcp_fsf_open_wka_port_handler; |
1680 | req->qtcb->bottom.support.d_id = wka_port->d_id; | 1667 | hton24(req->qtcb->bottom.support.d_id, wka_port->d_id); |
1681 | req->data = wka_port; | 1668 | req->data = wka_port; |
1682 | 1669 | ||
1683 | zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); | 1670 | zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); |
@@ -1691,23 +1678,23 @@ out: | |||
1691 | 1678 | ||
1692 | static void zfcp_fsf_close_wka_port_handler(struct zfcp_fsf_req *req) | 1679 | static void zfcp_fsf_close_wka_port_handler(struct zfcp_fsf_req *req) |
1693 | { | 1680 | { |
1694 | struct zfcp_wka_port *wka_port = req->data; | 1681 | struct zfcp_fc_wka_port *wka_port = req->data; |
1695 | 1682 | ||
1696 | if (req->qtcb->header.fsf_status == FSF_PORT_HANDLE_NOT_VALID) { | 1683 | if (req->qtcb->header.fsf_status == FSF_PORT_HANDLE_NOT_VALID) { |
1697 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 1684 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
1698 | zfcp_erp_adapter_reopen(wka_port->adapter, 0, "fscwph1", req); | 1685 | zfcp_erp_adapter_reopen(wka_port->adapter, 0, "fscwph1", req); |
1699 | } | 1686 | } |
1700 | 1687 | ||
1701 | wka_port->status = ZFCP_WKA_PORT_OFFLINE; | 1688 | wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE; |
1702 | wake_up(&wka_port->completion_wq); | 1689 | wake_up(&wka_port->completion_wq); |
1703 | } | 1690 | } |
1704 | 1691 | ||
1705 | /** | 1692 | /** |
1706 | * zfcp_fsf_close_wka_port - create and send close wka port request | 1693 | * zfcp_fsf_close_wka_port - create and send close wka port request |
1707 | * @erp_action: pointer to struct zfcp_erp_action | 1694 | * @wka_port: WKA port to open |
1708 | * Returns: 0 on success, error otherwise | 1695 | * Returns: 0 on success, error otherwise |
1709 | */ | 1696 | */ |
1710 | int zfcp_fsf_close_wka_port(struct zfcp_wka_port *wka_port) | 1697 | int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port) |
1711 | { | 1698 | { |
1712 | struct qdio_buffer_element *sbale; | 1699 | struct qdio_buffer_element *sbale; |
1713 | struct zfcp_qdio *qdio = wka_port->adapter->qdio; | 1700 | struct zfcp_qdio *qdio = wka_port->adapter->qdio; |
@@ -1765,13 +1752,13 @@ static void zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *req) | |||
1765 | /* can't use generic zfcp_erp_modify_port_status because | 1752 | /* can't use generic zfcp_erp_modify_port_status because |
1766 | * ZFCP_STATUS_COMMON_OPEN must not be reset for the port */ | 1753 | * ZFCP_STATUS_COMMON_OPEN must not be reset for the port */ |
1767 | atomic_clear_mask(ZFCP_STATUS_PORT_PHYS_OPEN, &port->status); | 1754 | atomic_clear_mask(ZFCP_STATUS_PORT_PHYS_OPEN, &port->status); |
1768 | list_for_each_entry(unit, &port->unit_list_head, list) | 1755 | read_lock(&port->unit_list_lock); |
1756 | list_for_each_entry(unit, &port->unit_list, list) | ||
1769 | atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN, | 1757 | atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN, |
1770 | &unit->status); | 1758 | &unit->status); |
1759 | read_unlock(&port->unit_list_lock); | ||
1771 | zfcp_erp_port_boxed(port, "fscpph2", req); | 1760 | zfcp_erp_port_boxed(port, "fscpph2", req); |
1772 | req->status |= ZFCP_STATUS_FSFREQ_ERROR | | 1761 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
1773 | ZFCP_STATUS_FSFREQ_RETRY; | ||
1774 | |||
1775 | break; | 1762 | break; |
1776 | case FSF_ADAPTER_STATUS_AVAILABLE: | 1763 | case FSF_ADAPTER_STATUS_AVAILABLE: |
1777 | switch (header->fsf_status_qual.word[0]) { | 1764 | switch (header->fsf_status_qual.word[0]) { |
@@ -1787,9 +1774,11 @@ static void zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *req) | |||
1787 | * ZFCP_STATUS_COMMON_OPEN must not be reset for the port | 1774 | * ZFCP_STATUS_COMMON_OPEN must not be reset for the port |
1788 | */ | 1775 | */ |
1789 | atomic_clear_mask(ZFCP_STATUS_PORT_PHYS_OPEN, &port->status); | 1776 | atomic_clear_mask(ZFCP_STATUS_PORT_PHYS_OPEN, &port->status); |
1790 | list_for_each_entry(unit, &port->unit_list_head, list) | 1777 | read_lock(&port->unit_list_lock); |
1778 | list_for_each_entry(unit, &port->unit_list, list) | ||
1791 | atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN, | 1779 | atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN, |
1792 | &unit->status); | 1780 | &unit->status); |
1781 | read_unlock(&port->unit_list_lock); | ||
1793 | break; | 1782 | break; |
1794 | } | 1783 | } |
1795 | } | 1784 | } |
@@ -1873,8 +1862,7 @@ static void zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *req) | |||
1873 | break; | 1862 | break; |
1874 | case FSF_PORT_BOXED: | 1863 | case FSF_PORT_BOXED: |
1875 | zfcp_erp_port_boxed(unit->port, "fsouh_2", req); | 1864 | zfcp_erp_port_boxed(unit->port, "fsouh_2", req); |
1876 | req->status |= ZFCP_STATUS_FSFREQ_ERROR | | 1865 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
1877 | ZFCP_STATUS_FSFREQ_RETRY; | ||
1878 | break; | 1866 | break; |
1879 | case FSF_LUN_SHARING_VIOLATION: | 1867 | case FSF_LUN_SHARING_VIOLATION: |
1880 | if (header->fsf_status_qual.word[0]) | 1868 | if (header->fsf_status_qual.word[0]) |
@@ -2036,8 +2024,7 @@ static void zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *req) | |||
2036 | break; | 2024 | break; |
2037 | case FSF_PORT_BOXED: | 2025 | case FSF_PORT_BOXED: |
2038 | zfcp_erp_port_boxed(unit->port, "fscuh_3", req); | 2026 | zfcp_erp_port_boxed(unit->port, "fscuh_3", req); |
2039 | req->status |= ZFCP_STATUS_FSFREQ_ERROR | | 2027 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
2040 | ZFCP_STATUS_FSFREQ_RETRY; | ||
2041 | break; | 2028 | break; |
2042 | case FSF_ADAPTER_STATUS_AVAILABLE: | 2029 | case FSF_ADAPTER_STATUS_AVAILABLE: |
2043 | switch (req->qtcb->header.fsf_status_qual.word[0]) { | 2030 | switch (req->qtcb->header.fsf_status_qual.word[0]) { |
@@ -2109,72 +2096,57 @@ static void zfcp_fsf_update_lat(struct fsf_latency_record *lat_rec, u32 lat) | |||
2109 | lat_rec->max = max(lat_rec->max, lat); | 2096 | lat_rec->max = max(lat_rec->max, lat); |
2110 | } | 2097 | } |
2111 | 2098 | ||
2112 | static void zfcp_fsf_req_latency(struct zfcp_fsf_req *req) | 2099 | static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi) |
2113 | { | 2100 | { |
2114 | struct fsf_qual_latency_info *lat_inf; | 2101 | struct fsf_qual_latency_info *lat_in; |
2115 | struct latency_cont *lat; | 2102 | struct latency_cont *lat = NULL; |
2116 | struct zfcp_unit *unit = req->unit; | 2103 | struct zfcp_unit *unit = req->unit; |
2104 | struct zfcp_blk_drv_data blktrc; | ||
2105 | int ticks = req->adapter->timer_ticks; | ||
2117 | 2106 | ||
2118 | lat_inf = &req->qtcb->prefix.prot_status_qual.latency_info; | 2107 | lat_in = &req->qtcb->prefix.prot_status_qual.latency_info; |
2119 | |||
2120 | switch (req->qtcb->bottom.io.data_direction) { | ||
2121 | case FSF_DATADIR_READ: | ||
2122 | lat = &unit->latencies.read; | ||
2123 | break; | ||
2124 | case FSF_DATADIR_WRITE: | ||
2125 | lat = &unit->latencies.write; | ||
2126 | break; | ||
2127 | case FSF_DATADIR_CMND: | ||
2128 | lat = &unit->latencies.cmd; | ||
2129 | break; | ||
2130 | default: | ||
2131 | return; | ||
2132 | } | ||
2133 | 2108 | ||
2134 | spin_lock(&unit->latencies.lock); | 2109 | blktrc.flags = 0; |
2135 | zfcp_fsf_update_lat(&lat->channel, lat_inf->channel_lat); | 2110 | blktrc.magic = ZFCP_BLK_DRV_DATA_MAGIC; |
2136 | zfcp_fsf_update_lat(&lat->fabric, lat_inf->fabric_lat); | 2111 | if (req->status & ZFCP_STATUS_FSFREQ_ERROR) |
2137 | lat->counter++; | 2112 | blktrc.flags |= ZFCP_BLK_REQ_ERROR; |
2138 | spin_unlock(&unit->latencies.lock); | 2113 | blktrc.inb_usage = req->queue_req.qdio_inb_usage; |
2139 | } | 2114 | blktrc.outb_usage = req->queue_req.qdio_outb_usage; |
2140 | 2115 | ||
2141 | #ifdef CONFIG_BLK_DEV_IO_TRACE | 2116 | if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA) { |
2142 | static void zfcp_fsf_trace_latency(struct zfcp_fsf_req *fsf_req) | 2117 | blktrc.flags |= ZFCP_BLK_LAT_VALID; |
2143 | { | 2118 | blktrc.channel_lat = lat_in->channel_lat * ticks; |
2144 | struct fsf_qual_latency_info *lat_inf; | 2119 | blktrc.fabric_lat = lat_in->fabric_lat * ticks; |
2145 | struct scsi_cmnd *scsi_cmnd = (struct scsi_cmnd *)fsf_req->data; | 2120 | |
2146 | struct request *req = scsi_cmnd->request; | 2121 | switch (req->qtcb->bottom.io.data_direction) { |
2147 | struct zfcp_blk_drv_data trace; | 2122 | case FSF_DATADIR_READ: |
2148 | int ticks = fsf_req->adapter->timer_ticks; | 2123 | lat = &unit->latencies.read; |
2124 | break; | ||
2125 | case FSF_DATADIR_WRITE: | ||
2126 | lat = &unit->latencies.write; | ||
2127 | break; | ||
2128 | case FSF_DATADIR_CMND: | ||
2129 | lat = &unit->latencies.cmd; | ||
2130 | break; | ||
2131 | } | ||
2149 | 2132 | ||
2150 | trace.flags = 0; | 2133 | if (lat) { |
2151 | trace.magic = ZFCP_BLK_DRV_DATA_MAGIC; | 2134 | spin_lock(&unit->latencies.lock); |
2152 | if (fsf_req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA) { | 2135 | zfcp_fsf_update_lat(&lat->channel, lat_in->channel_lat); |
2153 | trace.flags |= ZFCP_BLK_LAT_VALID; | 2136 | zfcp_fsf_update_lat(&lat->fabric, lat_in->fabric_lat); |
2154 | lat_inf = &fsf_req->qtcb->prefix.prot_status_qual.latency_info; | 2137 | lat->counter++; |
2155 | trace.channel_lat = lat_inf->channel_lat * ticks; | 2138 | spin_unlock(&unit->latencies.lock); |
2156 | trace.fabric_lat = lat_inf->fabric_lat * ticks; | 2139 | } |
2157 | } | 2140 | } |
2158 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) | ||
2159 | trace.flags |= ZFCP_BLK_REQ_ERROR; | ||
2160 | trace.inb_usage = fsf_req->queue_req.qdio_inb_usage; | ||
2161 | trace.outb_usage = fsf_req->queue_req.qdio_outb_usage; | ||
2162 | 2141 | ||
2163 | blk_add_driver_data(req->q, req, &trace, sizeof(trace)); | 2142 | blk_add_driver_data(scsi->request->q, scsi->request, &blktrc, |
2164 | } | 2143 | sizeof(blktrc)); |
2165 | #else | ||
2166 | static inline void zfcp_fsf_trace_latency(struct zfcp_fsf_req *fsf_req) | ||
2167 | { | ||
2168 | } | 2144 | } |
2169 | #endif | ||
2170 | 2145 | ||
2171 | static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req) | 2146 | static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req) |
2172 | { | 2147 | { |
2173 | struct scsi_cmnd *scpnt; | 2148 | struct scsi_cmnd *scpnt; |
2174 | struct fcp_rsp_iu *fcp_rsp_iu = (struct fcp_rsp_iu *) | 2149 | struct fcp_resp_with_ext *fcp_rsp; |
2175 | &(req->qtcb->bottom.io.fcp_rsp); | ||
2176 | u32 sns_len; | ||
2177 | char *fcp_rsp_info = (unsigned char *) &fcp_rsp_iu[1]; | ||
2178 | unsigned long flags; | 2150 | unsigned long flags; |
2179 | 2151 | ||
2180 | read_lock_irqsave(&req->adapter->abort_lock, flags); | 2152 | read_lock_irqsave(&req->adapter->abort_lock, flags); |
@@ -2185,50 +2157,16 @@ static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req) | |||
2185 | return; | 2157 | return; |
2186 | } | 2158 | } |
2187 | 2159 | ||
2188 | if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ABORTED)) { | ||
2189 | set_host_byte(scpnt, DID_SOFT_ERROR); | ||
2190 | goto skip_fsfstatus; | ||
2191 | } | ||
2192 | |||
2193 | if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) { | 2160 | if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) { |
2194 | set_host_byte(scpnt, DID_ERROR); | 2161 | set_host_byte(scpnt, DID_TRANSPORT_DISRUPTED); |
2195 | goto skip_fsfstatus; | 2162 | goto skip_fsfstatus; |
2196 | } | 2163 | } |
2197 | 2164 | ||
2198 | set_msg_byte(scpnt, COMMAND_COMPLETE); | 2165 | fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp; |
2199 | 2166 | zfcp_fc_eval_fcp_rsp(fcp_rsp, scpnt); | |
2200 | scpnt->result |= fcp_rsp_iu->scsi_status; | ||
2201 | 2167 | ||
2202 | if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA) | 2168 | zfcp_fsf_req_trace(req, scpnt); |
2203 | zfcp_fsf_req_latency(req); | ||
2204 | |||
2205 | zfcp_fsf_trace_latency(req); | ||
2206 | |||
2207 | if (unlikely(fcp_rsp_iu->validity.bits.fcp_rsp_len_valid)) { | ||
2208 | if (fcp_rsp_info[3] == RSP_CODE_GOOD) | ||
2209 | set_host_byte(scpnt, DID_OK); | ||
2210 | else { | ||
2211 | set_host_byte(scpnt, DID_ERROR); | ||
2212 | goto skip_fsfstatus; | ||
2213 | } | ||
2214 | } | ||
2215 | |||
2216 | if (unlikely(fcp_rsp_iu->validity.bits.fcp_sns_len_valid)) { | ||
2217 | sns_len = FSF_FCP_RSP_SIZE - sizeof(struct fcp_rsp_iu) + | ||
2218 | fcp_rsp_iu->fcp_rsp_len; | ||
2219 | sns_len = min(sns_len, (u32) SCSI_SENSE_BUFFERSIZE); | ||
2220 | sns_len = min(sns_len, fcp_rsp_iu->fcp_sns_len); | ||
2221 | |||
2222 | memcpy(scpnt->sense_buffer, | ||
2223 | zfcp_get_fcp_sns_info_ptr(fcp_rsp_iu), sns_len); | ||
2224 | } | ||
2225 | 2169 | ||
2226 | if (unlikely(fcp_rsp_iu->validity.bits.fcp_resid_under)) { | ||
2227 | scsi_set_resid(scpnt, fcp_rsp_iu->fcp_resid); | ||
2228 | if (scsi_bufflen(scpnt) - scsi_get_resid(scpnt) < | ||
2229 | scpnt->underflow) | ||
2230 | set_host_byte(scpnt, DID_ERROR); | ||
2231 | } | ||
2232 | skip_fsfstatus: | 2170 | skip_fsfstatus: |
2233 | if (scpnt->result != 0) | 2171 | if (scpnt->result != 0) |
2234 | zfcp_dbf_scsi_result("erro", 3, req->adapter->dbf, scpnt, req); | 2172 | zfcp_dbf_scsi_result("erro", 3, req->adapter->dbf, scpnt, req); |
@@ -2250,11 +2188,13 @@ skip_fsfstatus: | |||
2250 | 2188 | ||
2251 | static void zfcp_fsf_send_fcp_ctm_handler(struct zfcp_fsf_req *req) | 2189 | static void zfcp_fsf_send_fcp_ctm_handler(struct zfcp_fsf_req *req) |
2252 | { | 2190 | { |
2253 | struct fcp_rsp_iu *fcp_rsp_iu = (struct fcp_rsp_iu *) | 2191 | struct fcp_resp_with_ext *fcp_rsp; |
2254 | &(req->qtcb->bottom.io.fcp_rsp); | 2192 | struct fcp_resp_rsp_info *rsp_info; |
2255 | char *fcp_rsp_info = (unsigned char *) &fcp_rsp_iu[1]; | 2193 | |
2194 | fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp; | ||
2195 | rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1]; | ||
2256 | 2196 | ||
2257 | if ((fcp_rsp_info[3] != RSP_CODE_GOOD) || | 2197 | if ((rsp_info->rsp_code != FCP_TMF_CMPL) || |
2258 | (req->status & ZFCP_STATUS_FSFREQ_ERROR)) | 2198 | (req->status & ZFCP_STATUS_FSFREQ_ERROR)) |
2259 | req->status |= ZFCP_STATUS_FSFREQ_TMFUNCFAILED; | 2199 | req->status |= ZFCP_STATUS_FSFREQ_TMFUNCFAILED; |
2260 | } | 2200 | } |
@@ -2314,13 +2254,11 @@ static void zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *req) | |||
2314 | break; | 2254 | break; |
2315 | case FSF_PORT_BOXED: | 2255 | case FSF_PORT_BOXED: |
2316 | zfcp_erp_port_boxed(unit->port, "fssfch5", req); | 2256 | zfcp_erp_port_boxed(unit->port, "fssfch5", req); |
2317 | req->status |= ZFCP_STATUS_FSFREQ_ERROR | | 2257 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
2318 | ZFCP_STATUS_FSFREQ_RETRY; | ||
2319 | break; | 2258 | break; |
2320 | case FSF_LUN_BOXED: | 2259 | case FSF_LUN_BOXED: |
2321 | zfcp_erp_unit_boxed(unit, "fssfch6", req); | 2260 | zfcp_erp_unit_boxed(unit, "fssfch6", req); |
2322 | req->status |= ZFCP_STATUS_FSFREQ_ERROR | | 2261 | req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
2323 | ZFCP_STATUS_FSFREQ_RETRY; | ||
2324 | break; | 2262 | break; |
2325 | case FSF_ADAPTER_STATUS_AVAILABLE: | 2263 | case FSF_ADAPTER_STATUS_AVAILABLE: |
2326 | if (header->fsf_status_qual.word[0] == | 2264 | if (header->fsf_status_qual.word[0] == |
@@ -2335,24 +2273,10 @@ skip_fsfstatus: | |||
2335 | else { | 2273 | else { |
2336 | zfcp_fsf_send_fcp_command_task_handler(req); | 2274 | zfcp_fsf_send_fcp_command_task_handler(req); |
2337 | req->unit = NULL; | 2275 | req->unit = NULL; |
2338 | zfcp_unit_put(unit); | 2276 | put_device(&unit->sysfs_device); |
2339 | } | 2277 | } |
2340 | } | 2278 | } |
2341 | 2279 | ||
2342 | static void zfcp_set_fcp_dl(struct fcp_cmnd_iu *fcp_cmd, u32 fcp_dl) | ||
2343 | { | ||
2344 | u32 *fcp_dl_ptr; | ||
2345 | |||
2346 | /* | ||
2347 | * fcp_dl_addr = start address of fcp_cmnd structure + | ||
2348 | * size of fixed part + size of dynamically sized add_dcp_cdb field | ||
2349 | * SEE FCP-2 documentation | ||
2350 | */ | ||
2351 | fcp_dl_ptr = (u32 *) ((unsigned char *) &fcp_cmd[1] + | ||
2352 | (fcp_cmd->add_fcp_cdb_length << 2)); | ||
2353 | *fcp_dl_ptr = fcp_dl; | ||
2354 | } | ||
2355 | |||
2356 | /** | 2280 | /** |
2357 | * zfcp_fsf_send_fcp_command_task - initiate an FCP command (for a SCSI command) | 2281 | * zfcp_fsf_send_fcp_command_task - initiate an FCP command (for a SCSI command) |
2358 | * @unit: unit where command is sent to | 2282 | * @unit: unit where command is sent to |
@@ -2362,7 +2286,7 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit, | |||
2362 | struct scsi_cmnd *scsi_cmnd) | 2286 | struct scsi_cmnd *scsi_cmnd) |
2363 | { | 2287 | { |
2364 | struct zfcp_fsf_req *req; | 2288 | struct zfcp_fsf_req *req; |
2365 | struct fcp_cmnd_iu *fcp_cmnd_iu; | 2289 | struct fcp_cmnd *fcp_cmnd; |
2366 | unsigned int sbtype = SBAL_FLAGS0_TYPE_READ; | 2290 | unsigned int sbtype = SBAL_FLAGS0_TYPE_READ; |
2367 | int real_bytes, retval = -EIO; | 2291 | int real_bytes, retval = -EIO; |
2368 | struct zfcp_adapter *adapter = unit->port->adapter; | 2292 | struct zfcp_adapter *adapter = unit->port->adapter; |
@@ -2387,23 +2311,21 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit, | |||
2387 | } | 2311 | } |
2388 | 2312 | ||
2389 | req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; | 2313 | req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; |
2390 | zfcp_unit_get(unit); | 2314 | get_device(&unit->sysfs_device); |
2391 | req->unit = unit; | 2315 | req->unit = unit; |
2392 | req->data = scsi_cmnd; | 2316 | req->data = scsi_cmnd; |
2393 | req->handler = zfcp_fsf_send_fcp_command_handler; | 2317 | req->handler = zfcp_fsf_send_fcp_command_handler; |
2394 | req->qtcb->header.lun_handle = unit->handle; | 2318 | req->qtcb->header.lun_handle = unit->handle; |
2395 | req->qtcb->header.port_handle = unit->port->handle; | 2319 | req->qtcb->header.port_handle = unit->port->handle; |
2396 | req->qtcb->bottom.io.service_class = FSF_CLASS_3; | 2320 | req->qtcb->bottom.io.service_class = FSF_CLASS_3; |
2321 | req->qtcb->bottom.io.fcp_cmnd_length = FCP_CMND_LEN; | ||
2397 | 2322 | ||
2398 | scsi_cmnd->host_scribble = (unsigned char *) req->req_id; | 2323 | scsi_cmnd->host_scribble = (unsigned char *) req->req_id; |
2399 | 2324 | ||
2400 | fcp_cmnd_iu = (struct fcp_cmnd_iu *) &(req->qtcb->bottom.io.fcp_cmnd); | ||
2401 | fcp_cmnd_iu->fcp_lun = unit->fcp_lun; | ||
2402 | /* | 2325 | /* |
2403 | * set depending on data direction: | 2326 | * set depending on data direction: |
2404 | * data direction bits in SBALE (SB Type) | 2327 | * data direction bits in SBALE (SB Type) |
2405 | * data direction bits in QTCB | 2328 | * data direction bits in QTCB |
2406 | * data direction bits in FCP_CMND IU | ||
2407 | */ | 2329 | */ |
2408 | switch (scsi_cmnd->sc_data_direction) { | 2330 | switch (scsi_cmnd->sc_data_direction) { |
2409 | case DMA_NONE: | 2331 | case DMA_NONE: |
@@ -2411,32 +2333,17 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit, | |||
2411 | break; | 2333 | break; |
2412 | case DMA_FROM_DEVICE: | 2334 | case DMA_FROM_DEVICE: |
2413 | req->qtcb->bottom.io.data_direction = FSF_DATADIR_READ; | 2335 | req->qtcb->bottom.io.data_direction = FSF_DATADIR_READ; |
2414 | fcp_cmnd_iu->rddata = 1; | ||
2415 | break; | 2336 | break; |
2416 | case DMA_TO_DEVICE: | 2337 | case DMA_TO_DEVICE: |
2417 | req->qtcb->bottom.io.data_direction = FSF_DATADIR_WRITE; | 2338 | req->qtcb->bottom.io.data_direction = FSF_DATADIR_WRITE; |
2418 | sbtype = SBAL_FLAGS0_TYPE_WRITE; | 2339 | sbtype = SBAL_FLAGS0_TYPE_WRITE; |
2419 | fcp_cmnd_iu->wddata = 1; | ||
2420 | break; | 2340 | break; |
2421 | case DMA_BIDIRECTIONAL: | 2341 | case DMA_BIDIRECTIONAL: |
2422 | goto failed_scsi_cmnd; | 2342 | goto failed_scsi_cmnd; |
2423 | } | 2343 | } |
2424 | 2344 | ||
2425 | if (likely((scsi_cmnd->device->simple_tags) || | 2345 | fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd; |
2426 | ((atomic_read(&unit->status) & ZFCP_STATUS_UNIT_READONLY) && | 2346 | zfcp_fc_scsi_to_fcp(fcp_cmnd, scsi_cmnd); |
2427 | (atomic_read(&unit->status) & ZFCP_STATUS_UNIT_SHARED)))) | ||
2428 | fcp_cmnd_iu->task_attribute = SIMPLE_Q; | ||
2429 | else | ||
2430 | fcp_cmnd_iu->task_attribute = UNTAGGED; | ||
2431 | |||
2432 | if (unlikely(scsi_cmnd->cmd_len > FCP_CDB_LENGTH)) | ||
2433 | fcp_cmnd_iu->add_fcp_cdb_length = | ||
2434 | (scsi_cmnd->cmd_len - FCP_CDB_LENGTH) >> 2; | ||
2435 | |||
2436 | memcpy(fcp_cmnd_iu->fcp_cdb, scsi_cmnd->cmnd, scsi_cmnd->cmd_len); | ||
2437 | |||
2438 | req->qtcb->bottom.io.fcp_cmnd_length = sizeof(struct fcp_cmnd_iu) + | ||
2439 | fcp_cmnd_iu->add_fcp_cdb_length + sizeof(u32); | ||
2440 | 2347 | ||
2441 | real_bytes = zfcp_qdio_sbals_from_sg(qdio, &req->queue_req, sbtype, | 2348 | real_bytes = zfcp_qdio_sbals_from_sg(qdio, &req->queue_req, sbtype, |
2442 | scsi_sglist(scsi_cmnd), | 2349 | scsi_sglist(scsi_cmnd), |
@@ -2454,8 +2361,6 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit, | |||
2454 | goto failed_scsi_cmnd; | 2361 | goto failed_scsi_cmnd; |
2455 | } | 2362 | } |
2456 | 2363 | ||
2457 | zfcp_set_fcp_dl(fcp_cmnd_iu, real_bytes); | ||
2458 | |||
2459 | retval = zfcp_fsf_req_send(req); | 2364 | retval = zfcp_fsf_req_send(req); |
2460 | if (unlikely(retval)) | 2365 | if (unlikely(retval)) |
2461 | goto failed_scsi_cmnd; | 2366 | goto failed_scsi_cmnd; |
@@ -2463,7 +2368,7 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit, | |||
2463 | goto out; | 2368 | goto out; |
2464 | 2369 | ||
2465 | failed_scsi_cmnd: | 2370 | failed_scsi_cmnd: |
2466 | zfcp_unit_put(unit); | 2371 | put_device(&unit->sysfs_device); |
2467 | zfcp_fsf_req_free(req); | 2372 | zfcp_fsf_req_free(req); |
2468 | scsi_cmnd->host_scribble = NULL; | 2373 | scsi_cmnd->host_scribble = NULL; |
2469 | out: | 2374 | out: |
@@ -2481,7 +2386,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *unit, u8 tm_flags) | |||
2481 | { | 2386 | { |
2482 | struct qdio_buffer_element *sbale; | 2387 | struct qdio_buffer_element *sbale; |
2483 | struct zfcp_fsf_req *req = NULL; | 2388 | struct zfcp_fsf_req *req = NULL; |
2484 | struct fcp_cmnd_iu *fcp_cmnd_iu; | 2389 | struct fcp_cmnd *fcp_cmnd; |
2485 | struct zfcp_qdio *qdio = unit->port->adapter->qdio; | 2390 | struct zfcp_qdio *qdio = unit->port->adapter->qdio; |
2486 | 2391 | ||
2487 | if (unlikely(!(atomic_read(&unit->status) & | 2392 | if (unlikely(!(atomic_read(&unit->status) & |
@@ -2507,16 +2412,14 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *unit, u8 tm_flags) | |||
2507 | req->qtcb->header.port_handle = unit->port->handle; | 2412 | req->qtcb->header.port_handle = unit->port->handle; |
2508 | req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND; | 2413 | req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND; |
2509 | req->qtcb->bottom.io.service_class = FSF_CLASS_3; | 2414 | req->qtcb->bottom.io.service_class = FSF_CLASS_3; |
2510 | req->qtcb->bottom.io.fcp_cmnd_length = sizeof(struct fcp_cmnd_iu) + | 2415 | req->qtcb->bottom.io.fcp_cmnd_length = FCP_CMND_LEN; |
2511 | sizeof(u32); | ||
2512 | 2416 | ||
2513 | sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req); | 2417 | sbale = zfcp_qdio_sbale_req(qdio, &req->queue_req); |
2514 | sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE; | 2418 | sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE; |
2515 | sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; | 2419 | sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; |
2516 | 2420 | ||
2517 | fcp_cmnd_iu = (struct fcp_cmnd_iu *) &req->qtcb->bottom.io.fcp_cmnd; | 2421 | fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd; |
2518 | fcp_cmnd_iu->fcp_lun = unit->fcp_lun; | 2422 | zfcp_fc_fcp_tm(fcp_cmnd, unit->device, tm_flags); |
2519 | fcp_cmnd_iu->task_management_flags = tm_flags; | ||
2520 | 2423 | ||
2521 | zfcp_fsf_start_timer(req, ZFCP_SCSI_ER_TIMEOUT); | 2424 | zfcp_fsf_start_timer(req, ZFCP_SCSI_ER_TIMEOUT); |
2522 | if (!zfcp_fsf_req_send(req)) | 2425 | if (!zfcp_fsf_req_send(req)) |