diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_erp.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_erp.c | 60 |
1 files changed, 10 insertions, 50 deletions
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 631bdb1dfd6c..fdc9b4352a64 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -719,6 +719,7 @@ static void zfcp_erp_adapter_strategy_close(struct zfcp_erp_action *act) zfcp_qdio_close(adapter); zfcp_fsf_req_dismiss_all(adapter); adapter->fsf_req_seq_no = 0; + zfcp_fc_wka_port_force_offline(&adapter->nsp); /* all ports and units are closed */ zfcp_erp_modify_adapter_status(adapter, "erascl1", NULL, ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR); @@ -1176,48 +1177,6 @@ static void zfcp_erp_action_dequeue(struct zfcp_erp_action *erp_action) } } -struct zfcp_erp_add_work { - struct zfcp_unit *unit; - struct work_struct work; -}; - -static void zfcp_erp_scsi_scan(struct work_struct *work) -{ - struct zfcp_erp_add_work *p = - container_of(work, struct zfcp_erp_add_work, work); - struct zfcp_unit *unit = p->unit; - struct fc_rport *rport = unit->port->rport; - - if (rport && rport->port_state == FC_PORTSTATE_ONLINE) - scsi_scan_target(&rport->dev, 0, rport->scsi_target_id, - scsilun_to_int((struct scsi_lun *)&unit->fcp_lun), 0); - atomic_clear_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status); - zfcp_unit_put(unit); - wake_up(&unit->port->adapter->erp_done_wqh); - kfree(p); -} - -static void zfcp_erp_schedule_work(struct zfcp_unit *unit) -{ - struct zfcp_erp_add_work *p; - - p = kzalloc(sizeof(*p), GFP_KERNEL); - if (!p) { - dev_err(&unit->port->adapter->ccw_device->dev, - "Registering unit 0x%016Lx on port 0x%016Lx failed\n", - (unsigned long long)unit->fcp_lun, - (unsigned long long)unit->port->wwpn); - return; - } - - zfcp_unit_get(unit); - atomic_set_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status); - INIT_WORK(&p->work, zfcp_erp_scsi_scan); - p->unit = unit; - if (!queue_work(zfcp_data.work_queue, &p->work)) - zfcp_unit_put(unit); -} - static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result) { struct zfcp_adapter *adapter = act->adapter; @@ -1226,11 +1185,11 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result) switch (act->action) { case ZFCP_ERP_ACTION_REOPEN_UNIT: - flush_work(&port->rport_work); if ((result == ZFCP_ERP_SUCCEEDED) && !unit->device) { - if (!(atomic_read(&unit->status) & - ZFCP_STATUS_UNIT_SCSI_WORK_PENDING)) - zfcp_erp_schedule_work(unit); + zfcp_unit_get(unit); + if (scsi_queue_work(unit->port->adapter->scsi_host, + &unit->scsi_work) <= 0) + zfcp_unit_put(unit); } zfcp_unit_put(unit); break; @@ -1352,6 +1311,11 @@ static int zfcp_erp_thread(void *data) while (!(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL)) { + + zfcp_rec_dbf_event_thread_lock("erthrd1", adapter); + ignore = down_interruptible(&adapter->erp_ready_sem); + zfcp_rec_dbf_event_thread_lock("erthrd2", adapter); + write_lock_irqsave(&adapter->erp_lock, flags); next = adapter->erp_ready_head.next; write_unlock_irqrestore(&adapter->erp_lock, flags); @@ -1363,10 +1327,6 @@ static int zfcp_erp_thread(void *data) if (zfcp_erp_strategy(act) != ZFCP_ERP_DISMISSED) zfcp_erp_wakeup(adapter); } - - zfcp_rec_dbf_event_thread_lock("erthrd1", adapter); - ignore = down_interruptible(&adapter->erp_ready_sem); - zfcp_rec_dbf_event_thread_lock("erthrd2", adapter); } atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status); |