aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_erp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/scsi/zfcp_erp.c')
-rw-r--r--drivers/s390/scsi/zfcp_erp.c60
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)
719 zfcp_qdio_close(adapter); 719 zfcp_qdio_close(adapter);
720 zfcp_fsf_req_dismiss_all(adapter); 720 zfcp_fsf_req_dismiss_all(adapter);
721 adapter->fsf_req_seq_no = 0; 721 adapter->fsf_req_seq_no = 0;
722 zfcp_fc_wka_port_force_offline(&adapter->nsp);
722 /* all ports and units are closed */ 723 /* all ports and units are closed */
723 zfcp_erp_modify_adapter_status(adapter, "erascl1", NULL, 724 zfcp_erp_modify_adapter_status(adapter, "erascl1", NULL,
724 ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR); 725 ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR);
@@ -1176,48 +1177,6 @@ static void zfcp_erp_action_dequeue(struct zfcp_erp_action *erp_action)
1176 } 1177 }
1177} 1178}
1178 1179
1179struct zfcp_erp_add_work {
1180 struct zfcp_unit *unit;
1181 struct work_struct work;
1182};
1183
1184static void zfcp_erp_scsi_scan(struct work_struct *work)
1185{
1186 struct zfcp_erp_add_work *p =
1187 container_of(work, struct zfcp_erp_add_work, work);
1188 struct zfcp_unit *unit = p->unit;
1189 struct fc_rport *rport = unit->port->rport;
1190
1191 if (rport && rport->port_state == FC_PORTSTATE_ONLINE)
1192 scsi_scan_target(&rport->dev, 0, rport->scsi_target_id,
1193 scsilun_to_int((struct scsi_lun *)&unit->fcp_lun), 0);
1194 atomic_clear_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status);
1195 zfcp_unit_put(unit);
1196 wake_up(&unit->port->adapter->erp_done_wqh);
1197 kfree(p);
1198}
1199
1200static void zfcp_erp_schedule_work(struct zfcp_unit *unit)
1201{
1202 struct zfcp_erp_add_work *p;
1203
1204 p = kzalloc(sizeof(*p), GFP_KERNEL);
1205 if (!p) {
1206 dev_err(&unit->port->adapter->ccw_device->dev,
1207 "Registering unit 0x%016Lx on port 0x%016Lx failed\n",
1208 (unsigned long long)unit->fcp_lun,
1209 (unsigned long long)unit->port->wwpn);
1210 return;
1211 }
1212
1213 zfcp_unit_get(unit);
1214 atomic_set_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status);
1215 INIT_WORK(&p->work, zfcp_erp_scsi_scan);
1216 p->unit = unit;
1217 if (!queue_work(zfcp_data.work_queue, &p->work))
1218 zfcp_unit_put(unit);
1219}
1220
1221static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result) 1180static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
1222{ 1181{
1223 struct zfcp_adapter *adapter = act->adapter; 1182 struct zfcp_adapter *adapter = act->adapter;
@@ -1226,11 +1185,11 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
1226 1185
1227 switch (act->action) { 1186 switch (act->action) {
1228 case ZFCP_ERP_ACTION_REOPEN_UNIT: 1187 case ZFCP_ERP_ACTION_REOPEN_UNIT:
1229 flush_work(&port->rport_work);
1230 if ((result == ZFCP_ERP_SUCCEEDED) && !unit->device) { 1188 if ((result == ZFCP_ERP_SUCCEEDED) && !unit->device) {
1231 if (!(atomic_read(&unit->status) & 1189 zfcp_unit_get(unit);
1232 ZFCP_STATUS_UNIT_SCSI_WORK_PENDING)) 1190 if (scsi_queue_work(unit->port->adapter->scsi_host,
1233 zfcp_erp_schedule_work(unit); 1191 &unit->scsi_work) <= 0)
1192 zfcp_unit_put(unit);
1234 } 1193 }
1235 zfcp_unit_put(unit); 1194 zfcp_unit_put(unit);
1236 break; 1195 break;
@@ -1352,6 +1311,11 @@ static int zfcp_erp_thread(void *data)
1352 1311
1353 while (!(atomic_read(&adapter->status) & 1312 while (!(atomic_read(&adapter->status) &
1354 ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL)) { 1313 ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL)) {
1314
1315 zfcp_rec_dbf_event_thread_lock("erthrd1", adapter);
1316 ignore = down_interruptible(&adapter->erp_ready_sem);
1317 zfcp_rec_dbf_event_thread_lock("erthrd2", adapter);
1318
1355 write_lock_irqsave(&adapter->erp_lock, flags); 1319 write_lock_irqsave(&adapter->erp_lock, flags);
1356 next = adapter->erp_ready_head.next; 1320 next = adapter->erp_ready_head.next;
1357 write_unlock_irqrestore(&adapter->erp_lock, flags); 1321 write_unlock_irqrestore(&adapter->erp_lock, flags);
@@ -1363,10 +1327,6 @@ static int zfcp_erp_thread(void *data)
1363 if (zfcp_erp_strategy(act) != ZFCP_ERP_DISMISSED) 1327 if (zfcp_erp_strategy(act) != ZFCP_ERP_DISMISSED)
1364 zfcp_erp_wakeup(adapter); 1328 zfcp_erp_wakeup(adapter);
1365 } 1329 }
1366
1367 zfcp_rec_dbf_event_thread_lock("erthrd1", adapter);
1368 ignore = down_interruptible(&adapter->erp_ready_sem);
1369 zfcp_rec_dbf_event_thread_lock("erthrd2", adapter);
1370 } 1330 }
1371 1331
1372 atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status); 1332 atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);