diff options
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/scsi/zfcp_aux.c | 90 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_def.h | 41 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_erp.c | 89 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_ext.h | 4 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 50 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_qdio.c | 49 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_scsi.c | 9 |
7 files changed, 174 insertions, 158 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 1f9554e08013..324899c96efe 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c | |||
@@ -118,97 +118,32 @@ _zfcp_hex_dump(char *addr, int count) | |||
118 | 118 | ||
119 | #define ZFCP_LOG_AREA ZFCP_LOG_AREA_FSF | 119 | #define ZFCP_LOG_AREA ZFCP_LOG_AREA_FSF |
120 | 120 | ||
121 | static int zfcp_reqlist_init(struct zfcp_adapter *adapter) | 121 | static int zfcp_reqlist_alloc(struct zfcp_adapter *adapter) |
122 | { | 122 | { |
123 | int i; | 123 | int idx; |
124 | 124 | ||
125 | adapter->req_list = kcalloc(REQUEST_LIST_SIZE, sizeof(struct list_head), | 125 | adapter->req_list = kcalloc(REQUEST_LIST_SIZE, sizeof(struct list_head), |
126 | GFP_KERNEL); | 126 | GFP_KERNEL); |
127 | |||
128 | if (!adapter->req_list) | 127 | if (!adapter->req_list) |
129 | return -ENOMEM; | 128 | return -ENOMEM; |
130 | 129 | ||
131 | for (i=0; i<REQUEST_LIST_SIZE; i++) | 130 | for (idx = 0; idx < REQUEST_LIST_SIZE; idx++) |
132 | INIT_LIST_HEAD(&adapter->req_list[i]); | 131 | INIT_LIST_HEAD(&adapter->req_list[idx]); |
133 | |||
134 | return 0; | 132 | return 0; |
135 | } | 133 | } |
136 | 134 | ||
137 | static void zfcp_reqlist_free(struct zfcp_adapter *adapter) | 135 | static void zfcp_reqlist_free(struct zfcp_adapter *adapter) |
138 | { | 136 | { |
139 | struct zfcp_fsf_req *request, *tmp; | ||
140 | unsigned int i; | ||
141 | |||
142 | for (i=0; i<REQUEST_LIST_SIZE; i++) { | ||
143 | if (list_empty(&adapter->req_list[i])) | ||
144 | continue; | ||
145 | |||
146 | list_for_each_entry_safe(request, tmp, | ||
147 | &adapter->req_list[i], list) | ||
148 | list_del(&request->list); | ||
149 | } | ||
150 | |||
151 | kfree(adapter->req_list); | 137 | kfree(adapter->req_list); |
152 | } | 138 | } |
153 | 139 | ||
154 | void zfcp_reqlist_add(struct zfcp_adapter *adapter, | ||
155 | struct zfcp_fsf_req *fsf_req) | ||
156 | { | ||
157 | unsigned int i; | ||
158 | |||
159 | i = fsf_req->req_id % REQUEST_LIST_SIZE; | ||
160 | list_add_tail(&fsf_req->list, &adapter->req_list[i]); | ||
161 | } | ||
162 | |||
163 | void zfcp_reqlist_remove(struct zfcp_adapter *adapter, unsigned long req_id) | ||
164 | { | ||
165 | struct zfcp_fsf_req *request, *tmp; | ||
166 | unsigned int i, counter; | ||
167 | u64 dbg_tmp[2]; | ||
168 | |||
169 | i = req_id % REQUEST_LIST_SIZE; | ||
170 | BUG_ON(list_empty(&adapter->req_list[i])); | ||
171 | |||
172 | counter = 0; | ||
173 | list_for_each_entry_safe(request, tmp, &adapter->req_list[i], list) { | ||
174 | if (request->req_id == req_id) { | ||
175 | dbg_tmp[0] = (u64) atomic_read(&adapter->reqs_active); | ||
176 | dbg_tmp[1] = (u64) counter; | ||
177 | debug_event(adapter->erp_dbf, 4, (void *) dbg_tmp, 16); | ||
178 | list_del(&request->list); | ||
179 | break; | ||
180 | } | ||
181 | counter++; | ||
182 | } | ||
183 | } | ||
184 | |||
185 | struct zfcp_fsf_req *zfcp_reqlist_ismember(struct zfcp_adapter *adapter, | ||
186 | unsigned long req_id) | ||
187 | { | ||
188 | struct zfcp_fsf_req *request, *tmp; | ||
189 | unsigned int i; | ||
190 | |||
191 | /* 0 is reserved as an invalid req_id */ | ||
192 | if (req_id == 0) | ||
193 | return NULL; | ||
194 | |||
195 | i = req_id % REQUEST_LIST_SIZE; | ||
196 | |||
197 | list_for_each_entry_safe(request, tmp, &adapter->req_list[i], list) | ||
198 | if (request->req_id == req_id) | ||
199 | return request; | ||
200 | |||
201 | return NULL; | ||
202 | } | ||
203 | |||
204 | int zfcp_reqlist_isempty(struct zfcp_adapter *adapter) | 140 | int zfcp_reqlist_isempty(struct zfcp_adapter *adapter) |
205 | { | 141 | { |
206 | unsigned int i; | 142 | unsigned int idx; |
207 | 143 | ||
208 | for (i=0; i<REQUEST_LIST_SIZE; i++) | 144 | for (idx = 0; idx < REQUEST_LIST_SIZE; idx++) |
209 | if (!list_empty(&adapter->req_list[i])) | 145 | if (!list_empty(&adapter->req_list[idx])) |
210 | return 0; | 146 | return 0; |
211 | |||
212 | return 1; | 147 | return 1; |
213 | } | 148 | } |
214 | 149 | ||
@@ -913,6 +848,8 @@ zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun) | |||
913 | unit->sysfs_device.release = zfcp_sysfs_unit_release; | 848 | unit->sysfs_device.release = zfcp_sysfs_unit_release; |
914 | dev_set_drvdata(&unit->sysfs_device, unit); | 849 | dev_set_drvdata(&unit->sysfs_device, unit); |
915 | 850 | ||
851 | init_waitqueue_head(&unit->scsi_scan_wq); | ||
852 | |||
916 | /* mark unit unusable as long as sysfs registration is not complete */ | 853 | /* mark unit unusable as long as sysfs registration is not complete */ |
917 | atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status); | 854 | atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status); |
918 | 855 | ||
@@ -1104,7 +1041,7 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) | |||
1104 | 1041 | ||
1105 | /* initialize list of fsf requests */ | 1042 | /* initialize list of fsf requests */ |
1106 | spin_lock_init(&adapter->req_list_lock); | 1043 | spin_lock_init(&adapter->req_list_lock); |
1107 | retval = zfcp_reqlist_init(adapter); | 1044 | retval = zfcp_reqlist_alloc(adapter); |
1108 | if (retval) { | 1045 | if (retval) { |
1109 | ZFCP_LOG_INFO("request list initialization failed\n"); | 1046 | ZFCP_LOG_INFO("request list initialization failed\n"); |
1110 | goto failed_low_mem_buffers; | 1047 | goto failed_low_mem_buffers; |
@@ -1165,6 +1102,7 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) | |||
1165 | zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev); | 1102 | zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev); |
1166 | sysfs_failed: | 1103 | sysfs_failed: |
1167 | dev_set_drvdata(&ccw_device->dev, NULL); | 1104 | dev_set_drvdata(&ccw_device->dev, NULL); |
1105 | zfcp_reqlist_free(adapter); | ||
1168 | failed_low_mem_buffers: | 1106 | failed_low_mem_buffers: |
1169 | zfcp_free_low_mem_buffers(adapter); | 1107 | zfcp_free_low_mem_buffers(adapter); |
1170 | if (qdio_free(ccw_device) != 0) | 1108 | if (qdio_free(ccw_device) != 0) |
@@ -1497,7 +1435,7 @@ zfcp_fsf_incoming_els_plogi(struct zfcp_adapter *adapter, | |||
1497 | 1435 | ||
1498 | if (!port || (port->wwpn != (*(wwn_t *) &els_plogi->serv_param.wwpn))) { | 1436 | if (!port || (port->wwpn != (*(wwn_t *) &els_plogi->serv_param.wwpn))) { |
1499 | ZFCP_LOG_DEBUG("ignored incoming PLOGI for nonexisting port " | 1437 | ZFCP_LOG_DEBUG("ignored incoming PLOGI for nonexisting port " |
1500 | "with d_id 0x%08x on adapter %s\n", | 1438 | "with d_id 0x%06x on adapter %s\n", |
1501 | status_buffer->d_id, | 1439 | status_buffer->d_id, |
1502 | zfcp_get_busid_by_adapter(adapter)); | 1440 | zfcp_get_busid_by_adapter(adapter)); |
1503 | } else { | 1441 | } else { |
@@ -1522,7 +1460,7 @@ zfcp_fsf_incoming_els_logo(struct zfcp_adapter *adapter, | |||
1522 | 1460 | ||
1523 | if (!port || (port->wwpn != els_logo->nport_wwpn)) { | 1461 | if (!port || (port->wwpn != els_logo->nport_wwpn)) { |
1524 | ZFCP_LOG_DEBUG("ignored incoming LOGO for nonexisting port " | 1462 | ZFCP_LOG_DEBUG("ignored incoming LOGO for nonexisting port " |
1525 | "with d_id 0x%08x on adapter %s\n", | 1463 | "with d_id 0x%06x on adapter %s\n", |
1526 | status_buffer->d_id, | 1464 | status_buffer->d_id, |
1527 | zfcp_get_busid_by_adapter(adapter)); | 1465 | zfcp_get_busid_by_adapter(adapter)); |
1528 | } else { | 1466 | } else { |
@@ -1704,7 +1642,7 @@ static void zfcp_ns_gid_pn_handler(unsigned long data) | |||
1704 | /* looks like a valid d_id */ | 1642 | /* looks like a valid d_id */ |
1705 | port->d_id = ct_iu_resp->d_id & ZFCP_DID_MASK; | 1643 | port->d_id = ct_iu_resp->d_id & ZFCP_DID_MASK; |
1706 | atomic_set_mask(ZFCP_STATUS_PORT_DID_DID, &port->status); | 1644 | atomic_set_mask(ZFCP_STATUS_PORT_DID_DID, &port->status); |
1707 | ZFCP_LOG_DEBUG("adapter %s: wwpn=0x%016Lx ---> d_id=0x%08x\n", | 1645 | ZFCP_LOG_DEBUG("adapter %s: wwpn=0x%016Lx ---> d_id=0x%06x\n", |
1708 | zfcp_get_busid_by_port(port), port->wwpn, port->d_id); | 1646 | zfcp_get_busid_by_port(port), port->wwpn, port->d_id); |
1709 | goto out; | 1647 | goto out; |
1710 | 1648 | ||
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 32933ed54b8a..22649639230b 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h | |||
@@ -637,6 +637,7 @@ do { \ | |||
637 | #define ZFCP_STATUS_UNIT_SHARED 0x00000004 | 637 | #define ZFCP_STATUS_UNIT_SHARED 0x00000004 |
638 | #define ZFCP_STATUS_UNIT_READONLY 0x00000008 | 638 | #define ZFCP_STATUS_UNIT_READONLY 0x00000008 |
639 | #define ZFCP_STATUS_UNIT_REGISTERED 0x00000010 | 639 | #define ZFCP_STATUS_UNIT_REGISTERED 0x00000010 |
640 | #define ZFCP_STATUS_UNIT_SCSI_WORK_PENDING 0x00000020 | ||
640 | 641 | ||
641 | /* FSF request status (this does not have a common part) */ | 642 | /* FSF request status (this does not have a common part) */ |
642 | #define ZFCP_STATUS_FSFREQ_NOT_INIT 0x00000000 | 643 | #define ZFCP_STATUS_FSFREQ_NOT_INIT 0x00000000 |
@@ -980,6 +981,10 @@ struct zfcp_unit { | |||
980 | struct scsi_device *device; /* scsi device struct pointer */ | 981 | struct scsi_device *device; /* scsi device struct pointer */ |
981 | struct zfcp_erp_action erp_action; /* pending error recovery */ | 982 | struct zfcp_erp_action erp_action; /* pending error recovery */ |
982 | atomic_t erp_counter; | 983 | atomic_t erp_counter; |
984 | wait_queue_head_t scsi_scan_wq; /* can be used to wait until | ||
985 | all scsi_scan_target | ||
986 | requests have been | ||
987 | completed. */ | ||
983 | }; | 988 | }; |
984 | 989 | ||
985 | /* FSF request */ | 990 | /* FSF request */ |
@@ -1085,6 +1090,42 @@ extern void _zfcp_hex_dump(char *, int); | |||
1085 | #define zfcp_get_busid_by_unit(unit) (zfcp_get_busid_by_port(unit->port)) | 1090 | #define zfcp_get_busid_by_unit(unit) (zfcp_get_busid_by_port(unit->port)) |
1086 | 1091 | ||
1087 | /* | 1092 | /* |
1093 | * Helper functions for request ID management. | ||
1094 | */ | ||
1095 | static inline int zfcp_reqlist_hash(unsigned long req_id) | ||
1096 | { | ||
1097 | return req_id % REQUEST_LIST_SIZE; | ||
1098 | } | ||
1099 | |||
1100 | static inline void zfcp_reqlist_add(struct zfcp_adapter *adapter, | ||
1101 | struct zfcp_fsf_req *fsf_req) | ||
1102 | { | ||
1103 | unsigned int idx; | ||
1104 | |||
1105 | idx = zfcp_reqlist_hash(fsf_req->req_id); | ||
1106 | list_add_tail(&fsf_req->list, &adapter->req_list[idx]); | ||
1107 | } | ||
1108 | |||
1109 | static inline void zfcp_reqlist_remove(struct zfcp_adapter *adapter, | ||
1110 | struct zfcp_fsf_req *fsf_req) | ||
1111 | { | ||
1112 | list_del(&fsf_req->list); | ||
1113 | } | ||
1114 | |||
1115 | static inline struct zfcp_fsf_req * | ||
1116 | zfcp_reqlist_find(struct zfcp_adapter *adapter, unsigned long req_id) | ||
1117 | { | ||
1118 | struct zfcp_fsf_req *request; | ||
1119 | unsigned int idx; | ||
1120 | |||
1121 | idx = zfcp_reqlist_hash(req_id); | ||
1122 | list_for_each_entry(request, &adapter->req_list[idx], list) | ||
1123 | if (request->req_id == req_id) | ||
1124 | return request; | ||
1125 | return NULL; | ||
1126 | } | ||
1127 | |||
1128 | /* | ||
1088 | * functions needed for reference/usage counting | 1129 | * functions needed for reference/usage counting |
1089 | */ | 1130 | */ |
1090 | 1131 | ||
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index c1f2d4b14c2b..aef66bc2b6ca 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c | |||
@@ -179,7 +179,7 @@ static void zfcp_close_fsf(struct zfcp_adapter *adapter) | |||
179 | static void zfcp_fsf_request_timeout_handler(unsigned long data) | 179 | static void zfcp_fsf_request_timeout_handler(unsigned long data) |
180 | { | 180 | { |
181 | struct zfcp_adapter *adapter = (struct zfcp_adapter *) data; | 181 | struct zfcp_adapter *adapter = (struct zfcp_adapter *) data; |
182 | zfcp_erp_adapter_reopen(adapter, 0); | 182 | zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED); |
183 | } | 183 | } |
184 | 184 | ||
185 | void zfcp_fsf_start_timer(struct zfcp_fsf_req *fsf_req, unsigned long timeout) | 185 | void zfcp_fsf_start_timer(struct zfcp_fsf_req *fsf_req, unsigned long timeout) |
@@ -342,9 +342,9 @@ zfcp_erp_adisc(struct zfcp_port *port) | |||
342 | adisc->wwpn = fc_host_port_name(adapter->scsi_host); | 342 | adisc->wwpn = fc_host_port_name(adapter->scsi_host); |
343 | adisc->wwnn = fc_host_node_name(adapter->scsi_host); | 343 | adisc->wwnn = fc_host_node_name(adapter->scsi_host); |
344 | adisc->nport_id = fc_host_port_id(adapter->scsi_host); | 344 | adisc->nport_id = fc_host_port_id(adapter->scsi_host); |
345 | ZFCP_LOG_INFO("ADISC request from s_id 0x%08x to d_id 0x%08x " | 345 | ZFCP_LOG_INFO("ADISC request from s_id 0x%06x to d_id 0x%06x " |
346 | "(wwpn=0x%016Lx, wwnn=0x%016Lx, " | 346 | "(wwpn=0x%016Lx, wwnn=0x%016Lx, " |
347 | "hard_nport_id=0x%08x, nport_id=0x%08x)\n", | 347 | "hard_nport_id=0x%06x, nport_id=0x%06x)\n", |
348 | adisc->nport_id, send_els->d_id, (wwn_t) adisc->wwpn, | 348 | adisc->nport_id, send_els->d_id, (wwn_t) adisc->wwpn, |
349 | (wwn_t) adisc->wwnn, adisc->hard_nport_id, | 349 | (wwn_t) adisc->wwnn, adisc->hard_nport_id, |
350 | adisc->nport_id); | 350 | adisc->nport_id); |
@@ -352,7 +352,7 @@ zfcp_erp_adisc(struct zfcp_port *port) | |||
352 | retval = zfcp_fsf_send_els(send_els); | 352 | retval = zfcp_fsf_send_els(send_els); |
353 | if (retval != 0) { | 353 | if (retval != 0) { |
354 | ZFCP_LOG_NORMAL("error: initiation of Send ELS failed for port " | 354 | ZFCP_LOG_NORMAL("error: initiation of Send ELS failed for port " |
355 | "0x%08x on adapter %s\n", send_els->d_id, | 355 | "0x%06x on adapter %s\n", send_els->d_id, |
356 | zfcp_get_busid_by_adapter(adapter)); | 356 | zfcp_get_busid_by_adapter(adapter)); |
357 | goto freemem; | 357 | goto freemem; |
358 | } | 358 | } |
@@ -398,7 +398,7 @@ zfcp_erp_adisc_handler(unsigned long data) | |||
398 | if (send_els->status != 0) { | 398 | if (send_els->status != 0) { |
399 | ZFCP_LOG_NORMAL("ELS request rejected/timed out, " | 399 | ZFCP_LOG_NORMAL("ELS request rejected/timed out, " |
400 | "force physical port reopen " | 400 | "force physical port reopen " |
401 | "(adapter %s, port d_id=0x%08x)\n", | 401 | "(adapter %s, port d_id=0x%06x)\n", |
402 | zfcp_get_busid_by_adapter(adapter), d_id); | 402 | zfcp_get_busid_by_adapter(adapter), d_id); |
403 | debug_text_event(adapter->erp_dbf, 3, "forcreop"); | 403 | debug_text_event(adapter->erp_dbf, 3, "forcreop"); |
404 | if (zfcp_erp_port_forced_reopen(port, 0)) | 404 | if (zfcp_erp_port_forced_reopen(port, 0)) |
@@ -411,9 +411,9 @@ zfcp_erp_adisc_handler(unsigned long data) | |||
411 | 411 | ||
412 | adisc = zfcp_sg_to_address(send_els->resp); | 412 | adisc = zfcp_sg_to_address(send_els->resp); |
413 | 413 | ||
414 | ZFCP_LOG_INFO("ADISC response from d_id 0x%08x to s_id " | 414 | ZFCP_LOG_INFO("ADISC response from d_id 0x%06x to s_id " |
415 | "0x%08x (wwpn=0x%016Lx, wwnn=0x%016Lx, " | 415 | "0x%06x (wwpn=0x%016Lx, wwnn=0x%016Lx, " |
416 | "hard_nport_id=0x%08x, nport_id=0x%08x)\n", | 416 | "hard_nport_id=0x%06x, nport_id=0x%06x)\n", |
417 | d_id, fc_host_port_id(adapter->scsi_host), | 417 | d_id, fc_host_port_id(adapter->scsi_host), |
418 | (wwn_t) adisc->wwpn, (wwn_t) adisc->wwnn, | 418 | (wwn_t) adisc->wwpn, (wwn_t) adisc->wwnn, |
419 | adisc->hard_nport_id, adisc->nport_id); | 419 | adisc->hard_nport_id, adisc->nport_id); |
@@ -847,8 +847,7 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action) | |||
847 | if (erp_action->fsf_req) { | 847 | if (erp_action->fsf_req) { |
848 | /* take lock to ensure that request is not deleted meanwhile */ | 848 | /* take lock to ensure that request is not deleted meanwhile */ |
849 | spin_lock(&adapter->req_list_lock); | 849 | spin_lock(&adapter->req_list_lock); |
850 | if (zfcp_reqlist_ismember(adapter, | 850 | if (zfcp_reqlist_find(adapter, erp_action->fsf_req->req_id)) { |
851 | erp_action->fsf_req->req_id)) { | ||
852 | /* fsf_req still exists */ | 851 | /* fsf_req still exists */ |
853 | debug_text_event(adapter->erp_dbf, 3, "a_ca_req"); | 852 | debug_text_event(adapter->erp_dbf, 3, "a_ca_req"); |
854 | debug_event(adapter->erp_dbf, 3, &erp_action->fsf_req, | 853 | debug_event(adapter->erp_dbf, 3, &erp_action->fsf_req, |
@@ -1377,7 +1376,7 @@ zfcp_erp_port_failed(struct zfcp_port *port) | |||
1377 | 1376 | ||
1378 | if (atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status)) | 1377 | if (atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status)) |
1379 | ZFCP_LOG_NORMAL("port erp failed (adapter %s, " | 1378 | ZFCP_LOG_NORMAL("port erp failed (adapter %s, " |
1380 | "port d_id=0x%08x)\n", | 1379 | "port d_id=0x%06x)\n", |
1381 | zfcp_get_busid_by_port(port), port->d_id); | 1380 | zfcp_get_busid_by_port(port), port->d_id); |
1382 | else | 1381 | else |
1383 | ZFCP_LOG_NORMAL("port erp failed (adapter %s, wwpn=0x%016Lx)\n", | 1382 | ZFCP_LOG_NORMAL("port erp failed (adapter %s, wwpn=0x%016Lx)\n", |
@@ -1591,6 +1590,62 @@ zfcp_erp_strategy_check_adapter(struct zfcp_adapter *adapter, int result) | |||
1591 | return result; | 1590 | return result; |
1592 | } | 1591 | } |
1593 | 1592 | ||
1593 | struct zfcp_erp_add_work { | ||
1594 | struct zfcp_unit *unit; | ||
1595 | struct work_struct work; | ||
1596 | }; | ||
1597 | |||
1598 | /** | ||
1599 | * zfcp_erp_scsi_scan | ||
1600 | * @data: pointer to a struct zfcp_erp_add_work | ||
1601 | * | ||
1602 | * Registers a logical unit with the SCSI stack. | ||
1603 | */ | ||
1604 | static void zfcp_erp_scsi_scan(struct work_struct *work) | ||
1605 | { | ||
1606 | struct zfcp_erp_add_work *p = | ||
1607 | container_of(work, struct zfcp_erp_add_work, work); | ||
1608 | struct zfcp_unit *unit = p->unit; | ||
1609 | struct fc_rport *rport = unit->port->rport; | ||
1610 | scsi_scan_target(&rport->dev, 0, rport->scsi_target_id, | ||
1611 | unit->scsi_lun, 0); | ||
1612 | atomic_clear_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status); | ||
1613 | wake_up(&unit->scsi_scan_wq); | ||
1614 | zfcp_unit_put(unit); | ||
1615 | kfree(p); | ||
1616 | } | ||
1617 | |||
1618 | /** | ||
1619 | * zfcp_erp_schedule_work | ||
1620 | * @unit: pointer to unit which should be registered with SCSI stack | ||
1621 | * | ||
1622 | * Schedules work which registers a unit with the SCSI stack | ||
1623 | */ | ||
1624 | static void | ||
1625 | zfcp_erp_schedule_work(struct zfcp_unit *unit) | ||
1626 | { | ||
1627 | struct zfcp_erp_add_work *p; | ||
1628 | |||
1629 | p = kmalloc(sizeof(*p), GFP_KERNEL); | ||
1630 | if (!p) { | ||
1631 | ZFCP_LOG_NORMAL("error: Out of resources. Could not register " | ||
1632 | "the FCP-LUN 0x%Lx connected to " | ||
1633 | "the port with WWPN 0x%Lx connected to " | ||
1634 | "the adapter %s with the SCSI stack.\n", | ||
1635 | unit->fcp_lun, | ||
1636 | unit->port->wwpn, | ||
1637 | zfcp_get_busid_by_unit(unit)); | ||
1638 | return; | ||
1639 | } | ||
1640 | |||
1641 | zfcp_unit_get(unit); | ||
1642 | memset(p, 0, sizeof(*p)); | ||
1643 | atomic_set_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status); | ||
1644 | INIT_WORK(&p->work, zfcp_erp_scsi_scan); | ||
1645 | p->unit = unit; | ||
1646 | schedule_work(&p->work); | ||
1647 | } | ||
1648 | |||
1594 | /* | 1649 | /* |
1595 | * function: | 1650 | * function: |
1596 | * | 1651 | * |
@@ -2401,7 +2456,7 @@ zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *erp_action) | |||
2401 | retval = ZFCP_ERP_FAILED; | 2456 | retval = ZFCP_ERP_FAILED; |
2402 | } | 2457 | } |
2403 | } else { | 2458 | } else { |
2404 | ZFCP_LOG_DEBUG("port 0x%016Lx has d_id=0x%08x -> " | 2459 | ZFCP_LOG_DEBUG("port 0x%016Lx has d_id=0x%06x -> " |
2405 | "trying open\n", port->wwpn, port->d_id); | 2460 | "trying open\n", port->wwpn, port->d_id); |
2406 | retval = zfcp_erp_port_strategy_open_port(erp_action); | 2461 | retval = zfcp_erp_port_strategy_open_port(erp_action); |
2407 | } | 2462 | } |
@@ -2441,7 +2496,7 @@ zfcp_erp_port_strategy_open_nameserver(struct zfcp_erp_action *erp_action) | |||
2441 | case ZFCP_ERP_STEP_UNINITIALIZED: | 2496 | case ZFCP_ERP_STEP_UNINITIALIZED: |
2442 | case ZFCP_ERP_STEP_PHYS_PORT_CLOSING: | 2497 | case ZFCP_ERP_STEP_PHYS_PORT_CLOSING: |
2443 | case ZFCP_ERP_STEP_PORT_CLOSING: | 2498 | case ZFCP_ERP_STEP_PORT_CLOSING: |
2444 | ZFCP_LOG_DEBUG("port 0x%016Lx has d_id=0x%08x -> trying open\n", | 2499 | ZFCP_LOG_DEBUG("port 0x%016Lx has d_id=0x%06x -> trying open\n", |
2445 | port->wwpn, port->d_id); | 2500 | port->wwpn, port->d_id); |
2446 | retval = zfcp_erp_port_strategy_open_port(erp_action); | 2501 | retval = zfcp_erp_port_strategy_open_port(erp_action); |
2447 | break; | 2502 | break; |
@@ -3092,9 +3147,9 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter, | |||
3092 | && port->rport) { | 3147 | && port->rport) { |
3093 | atomic_set_mask(ZFCP_STATUS_UNIT_REGISTERED, | 3148 | atomic_set_mask(ZFCP_STATUS_UNIT_REGISTERED, |
3094 | &unit->status); | 3149 | &unit->status); |
3095 | scsi_scan_target(&port->rport->dev, 0, | 3150 | if (atomic_test_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, |
3096 | port->rport->scsi_target_id, | 3151 | &unit->status) == 0) |
3097 | unit->scsi_lun, 0); | 3152 | zfcp_erp_schedule_work(unit); |
3098 | } | 3153 | } |
3099 | zfcp_unit_put(unit); | 3154 | zfcp_unit_put(unit); |
3100 | break; | 3155 | break; |
@@ -3121,7 +3176,7 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter, | |||
3121 | zfcp_get_busid_by_port(port), | 3176 | zfcp_get_busid_by_port(port), |
3122 | port->wwpn); | 3177 | port->wwpn); |
3123 | else { | 3178 | else { |
3124 | scsi_flush_work(adapter->scsi_host); | 3179 | scsi_target_unblock(&port->rport->dev); |
3125 | port->rport->maxframe_size = port->maxframe_size; | 3180 | port->rport->maxframe_size = port->maxframe_size; |
3126 | port->rport->supported_classes = | 3181 | port->rport->supported_classes = |
3127 | port->supported_classes; | 3182 | port->supported_classes; |
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 01386ac688a2..991d45667a44 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h | |||
@@ -184,10 +184,6 @@ extern void zfcp_scsi_dbf_event_abort(const char *, struct zfcp_adapter *, | |||
184 | unsigned long); | 184 | unsigned long); |
185 | extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *, | 185 | extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *, |
186 | struct scsi_cmnd *); | 186 | struct scsi_cmnd *); |
187 | extern void zfcp_reqlist_add(struct zfcp_adapter *, struct zfcp_fsf_req *); | ||
188 | extern void zfcp_reqlist_remove(struct zfcp_adapter *, unsigned long); | ||
189 | extern struct zfcp_fsf_req *zfcp_reqlist_ismember(struct zfcp_adapter *, | ||
190 | unsigned long); | ||
191 | extern int zfcp_reqlist_isempty(struct zfcp_adapter *); | 187 | extern int zfcp_reqlist_isempty(struct zfcp_adapter *); |
192 | 188 | ||
193 | #endif /* ZFCP_EXT_H */ | 189 | #endif /* ZFCP_EXT_H */ |
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 4c0a59afd5c8..a8b02542ac2d 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -828,7 +828,7 @@ zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *fsf_req) | |||
828 | 828 | ||
829 | if (!port || (port->d_id != (status_buffer->d_id & ZFCP_DID_MASK))) { | 829 | if (!port || (port->d_id != (status_buffer->d_id & ZFCP_DID_MASK))) { |
830 | ZFCP_LOG_NORMAL("bug: Reopen port indication received for" | 830 | ZFCP_LOG_NORMAL("bug: Reopen port indication received for" |
831 | "nonexisting port with d_id 0x%08x on " | 831 | "nonexisting port with d_id 0x%06x on " |
832 | "adapter %s. Ignored.\n", | 832 | "adapter %s. Ignored.\n", |
833 | status_buffer->d_id & ZFCP_DID_MASK, | 833 | status_buffer->d_id & ZFCP_DID_MASK, |
834 | zfcp_get_busid_by_adapter(adapter)); | 834 | zfcp_get_busid_by_adapter(adapter)); |
@@ -853,7 +853,7 @@ zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *fsf_req) | |||
853 | &status_buffer->status_subtype, sizeof (u32)); | 853 | &status_buffer->status_subtype, sizeof (u32)); |
854 | ZFCP_LOG_NORMAL("bug: Undefined status subtype received " | 854 | ZFCP_LOG_NORMAL("bug: Undefined status subtype received " |
855 | "for a reopen indication on port with " | 855 | "for a reopen indication on port with " |
856 | "d_id 0x%08x on the adapter %s. " | 856 | "d_id 0x%06x on the adapter %s. " |
857 | "Ignored. (debug info 0x%x)\n", | 857 | "Ignored. (debug info 0x%x)\n", |
858 | status_buffer->d_id, | 858 | status_buffer->d_id, |
859 | zfcp_get_busid_by_adapter(adapter), | 859 | zfcp_get_busid_by_adapter(adapter), |
@@ -1156,7 +1156,7 @@ zfcp_fsf_abort_fcp_command(unsigned long old_req_id, | |||
1156 | } | 1156 | } |
1157 | 1157 | ||
1158 | ZFCP_LOG_DEBUG("Abort FCP Command request initiated " | 1158 | ZFCP_LOG_DEBUG("Abort FCP Command request initiated " |
1159 | "(adapter%s, port d_id=0x%08x, " | 1159 | "(adapter%s, port d_id=0x%06x, " |
1160 | "unit x%016Lx, old_req_id=0x%lx)\n", | 1160 | "unit x%016Lx, old_req_id=0x%lx)\n", |
1161 | zfcp_get_busid_by_adapter(adapter), | 1161 | zfcp_get_busid_by_adapter(adapter), |
1162 | unit->port->d_id, | 1162 | unit->port->d_id, |
@@ -1554,7 +1554,7 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req) | |||
1554 | 1554 | ||
1555 | case FSF_ACCESS_DENIED: | 1555 | case FSF_ACCESS_DENIED: |
1556 | ZFCP_LOG_NORMAL("access denied, cannot send generic service " | 1556 | ZFCP_LOG_NORMAL("access denied, cannot send generic service " |
1557 | "command (adapter %s, port d_id=0x%08x)\n", | 1557 | "command (adapter %s, port d_id=0x%06x)\n", |
1558 | zfcp_get_busid_by_port(port), port->d_id); | 1558 | zfcp_get_busid_by_port(port), port->d_id); |
1559 | for (counter = 0; counter < 2; counter++) { | 1559 | for (counter = 0; counter < 2; counter++) { |
1560 | subtable = header->fsf_status_qual.halfword[counter * 2]; | 1560 | subtable = header->fsf_status_qual.halfword[counter * 2]; |
@@ -1576,7 +1576,7 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req) | |||
1576 | 1576 | ||
1577 | case FSF_GENERIC_COMMAND_REJECTED: | 1577 | case FSF_GENERIC_COMMAND_REJECTED: |
1578 | ZFCP_LOG_INFO("generic service command rejected " | 1578 | ZFCP_LOG_INFO("generic service command rejected " |
1579 | "(adapter %s, port d_id=0x%08x)\n", | 1579 | "(adapter %s, port d_id=0x%06x)\n", |
1580 | zfcp_get_busid_by_port(port), port->d_id); | 1580 | zfcp_get_busid_by_port(port), port->d_id); |
1581 | ZFCP_LOG_INFO("status qualifier:\n"); | 1581 | ZFCP_LOG_INFO("status qualifier:\n"); |
1582 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_INFO, | 1582 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_INFO, |
@@ -1602,7 +1602,7 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req) | |||
1602 | 1602 | ||
1603 | case FSF_PORT_BOXED: | 1603 | case FSF_PORT_BOXED: |
1604 | ZFCP_LOG_INFO("port needs to be reopened " | 1604 | ZFCP_LOG_INFO("port needs to be reopened " |
1605 | "(adapter %s, port d_id=0x%08x)\n", | 1605 | "(adapter %s, port d_id=0x%06x)\n", |
1606 | zfcp_get_busid_by_port(port), port->d_id); | 1606 | zfcp_get_busid_by_port(port), port->d_id); |
1607 | debug_text_event(adapter->erp_dbf, 2, "fsf_s_pboxed"); | 1607 | debug_text_event(adapter->erp_dbf, 2, "fsf_s_pboxed"); |
1608 | zfcp_erp_port_boxed(port); | 1608 | zfcp_erp_port_boxed(port); |
@@ -1683,7 +1683,7 @@ zfcp_fsf_send_els(struct zfcp_send_els *els) | |||
1683 | NULL, &lock_flags, &fsf_req); | 1683 | NULL, &lock_flags, &fsf_req); |
1684 | if (ret < 0) { | 1684 | if (ret < 0) { |
1685 | ZFCP_LOG_INFO("error: creation of ELS request failed " | 1685 | ZFCP_LOG_INFO("error: creation of ELS request failed " |
1686 | "(adapter %s, port d_id: 0x%08x)\n", | 1686 | "(adapter %s, port d_id: 0x%06x)\n", |
1687 | zfcp_get_busid_by_adapter(adapter), d_id); | 1687 | zfcp_get_busid_by_adapter(adapter), d_id); |
1688 | goto failed_req; | 1688 | goto failed_req; |
1689 | } | 1689 | } |
@@ -1708,7 +1708,7 @@ zfcp_fsf_send_els(struct zfcp_send_els *els) | |||
1708 | ZFCP_MAX_SBALS_PER_ELS_REQ); | 1708 | ZFCP_MAX_SBALS_PER_ELS_REQ); |
1709 | if (bytes <= 0) { | 1709 | if (bytes <= 0) { |
1710 | ZFCP_LOG_INFO("error: creation of ELS request failed " | 1710 | ZFCP_LOG_INFO("error: creation of ELS request failed " |
1711 | "(adapter %s, port d_id: 0x%08x)\n", | 1711 | "(adapter %s, port d_id: 0x%06x)\n", |
1712 | zfcp_get_busid_by_adapter(adapter), d_id); | 1712 | zfcp_get_busid_by_adapter(adapter), d_id); |
1713 | if (bytes == 0) { | 1713 | if (bytes == 0) { |
1714 | ret = -ENOMEM; | 1714 | ret = -ENOMEM; |
@@ -1725,7 +1725,7 @@ zfcp_fsf_send_els(struct zfcp_send_els *els) | |||
1725 | ZFCP_MAX_SBALS_PER_ELS_REQ); | 1725 | ZFCP_MAX_SBALS_PER_ELS_REQ); |
1726 | if (bytes <= 0) { | 1726 | if (bytes <= 0) { |
1727 | ZFCP_LOG_INFO("error: creation of ELS request failed " | 1727 | ZFCP_LOG_INFO("error: creation of ELS request failed " |
1728 | "(adapter %s, port d_id: 0x%08x)\n", | 1728 | "(adapter %s, port d_id: 0x%06x)\n", |
1729 | zfcp_get_busid_by_adapter(adapter), d_id); | 1729 | zfcp_get_busid_by_adapter(adapter), d_id); |
1730 | if (bytes == 0) { | 1730 | if (bytes == 0) { |
1731 | ret = -ENOMEM; | 1731 | ret = -ENOMEM; |
@@ -1739,7 +1739,7 @@ zfcp_fsf_send_els(struct zfcp_send_els *els) | |||
1739 | /* reject request */ | 1739 | /* reject request */ |
1740 | ZFCP_LOG_INFO("error: microcode does not support chained SBALs" | 1740 | ZFCP_LOG_INFO("error: microcode does not support chained SBALs" |
1741 | ", ELS request too big (adapter %s, " | 1741 | ", ELS request too big (adapter %s, " |
1742 | "port d_id: 0x%08x)\n", | 1742 | "port d_id: 0x%06x)\n", |
1743 | zfcp_get_busid_by_adapter(adapter), d_id); | 1743 | zfcp_get_busid_by_adapter(adapter), d_id); |
1744 | ret = -EOPNOTSUPP; | 1744 | ret = -EOPNOTSUPP; |
1745 | goto failed_send; | 1745 | goto failed_send; |
@@ -1760,13 +1760,13 @@ zfcp_fsf_send_els(struct zfcp_send_els *els) | |||
1760 | ret = zfcp_fsf_req_send(fsf_req); | 1760 | ret = zfcp_fsf_req_send(fsf_req); |
1761 | if (ret) { | 1761 | if (ret) { |
1762 | ZFCP_LOG_DEBUG("error: initiation of ELS request failed " | 1762 | ZFCP_LOG_DEBUG("error: initiation of ELS request failed " |
1763 | "(adapter %s, port d_id: 0x%08x)\n", | 1763 | "(adapter %s, port d_id: 0x%06x)\n", |
1764 | zfcp_get_busid_by_adapter(adapter), d_id); | 1764 | zfcp_get_busid_by_adapter(adapter), d_id); |
1765 | goto failed_send; | 1765 | goto failed_send; |
1766 | } | 1766 | } |
1767 | 1767 | ||
1768 | ZFCP_LOG_DEBUG("ELS request initiated (adapter %s, port d_id: " | 1768 | ZFCP_LOG_DEBUG("ELS request initiated (adapter %s, port d_id: " |
1769 | "0x%08x)\n", zfcp_get_busid_by_adapter(adapter), d_id); | 1769 | "0x%06x)\n", zfcp_get_busid_by_adapter(adapter), d_id); |
1770 | goto out; | 1770 | goto out; |
1771 | 1771 | ||
1772 | failed_send: | 1772 | failed_send: |
@@ -1859,7 +1859,7 @@ static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req) | |||
1859 | case FSF_ELS_COMMAND_REJECTED: | 1859 | case FSF_ELS_COMMAND_REJECTED: |
1860 | ZFCP_LOG_INFO("ELS has been rejected because command filter " | 1860 | ZFCP_LOG_INFO("ELS has been rejected because command filter " |
1861 | "prohibited sending " | 1861 | "prohibited sending " |
1862 | "(adapter: %s, port d_id: 0x%08x)\n", | 1862 | "(adapter: %s, port d_id: 0x%06x)\n", |
1863 | zfcp_get_busid_by_adapter(adapter), d_id); | 1863 | zfcp_get_busid_by_adapter(adapter), d_id); |
1864 | 1864 | ||
1865 | break; | 1865 | break; |
@@ -1907,7 +1907,7 @@ static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req) | |||
1907 | 1907 | ||
1908 | case FSF_ACCESS_DENIED: | 1908 | case FSF_ACCESS_DENIED: |
1909 | ZFCP_LOG_NORMAL("access denied, cannot send ELS command " | 1909 | ZFCP_LOG_NORMAL("access denied, cannot send ELS command " |
1910 | "(adapter %s, port d_id=0x%08x)\n", | 1910 | "(adapter %s, port d_id=0x%06x)\n", |
1911 | zfcp_get_busid_by_adapter(adapter), d_id); | 1911 | zfcp_get_busid_by_adapter(adapter), d_id); |
1912 | for (counter = 0; counter < 2; counter++) { | 1912 | for (counter = 0; counter < 2; counter++) { |
1913 | subtable = header->fsf_status_qual.halfword[counter * 2]; | 1913 | subtable = header->fsf_status_qual.halfword[counter * 2]; |
@@ -2070,7 +2070,7 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) | |||
2070 | ZFCP_LOG_NORMAL("The adapter %s reported the following characteristics:\n" | 2070 | ZFCP_LOG_NORMAL("The adapter %s reported the following characteristics:\n" |
2071 | "WWNN 0x%016Lx, " | 2071 | "WWNN 0x%016Lx, " |
2072 | "WWPN 0x%016Lx, " | 2072 | "WWPN 0x%016Lx, " |
2073 | "S_ID 0x%08x,\n" | 2073 | "S_ID 0x%06x,\n" |
2074 | "adapter version 0x%x, " | 2074 | "adapter version 0x%x, " |
2075 | "LIC version 0x%x, " | 2075 | "LIC version 0x%x, " |
2076 | "FC link speed %d Gb/s\n", | 2076 | "FC link speed %d Gb/s\n", |
@@ -3043,6 +3043,7 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) | |||
3043 | queue_designator = &header->fsf_status_qual.fsf_queue_designator; | 3043 | queue_designator = &header->fsf_status_qual.fsf_queue_designator; |
3044 | 3044 | ||
3045 | atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED | | 3045 | atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED | |
3046 | ZFCP_STATUS_COMMON_ACCESS_BOXED | | ||
3046 | ZFCP_STATUS_UNIT_SHARED | | 3047 | ZFCP_STATUS_UNIT_SHARED | |
3047 | ZFCP_STATUS_UNIT_READONLY, | 3048 | ZFCP_STATUS_UNIT_READONLY, |
3048 | &unit->status); | 3049 | &unit->status); |
@@ -4645,23 +4646,22 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags, | |||
4645 | fsf_req->adapter = adapter; | 4646 | fsf_req->adapter = adapter; |
4646 | fsf_req->fsf_command = fsf_cmd; | 4647 | fsf_req->fsf_command = fsf_cmd; |
4647 | INIT_LIST_HEAD(&fsf_req->list); | 4648 | INIT_LIST_HEAD(&fsf_req->list); |
4648 | |||
4649 | /* this is serialized (we are holding req_queue-lock of adapter */ | ||
4650 | if (adapter->req_no == 0) | ||
4651 | adapter->req_no++; | ||
4652 | fsf_req->req_id = adapter->req_no++; | ||
4653 | |||
4654 | init_timer(&fsf_req->timer); | 4649 | init_timer(&fsf_req->timer); |
4655 | zfcp_fsf_req_qtcb_init(fsf_req); | ||
4656 | 4650 | ||
4657 | /* initialize waitqueue which may be used to wait on | 4651 | /* initialize waitqueue which may be used to wait on |
4658 | this request completion */ | 4652 | this request completion */ |
4659 | init_waitqueue_head(&fsf_req->completion_wq); | 4653 | init_waitqueue_head(&fsf_req->completion_wq); |
4660 | 4654 | ||
4661 | ret = zfcp_fsf_req_sbal_get(adapter, req_flags, lock_flags); | 4655 | ret = zfcp_fsf_req_sbal_get(adapter, req_flags, lock_flags); |
4662 | if(ret < 0) { | 4656 | if (ret < 0) |
4663 | goto failed_sbals; | 4657 | goto failed_sbals; |
4664 | } | 4658 | |
4659 | /* this is serialized (we are holding req_queue-lock of adapter) */ | ||
4660 | if (adapter->req_no == 0) | ||
4661 | adapter->req_no++; | ||
4662 | fsf_req->req_id = adapter->req_no++; | ||
4663 | |||
4664 | zfcp_fsf_req_qtcb_init(fsf_req); | ||
4665 | 4665 | ||
4666 | /* | 4666 | /* |
4667 | * We hold queue_lock here. Check if QDIOUP is set and let request fail | 4667 | * We hold queue_lock here. Check if QDIOUP is set and let request fail |
@@ -4788,7 +4788,7 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req) | |||
4788 | retval = -EIO; | 4788 | retval = -EIO; |
4789 | del_timer(&fsf_req->timer); | 4789 | del_timer(&fsf_req->timer); |
4790 | spin_lock(&adapter->req_list_lock); | 4790 | spin_lock(&adapter->req_list_lock); |
4791 | zfcp_reqlist_remove(adapter, fsf_req->req_id); | 4791 | zfcp_reqlist_remove(adapter, fsf_req); |
4792 | spin_unlock(&adapter->req_list_lock); | 4792 | spin_unlock(&adapter->req_list_lock); |
4793 | /* undo changes in request queue made for this request */ | 4793 | /* undo changes in request queue made for this request */ |
4794 | zfcp_qdio_zero_sbals(req_queue->buffer, | 4794 | zfcp_qdio_zero_sbals(req_queue->buffer, |
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index 1e12a78e8edd..cb08ca3cc0f9 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c | |||
@@ -283,10 +283,10 @@ zfcp_qdio_request_handler(struct ccw_device *ccw_device, | |||
283 | } | 283 | } |
284 | 284 | ||
285 | /** | 285 | /** |
286 | * zfcp_qdio_reqid_check - checks for valid reqids or unsolicited status | 286 | * zfcp_qdio_reqid_check - checks for valid reqids. |
287 | */ | 287 | */ |
288 | static int zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, | 288 | static void zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, |
289 | unsigned long req_id) | 289 | unsigned long req_id) |
290 | { | 290 | { |
291 | struct zfcp_fsf_req *fsf_req; | 291 | struct zfcp_fsf_req *fsf_req; |
292 | unsigned long flags; | 292 | unsigned long flags; |
@@ -294,23 +294,22 @@ static int zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, | |||
294 | debug_long_event(adapter->erp_dbf, 4, req_id); | 294 | debug_long_event(adapter->erp_dbf, 4, req_id); |
295 | 295 | ||
296 | spin_lock_irqsave(&adapter->req_list_lock, flags); | 296 | spin_lock_irqsave(&adapter->req_list_lock, flags); |
297 | fsf_req = zfcp_reqlist_ismember(adapter, req_id); | 297 | fsf_req = zfcp_reqlist_find(adapter, req_id); |
298 | 298 | ||
299 | if (!fsf_req) { | 299 | if (!fsf_req) |
300 | spin_unlock_irqrestore(&adapter->req_list_lock, flags); | 300 | /* |
301 | ZFCP_LOG_NORMAL("error: unknown request id (%ld).\n", req_id); | 301 | * Unknown request means that we have potentially memory |
302 | zfcp_erp_adapter_reopen(adapter, 0); | 302 | * corruption and must stop the machine immediatly. |
303 | return -EINVAL; | 303 | */ |
304 | } | 304 | panic("error: unknown request id (%ld) on adapter %s.\n", |
305 | req_id, zfcp_get_busid_by_adapter(adapter)); | ||
305 | 306 | ||
306 | zfcp_reqlist_remove(adapter, req_id); | 307 | zfcp_reqlist_remove(adapter, fsf_req); |
307 | atomic_dec(&adapter->reqs_active); | 308 | atomic_dec(&adapter->reqs_active); |
308 | spin_unlock_irqrestore(&adapter->req_list_lock, flags); | 309 | spin_unlock_irqrestore(&adapter->req_list_lock, flags); |
309 | 310 | ||
310 | /* finish the FSF request */ | 311 | /* finish the FSF request */ |
311 | zfcp_fsf_req_complete(fsf_req); | 312 | zfcp_fsf_req_complete(fsf_req); |
312 | |||
313 | return 0; | ||
314 | } | 313 | } |
315 | 314 | ||
316 | /* | 315 | /* |
@@ -374,27 +373,9 @@ zfcp_qdio_response_handler(struct ccw_device *ccw_device, | |||
374 | 373 | ||
375 | /* look for QDIO request identifiers in SB */ | 374 | /* look for QDIO request identifiers in SB */ |
376 | buffere = &buffer->element[buffere_index]; | 375 | buffere = &buffer->element[buffere_index]; |
377 | retval = zfcp_qdio_reqid_check(adapter, | 376 | zfcp_qdio_reqid_check(adapter, |
378 | (unsigned long) buffere->addr); | 377 | (unsigned long) buffere->addr); |
379 | 378 | ||
380 | if (retval) { | ||
381 | ZFCP_LOG_NORMAL("bug: unexpected inbound " | ||
382 | "packet on adapter %s " | ||
383 | "(reqid=0x%lx, " | ||
384 | "first_element=%d, " | ||
385 | "elements_processed=%d)\n", | ||
386 | zfcp_get_busid_by_adapter(adapter), | ||
387 | (unsigned long) buffere->addr, | ||
388 | first_element, | ||
389 | elements_processed); | ||
390 | ZFCP_LOG_NORMAL("hex dump of inbound buffer " | ||
391 | "at address %p " | ||
392 | "(buffer_index=%d, " | ||
393 | "buffere_index=%d)\n", buffer, | ||
394 | buffer_index, buffere_index); | ||
395 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL, | ||
396 | (char *) buffer, SBAL_SIZE); | ||
397 | } | ||
398 | /* | 379 | /* |
399 | * A single used SBALE per inbound SBALE has been | 380 | * A single used SBALE per inbound SBALE has been |
400 | * implemented by QDIO so far. Hope they will | 381 | * implemented by QDIO so far. Hope they will |
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 99db02062c3b..16e2d64658af 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #define ZFCP_LOG_AREA ZFCP_LOG_AREA_SCSI | 22 | #define ZFCP_LOG_AREA ZFCP_LOG_AREA_SCSI |
23 | 23 | ||
24 | #include "zfcp_ext.h" | 24 | #include "zfcp_ext.h" |
25 | #include <asm/atomic.h> | ||
25 | 26 | ||
26 | static void zfcp_scsi_slave_destroy(struct scsi_device *sdp); | 27 | static void zfcp_scsi_slave_destroy(struct scsi_device *sdp); |
27 | static int zfcp_scsi_slave_alloc(struct scsi_device *sdp); | 28 | static int zfcp_scsi_slave_alloc(struct scsi_device *sdp); |
@@ -179,6 +180,10 @@ static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt) | |||
179 | struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata; | 180 | struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata; |
180 | 181 | ||
181 | if (unit) { | 182 | if (unit) { |
183 | zfcp_erp_wait(unit->port->adapter); | ||
184 | wait_event(unit->scsi_scan_wq, | ||
185 | atomic_test_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, | ||
186 | &unit->status) == 0); | ||
182 | atomic_clear_mask(ZFCP_STATUS_UNIT_REGISTERED, &unit->status); | 187 | atomic_clear_mask(ZFCP_STATUS_UNIT_REGISTERED, &unit->status); |
183 | sdpnt->hostdata = NULL; | 188 | sdpnt->hostdata = NULL; |
184 | unit->device = NULL; | 189 | unit->device = NULL; |
@@ -402,8 +407,8 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) | |||
402 | 407 | ||
403 | /* Check whether corresponding fsf_req is still pending */ | 408 | /* Check whether corresponding fsf_req is still pending */ |
404 | spin_lock(&adapter->req_list_lock); | 409 | spin_lock(&adapter->req_list_lock); |
405 | fsf_req = zfcp_reqlist_ismember(adapter, (unsigned long) | 410 | fsf_req = zfcp_reqlist_find(adapter, |
406 | scpnt->host_scribble); | 411 | (unsigned long) scpnt->host_scribble); |
407 | spin_unlock(&adapter->req_list_lock); | 412 | spin_unlock(&adapter->req_list_lock); |
408 | if (!fsf_req) { | 413 | if (!fsf_req) { |
409 | write_unlock_irqrestore(&adapter->abort_lock, flags); | 414 | write_unlock_irqrestore(&adapter->abort_lock, flags); |