diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_scsi.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_scsi.c | 73 |
1 files changed, 30 insertions, 43 deletions
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 6925a1784682..3ff726afafc6 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c | |||
@@ -9,8 +9,9 @@ | |||
9 | #define KMSG_COMPONENT "zfcp" | 9 | #define KMSG_COMPONENT "zfcp" |
10 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | 10 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt |
11 | 11 | ||
12 | #include "zfcp_ext.h" | ||
13 | #include <asm/atomic.h> | 12 | #include <asm/atomic.h> |
13 | #include "zfcp_ext.h" | ||
14 | #include "zfcp_dbf.h" | ||
14 | 15 | ||
15 | static unsigned int default_depth = 32; | 16 | static unsigned int default_depth = 32; |
16 | module_param_named(queue_depth, default_depth, uint, 0600); | 17 | module_param_named(queue_depth, default_depth, uint, 0600); |
@@ -52,11 +53,11 @@ static int zfcp_scsi_slave_configure(struct scsi_device *sdp) | |||
52 | 53 | ||
53 | static void zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result) | 54 | static void zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result) |
54 | { | 55 | { |
56 | struct zfcp_adapter *adapter = | ||
57 | (struct zfcp_adapter *) scpnt->device->host->hostdata[0]; | ||
55 | set_host_byte(scpnt, result); | 58 | set_host_byte(scpnt, result); |
56 | if ((scpnt->device != NULL) && (scpnt->device->host != NULL)) | 59 | if ((scpnt->device != NULL) && (scpnt->device->host != NULL)) |
57 | zfcp_scsi_dbf_event_result("fail", 4, | 60 | zfcp_dbf_scsi_result("fail", 4, adapter->dbf, scpnt, NULL); |
58 | (struct zfcp_adapter*) scpnt->device->host->hostdata[0], | ||
59 | scpnt, NULL); | ||
60 | /* return directly */ | 61 | /* return directly */ |
61 | scpnt->scsi_done(scpnt); | 62 | scpnt->scsi_done(scpnt); |
62 | } | 63 | } |
@@ -92,7 +93,7 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt, | |||
92 | scsi_result = fc_remote_port_chkready(rport); | 93 | scsi_result = fc_remote_port_chkready(rport); |
93 | if (unlikely(scsi_result)) { | 94 | if (unlikely(scsi_result)) { |
94 | scpnt->result = scsi_result; | 95 | scpnt->result = scsi_result; |
95 | zfcp_scsi_dbf_event_result("fail", 4, adapter, scpnt, NULL); | 96 | zfcp_dbf_scsi_result("fail", 4, adapter->dbf, scpnt, NULL); |
96 | scpnt->scsi_done(scpnt); | 97 | scpnt->scsi_done(scpnt); |
97 | return 0; | 98 | return 0; |
98 | } | 99 | } |
@@ -180,8 +181,8 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) | |||
180 | spin_unlock(&adapter->req_list_lock); | 181 | spin_unlock(&adapter->req_list_lock); |
181 | if (!old_req) { | 182 | if (!old_req) { |
182 | write_unlock_irqrestore(&adapter->abort_lock, flags); | 183 | write_unlock_irqrestore(&adapter->abort_lock, flags); |
183 | zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, NULL, | 184 | zfcp_dbf_scsi_abort("lte1", adapter->dbf, scpnt, NULL, |
184 | old_reqid); | 185 | old_reqid); |
185 | return FAILED; /* completion could be in progress */ | 186 | return FAILED; /* completion could be in progress */ |
186 | } | 187 | } |
187 | old_req->data = NULL; | 188 | old_req->data = NULL; |
@@ -197,16 +198,15 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) | |||
197 | zfcp_erp_wait(adapter); | 198 | zfcp_erp_wait(adapter); |
198 | if (!(atomic_read(&adapter->status) & | 199 | if (!(atomic_read(&adapter->status) & |
199 | ZFCP_STATUS_COMMON_RUNNING)) { | 200 | ZFCP_STATUS_COMMON_RUNNING)) { |
200 | zfcp_scsi_dbf_event_abort("nres", adapter, scpnt, NULL, | 201 | zfcp_dbf_scsi_abort("nres", adapter->dbf, scpnt, NULL, |
201 | old_reqid); | 202 | old_reqid); |
202 | return SUCCESS; | 203 | return SUCCESS; |
203 | } | 204 | } |
204 | } | 205 | } |
205 | if (!abrt_req) | 206 | if (!abrt_req) |
206 | return FAILED; | 207 | return FAILED; |
207 | 208 | ||
208 | wait_event(abrt_req->completion_wq, | 209 | wait_for_completion(&abrt_req->completion); |
209 | abrt_req->status & ZFCP_STATUS_FSFREQ_COMPLETED); | ||
210 | 210 | ||
211 | if (abrt_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) | 211 | if (abrt_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) |
212 | dbf_tag = "okay"; | 212 | dbf_tag = "okay"; |
@@ -216,7 +216,7 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) | |||
216 | dbf_tag = "fail"; | 216 | dbf_tag = "fail"; |
217 | retval = FAILED; | 217 | retval = FAILED; |
218 | } | 218 | } |
219 | zfcp_scsi_dbf_event_abort(dbf_tag, adapter, scpnt, abrt_req, old_reqid); | 219 | zfcp_dbf_scsi_abort(dbf_tag, adapter->dbf, scpnt, abrt_req, old_reqid); |
220 | zfcp_fsf_req_free(abrt_req); | 220 | zfcp_fsf_req_free(abrt_req); |
221 | return retval; | 221 | return retval; |
222 | } | 222 | } |
@@ -225,7 +225,7 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags) | |||
225 | { | 225 | { |
226 | struct zfcp_unit *unit = scpnt->device->hostdata; | 226 | struct zfcp_unit *unit = scpnt->device->hostdata; |
227 | struct zfcp_adapter *adapter = unit->port->adapter; | 227 | struct zfcp_adapter *adapter = unit->port->adapter; |
228 | struct zfcp_fsf_req *fsf_req; | 228 | struct zfcp_fsf_req *fsf_req = NULL; |
229 | int retval = SUCCESS; | 229 | int retval = SUCCESS; |
230 | int retry = 3; | 230 | int retry = 3; |
231 | 231 | ||
@@ -237,25 +237,23 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags) | |||
237 | zfcp_erp_wait(adapter); | 237 | zfcp_erp_wait(adapter); |
238 | if (!(atomic_read(&adapter->status) & | 238 | if (!(atomic_read(&adapter->status) & |
239 | ZFCP_STATUS_COMMON_RUNNING)) { | 239 | ZFCP_STATUS_COMMON_RUNNING)) { |
240 | zfcp_scsi_dbf_event_devreset("nres", tm_flags, unit, | 240 | zfcp_dbf_scsi_devreset("nres", tm_flags, unit, scpnt); |
241 | scpnt); | ||
242 | return SUCCESS; | 241 | return SUCCESS; |
243 | } | 242 | } |
244 | } | 243 | } |
245 | if (!fsf_req) | 244 | if (!fsf_req) |
246 | return FAILED; | 245 | return FAILED; |
247 | 246 | ||
248 | wait_event(fsf_req->completion_wq, | 247 | wait_for_completion(&fsf_req->completion); |
249 | fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED); | ||
250 | 248 | ||
251 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) { | 249 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) { |
252 | zfcp_scsi_dbf_event_devreset("fail", tm_flags, unit, scpnt); | 250 | zfcp_dbf_scsi_devreset("fail", tm_flags, unit, scpnt); |
253 | retval = FAILED; | 251 | retval = FAILED; |
254 | } else if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP) { | 252 | } else if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP) { |
255 | zfcp_scsi_dbf_event_devreset("nsup", tm_flags, unit, scpnt); | 253 | zfcp_dbf_scsi_devreset("nsup", tm_flags, unit, scpnt); |
256 | retval = FAILED; | 254 | retval = FAILED; |
257 | } else | 255 | } else |
258 | zfcp_scsi_dbf_event_devreset("okay", tm_flags, unit, scpnt); | 256 | zfcp_dbf_scsi_devreset("okay", tm_flags, unit, scpnt); |
259 | 257 | ||
260 | zfcp_fsf_req_free(fsf_req); | 258 | zfcp_fsf_req_free(fsf_req); |
261 | return retval; | 259 | return retval; |
@@ -430,7 +428,7 @@ static struct fc_host_statistics *zfcp_get_fc_host_stats(struct Scsi_Host *host) | |||
430 | if (!data) | 428 | if (!data) |
431 | return NULL; | 429 | return NULL; |
432 | 430 | ||
433 | ret = zfcp_fsf_exchange_port_data_sync(adapter, data); | 431 | ret = zfcp_fsf_exchange_port_data_sync(adapter->qdio, data); |
434 | if (ret) { | 432 | if (ret) { |
435 | kfree(data); | 433 | kfree(data); |
436 | return NULL; | 434 | return NULL; |
@@ -459,7 +457,7 @@ static void zfcp_reset_fc_host_stats(struct Scsi_Host *shost) | |||
459 | if (!data) | 457 | if (!data) |
460 | return; | 458 | return; |
461 | 459 | ||
462 | ret = zfcp_fsf_exchange_port_data_sync(adapter, data); | 460 | ret = zfcp_fsf_exchange_port_data_sync(adapter->qdio, data); |
463 | if (ret) | 461 | if (ret) |
464 | kfree(data); | 462 | kfree(data); |
465 | else { | 463 | else { |
@@ -493,21 +491,6 @@ static void zfcp_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout) | |||
493 | } | 491 | } |
494 | 492 | ||
495 | /** | 493 | /** |
496 | * zfcp_scsi_dev_loss_tmo_callbk - Free any reference to rport | ||
497 | * @rport: The rport that is about to be deleted. | ||
498 | */ | ||
499 | static void zfcp_scsi_dev_loss_tmo_callbk(struct fc_rport *rport) | ||
500 | { | ||
501 | struct zfcp_port *port; | ||
502 | |||
503 | write_lock_irq(&zfcp_data.config_lock); | ||
504 | port = rport->dd_data; | ||
505 | if (port) | ||
506 | port->rport = NULL; | ||
507 | write_unlock_irq(&zfcp_data.config_lock); | ||
508 | } | ||
509 | |||
510 | /** | ||
511 | * zfcp_scsi_terminate_rport_io - Terminate all I/O on a rport | 494 | * zfcp_scsi_terminate_rport_io - Terminate all I/O on a rport |
512 | * @rport: The FC rport where to teminate I/O | 495 | * @rport: The FC rport where to teminate I/O |
513 | * | 496 | * |
@@ -518,9 +501,12 @@ static void zfcp_scsi_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
518 | static void zfcp_scsi_terminate_rport_io(struct fc_rport *rport) | 501 | static void zfcp_scsi_terminate_rport_io(struct fc_rport *rport) |
519 | { | 502 | { |
520 | struct zfcp_port *port; | 503 | struct zfcp_port *port; |
504 | struct Scsi_Host *shost = rport_to_shost(rport); | ||
505 | struct zfcp_adapter *adapter = | ||
506 | (struct zfcp_adapter *)shost->hostdata[0]; | ||
521 | 507 | ||
522 | write_lock_irq(&zfcp_data.config_lock); | 508 | write_lock_irq(&zfcp_data.config_lock); |
523 | port = rport->dd_data; | 509 | port = zfcp_get_port_by_wwpn(adapter, rport->port_name); |
524 | if (port) | 510 | if (port) |
525 | zfcp_port_get(port); | 511 | zfcp_port_get(port); |
526 | write_unlock_irq(&zfcp_data.config_lock); | 512 | write_unlock_irq(&zfcp_data.config_lock); |
@@ -552,7 +538,6 @@ static void zfcp_scsi_rport_register(struct zfcp_port *port) | |||
552 | return; | 538 | return; |
553 | } | 539 | } |
554 | 540 | ||
555 | rport->dd_data = port; | ||
556 | rport->maxframe_size = port->maxframe_size; | 541 | rport->maxframe_size = port->maxframe_size; |
557 | rport->supported_classes = port->supported_classes; | 542 | rport->supported_classes = port->supported_classes; |
558 | port->rport = rport; | 543 | port->rport = rport; |
@@ -573,7 +558,7 @@ void zfcp_scsi_schedule_rport_register(struct zfcp_port *port) | |||
573 | zfcp_port_get(port); | 558 | zfcp_port_get(port); |
574 | port->rport_task = RPORT_ADD; | 559 | port->rport_task = RPORT_ADD; |
575 | 560 | ||
576 | if (!queue_work(zfcp_data.work_queue, &port->rport_work)) | 561 | if (!queue_work(port->adapter->work_queue, &port->rport_work)) |
577 | zfcp_port_put(port); | 562 | zfcp_port_put(port); |
578 | } | 563 | } |
579 | 564 | ||
@@ -582,8 +567,11 @@ void zfcp_scsi_schedule_rport_block(struct zfcp_port *port) | |||
582 | zfcp_port_get(port); | 567 | zfcp_port_get(port); |
583 | port->rport_task = RPORT_DEL; | 568 | port->rport_task = RPORT_DEL; |
584 | 569 | ||
585 | if (!queue_work(zfcp_data.work_queue, &port->rport_work)) | 570 | if (port->rport && queue_work(port->adapter->work_queue, |
586 | zfcp_port_put(port); | 571 | &port->rport_work)) |
572 | return; | ||
573 | |||
574 | zfcp_port_put(port); | ||
587 | } | 575 | } |
588 | 576 | ||
589 | void zfcp_scsi_schedule_rports_block(struct zfcp_adapter *adapter) | 577 | void zfcp_scsi_schedule_rports_block(struct zfcp_adapter *adapter) |
@@ -662,7 +650,6 @@ struct fc_function_template zfcp_transport_functions = { | |||
662 | .reset_fc_host_stats = zfcp_reset_fc_host_stats, | 650 | .reset_fc_host_stats = zfcp_reset_fc_host_stats, |
663 | .set_rport_dev_loss_tmo = zfcp_set_rport_dev_loss_tmo, | 651 | .set_rport_dev_loss_tmo = zfcp_set_rport_dev_loss_tmo, |
664 | .get_host_port_state = zfcp_get_host_port_state, | 652 | .get_host_port_state = zfcp_get_host_port_state, |
665 | .dev_loss_tmo_callbk = zfcp_scsi_dev_loss_tmo_callbk, | ||
666 | .terminate_rport_io = zfcp_scsi_terminate_rport_io, | 653 | .terminate_rport_io = zfcp_scsi_terminate_rport_io, |
667 | .show_host_port_state = 1, | 654 | .show_host_port_state = 1, |
668 | .bsg_request = zfcp_execute_fc_job, | 655 | .bsg_request = zfcp_execute_fc_job, |