diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_erp.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_erp.c | 138 |
1 files changed, 74 insertions, 64 deletions
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index f73e2180f333..b51a11a82e63 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c | |||
@@ -99,9 +99,12 @@ static void zfcp_erp_action_dismiss_port(struct zfcp_port *port) | |||
99 | 99 | ||
100 | if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_INUSE) | 100 | if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_INUSE) |
101 | zfcp_erp_action_dismiss(&port->erp_action); | 101 | zfcp_erp_action_dismiss(&port->erp_action); |
102 | else | 102 | else { |
103 | list_for_each_entry(unit, &port->unit_list_head, list) | 103 | read_lock(&port->unit_list_lock); |
104 | zfcp_erp_action_dismiss_unit(unit); | 104 | list_for_each_entry(unit, &port->unit_list, list) |
105 | zfcp_erp_action_dismiss_unit(unit); | ||
106 | read_unlock(&port->unit_list_lock); | ||
107 | } | ||
105 | } | 108 | } |
106 | 109 | ||
107 | static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter) | 110 | static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter) |
@@ -110,9 +113,12 @@ static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter) | |||
110 | 113 | ||
111 | if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_INUSE) | 114 | if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_INUSE) |
112 | zfcp_erp_action_dismiss(&adapter->erp_action); | 115 | zfcp_erp_action_dismiss(&adapter->erp_action); |
113 | else | 116 | else { |
114 | list_for_each_entry(port, &adapter->port_list_head, list) | 117 | read_lock(&adapter->port_list_lock); |
118 | list_for_each_entry(port, &adapter->port_list, list) | ||
115 | zfcp_erp_action_dismiss_port(port); | 119 | zfcp_erp_action_dismiss_port(port); |
120 | read_unlock(&adapter->port_list_lock); | ||
121 | } | ||
116 | } | 122 | } |
117 | 123 | ||
118 | static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter, | 124 | static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter, |
@@ -168,7 +174,8 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, | |||
168 | 174 | ||
169 | switch (need) { | 175 | switch (need) { |
170 | case ZFCP_ERP_ACTION_REOPEN_UNIT: | 176 | case ZFCP_ERP_ACTION_REOPEN_UNIT: |
171 | zfcp_unit_get(unit); | 177 | if (!get_device(&unit->sysfs_device)) |
178 | return NULL; | ||
172 | atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status); | 179 | atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status); |
173 | erp_action = &unit->erp_action; | 180 | erp_action = &unit->erp_action; |
174 | if (!(atomic_read(&unit->status) & ZFCP_STATUS_COMMON_RUNNING)) | 181 | if (!(atomic_read(&unit->status) & ZFCP_STATUS_COMMON_RUNNING)) |
@@ -177,7 +184,8 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, | |||
177 | 184 | ||
178 | case ZFCP_ERP_ACTION_REOPEN_PORT: | 185 | case ZFCP_ERP_ACTION_REOPEN_PORT: |
179 | case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: | 186 | case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: |
180 | zfcp_port_get(port); | 187 | if (!get_device(&port->sysfs_device)) |
188 | return NULL; | ||
181 | zfcp_erp_action_dismiss_port(port); | 189 | zfcp_erp_action_dismiss_port(port); |
182 | atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status); | 190 | atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status); |
183 | erp_action = &port->erp_action; | 191 | erp_action = &port->erp_action; |
@@ -186,7 +194,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, | |||
186 | break; | 194 | break; |
187 | 195 | ||
188 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: | 196 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: |
189 | zfcp_adapter_get(adapter); | 197 | kref_get(&adapter->ref); |
190 | zfcp_erp_action_dismiss_adapter(adapter); | 198 | zfcp_erp_action_dismiss_adapter(adapter); |
191 | atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status); | 199 | atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status); |
192 | erp_action = &adapter->erp_action; | 200 | erp_action = &adapter->erp_action; |
@@ -264,11 +272,16 @@ void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear, | |||
264 | { | 272 | { |
265 | unsigned long flags; | 273 | unsigned long flags; |
266 | 274 | ||
267 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 275 | zfcp_erp_adapter_block(adapter, clear); |
268 | write_lock(&adapter->erp_lock); | 276 | zfcp_scsi_schedule_rports_block(adapter); |
269 | _zfcp_erp_adapter_reopen(adapter, clear, id, ref); | 277 | |
270 | write_unlock(&adapter->erp_lock); | 278 | write_lock_irqsave(&adapter->erp_lock, flags); |
271 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | 279 | if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_FAILED) |
280 | zfcp_erp_adapter_failed(adapter, "erareo1", NULL); | ||
281 | else | ||
282 | zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER, adapter, | ||
283 | NULL, NULL, id, ref); | ||
284 | write_unlock_irqrestore(&adapter->erp_lock, flags); | ||
272 | } | 285 | } |
273 | 286 | ||
274 | /** | 287 | /** |
@@ -345,11 +358,9 @@ void zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear, char *id, | |||
345 | unsigned long flags; | 358 | unsigned long flags; |
346 | struct zfcp_adapter *adapter = port->adapter; | 359 | struct zfcp_adapter *adapter = port->adapter; |
347 | 360 | ||
348 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 361 | write_lock_irqsave(&adapter->erp_lock, flags); |
349 | write_lock(&adapter->erp_lock); | ||
350 | _zfcp_erp_port_forced_reopen(port, clear, id, ref); | 362 | _zfcp_erp_port_forced_reopen(port, clear, id, ref); |
351 | write_unlock(&adapter->erp_lock); | 363 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
352 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | ||
353 | } | 364 | } |
354 | 365 | ||
355 | static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id, | 366 | static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id, |
@@ -377,15 +388,13 @@ static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id, | |||
377 | */ | 388 | */ |
378 | int zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id, void *ref) | 389 | int zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id, void *ref) |
379 | { | 390 | { |
380 | unsigned long flags; | ||
381 | int retval; | 391 | int retval; |
392 | unsigned long flags; | ||
382 | struct zfcp_adapter *adapter = port->adapter; | 393 | struct zfcp_adapter *adapter = port->adapter; |
383 | 394 | ||
384 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 395 | write_lock_irqsave(&adapter->erp_lock, flags); |
385 | write_lock(&adapter->erp_lock); | ||
386 | retval = _zfcp_erp_port_reopen(port, clear, id, ref); | 396 | retval = _zfcp_erp_port_reopen(port, clear, id, ref); |
387 | write_unlock(&adapter->erp_lock); | 397 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
388 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | ||
389 | 398 | ||
390 | return retval; | 399 | return retval; |
391 | } | 400 | } |
@@ -424,11 +433,9 @@ void zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear, char *id, | |||
424 | struct zfcp_port *port = unit->port; | 433 | struct zfcp_port *port = unit->port; |
425 | struct zfcp_adapter *adapter = port->adapter; | 434 | struct zfcp_adapter *adapter = port->adapter; |
426 | 435 | ||
427 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 436 | write_lock_irqsave(&adapter->erp_lock, flags); |
428 | write_lock(&adapter->erp_lock); | ||
429 | _zfcp_erp_unit_reopen(unit, clear, id, ref); | 437 | _zfcp_erp_unit_reopen(unit, clear, id, ref); |
430 | write_unlock(&adapter->erp_lock); | 438 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
431 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | ||
432 | } | 439 | } |
433 | 440 | ||
434 | static int status_change_set(unsigned long mask, atomic_t *status) | 441 | static int status_change_set(unsigned long mask, atomic_t *status) |
@@ -540,8 +547,10 @@ static void _zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter, | |||
540 | { | 547 | { |
541 | struct zfcp_port *port; | 548 | struct zfcp_port *port; |
542 | 549 | ||
543 | list_for_each_entry(port, &adapter->port_list_head, list) | 550 | read_lock(&adapter->port_list_lock); |
551 | list_for_each_entry(port, &adapter->port_list, list) | ||
544 | _zfcp_erp_port_reopen(port, clear, id, ref); | 552 | _zfcp_erp_port_reopen(port, clear, id, ref); |
553 | read_unlock(&adapter->port_list_lock); | ||
545 | } | 554 | } |
546 | 555 | ||
547 | static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear, | 556 | static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear, |
@@ -549,8 +558,10 @@ static void _zfcp_erp_unit_reopen_all(struct zfcp_port *port, int clear, | |||
549 | { | 558 | { |
550 | struct zfcp_unit *unit; | 559 | struct zfcp_unit *unit; |
551 | 560 | ||
552 | list_for_each_entry(unit, &port->unit_list_head, list) | 561 | read_lock(&port->unit_list_lock); |
562 | list_for_each_entry(unit, &port->unit_list, list) | ||
553 | _zfcp_erp_unit_reopen(unit, clear, id, ref); | 563 | _zfcp_erp_unit_reopen(unit, clear, id, ref); |
564 | read_unlock(&port->unit_list_lock); | ||
554 | } | 565 | } |
555 | 566 | ||
556 | static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act) | 567 | static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act) |
@@ -590,16 +601,14 @@ static void zfcp_erp_wakeup(struct zfcp_adapter *adapter) | |||
590 | { | 601 | { |
591 | unsigned long flags; | 602 | unsigned long flags; |
592 | 603 | ||
593 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 604 | read_lock_irqsave(&adapter->erp_lock, flags); |
594 | read_lock(&adapter->erp_lock); | ||
595 | if (list_empty(&adapter->erp_ready_head) && | 605 | if (list_empty(&adapter->erp_ready_head) && |
596 | list_empty(&adapter->erp_running_head)) { | 606 | list_empty(&adapter->erp_running_head)) { |
597 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, | 607 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, |
598 | &adapter->status); | 608 | &adapter->status); |
599 | wake_up(&adapter->erp_done_wqh); | 609 | wake_up(&adapter->erp_done_wqh); |
600 | } | 610 | } |
601 | read_unlock(&adapter->erp_lock); | 611 | read_unlock_irqrestore(&adapter->erp_lock, flags); |
602 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | ||
603 | } | 612 | } |
604 | 613 | ||
605 | static int zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *act) | 614 | static int zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *act) |
@@ -1170,28 +1179,28 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result) | |||
1170 | switch (act->action) { | 1179 | switch (act->action) { |
1171 | case ZFCP_ERP_ACTION_REOPEN_UNIT: | 1180 | case ZFCP_ERP_ACTION_REOPEN_UNIT: |
1172 | if ((result == ZFCP_ERP_SUCCEEDED) && !unit->device) { | 1181 | if ((result == ZFCP_ERP_SUCCEEDED) && !unit->device) { |
1173 | zfcp_unit_get(unit); | 1182 | get_device(&unit->sysfs_device); |
1174 | if (scsi_queue_work(unit->port->adapter->scsi_host, | 1183 | if (scsi_queue_work(unit->port->adapter->scsi_host, |
1175 | &unit->scsi_work) <= 0) | 1184 | &unit->scsi_work) <= 0) |
1176 | zfcp_unit_put(unit); | 1185 | put_device(&unit->sysfs_device); |
1177 | } | 1186 | } |
1178 | zfcp_unit_put(unit); | 1187 | put_device(&unit->sysfs_device); |
1179 | break; | 1188 | break; |
1180 | 1189 | ||
1181 | case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: | 1190 | case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: |
1182 | case ZFCP_ERP_ACTION_REOPEN_PORT: | 1191 | case ZFCP_ERP_ACTION_REOPEN_PORT: |
1183 | if (result == ZFCP_ERP_SUCCEEDED) | 1192 | if (result == ZFCP_ERP_SUCCEEDED) |
1184 | zfcp_scsi_schedule_rport_register(port); | 1193 | zfcp_scsi_schedule_rport_register(port); |
1185 | zfcp_port_put(port); | 1194 | put_device(&port->sysfs_device); |
1186 | break; | 1195 | break; |
1187 | 1196 | ||
1188 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: | 1197 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: |
1189 | if (result == ZFCP_ERP_SUCCEEDED) { | 1198 | if (result == ZFCP_ERP_SUCCEEDED) { |
1190 | register_service_level(&adapter->service_level); | 1199 | register_service_level(&adapter->service_level); |
1191 | schedule_work(&adapter->scan_work); | 1200 | queue_work(adapter->work_queue, &adapter->scan_work); |
1192 | } else | 1201 | } else |
1193 | unregister_service_level(&adapter->service_level); | 1202 | unregister_service_level(&adapter->service_level); |
1194 | zfcp_adapter_put(adapter); | 1203 | kref_put(&adapter->ref, zfcp_adapter_release); |
1195 | break; | 1204 | break; |
1196 | } | 1205 | } |
1197 | } | 1206 | } |
@@ -1214,12 +1223,12 @@ static int zfcp_erp_strategy_do_action(struct zfcp_erp_action *erp_action) | |||
1214 | static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action) | 1223 | static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action) |
1215 | { | 1224 | { |
1216 | int retval; | 1225 | int retval; |
1217 | struct zfcp_adapter *adapter = erp_action->adapter; | ||
1218 | unsigned long flags; | 1226 | unsigned long flags; |
1227 | struct zfcp_adapter *adapter = erp_action->adapter; | ||
1219 | 1228 | ||
1220 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 1229 | kref_get(&adapter->ref); |
1221 | write_lock(&adapter->erp_lock); | ||
1222 | 1230 | ||
1231 | write_lock_irqsave(&adapter->erp_lock, flags); | ||
1223 | zfcp_erp_strategy_check_fsfreq(erp_action); | 1232 | zfcp_erp_strategy_check_fsfreq(erp_action); |
1224 | 1233 | ||
1225 | if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) { | 1234 | if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) { |
@@ -1231,11 +1240,9 @@ static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action) | |||
1231 | zfcp_erp_action_to_running(erp_action); | 1240 | zfcp_erp_action_to_running(erp_action); |
1232 | 1241 | ||
1233 | /* no lock to allow for blocking operations */ | 1242 | /* no lock to allow for blocking operations */ |
1234 | write_unlock(&adapter->erp_lock); | 1243 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
1235 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | ||
1236 | retval = zfcp_erp_strategy_do_action(erp_action); | 1244 | retval = zfcp_erp_strategy_do_action(erp_action); |
1237 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 1245 | write_lock_irqsave(&adapter->erp_lock, flags); |
1238 | write_lock(&adapter->erp_lock); | ||
1239 | 1246 | ||
1240 | if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) | 1247 | if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) |
1241 | retval = ZFCP_ERP_CONTINUES; | 1248 | retval = ZFCP_ERP_CONTINUES; |
@@ -1273,12 +1280,12 @@ static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action) | |||
1273 | zfcp_erp_strategy_followup_failed(erp_action); | 1280 | zfcp_erp_strategy_followup_failed(erp_action); |
1274 | 1281 | ||
1275 | unlock: | 1282 | unlock: |
1276 | write_unlock(&adapter->erp_lock); | 1283 | write_unlock_irqrestore(&adapter->erp_lock, flags); |
1277 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | ||
1278 | 1284 | ||
1279 | if (retval != ZFCP_ERP_CONTINUES) | 1285 | if (retval != ZFCP_ERP_CONTINUES) |
1280 | zfcp_erp_action_cleanup(erp_action, retval); | 1286 | zfcp_erp_action_cleanup(erp_action, retval); |
1281 | 1287 | ||
1288 | kref_put(&adapter->ref, zfcp_adapter_release); | ||
1282 | return retval; | 1289 | return retval; |
1283 | } | 1290 | } |
1284 | 1291 | ||
@@ -1415,6 +1422,7 @@ void zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter, char *id, | |||
1415 | void *ref, u32 mask, int set_or_clear) | 1422 | void *ref, u32 mask, int set_or_clear) |
1416 | { | 1423 | { |
1417 | struct zfcp_port *port; | 1424 | struct zfcp_port *port; |
1425 | unsigned long flags; | ||
1418 | u32 common_mask = mask & ZFCP_COMMON_FLAGS; | 1426 | u32 common_mask = mask & ZFCP_COMMON_FLAGS; |
1419 | 1427 | ||
1420 | if (set_or_clear == ZFCP_SET) { | 1428 | if (set_or_clear == ZFCP_SET) { |
@@ -1429,10 +1437,13 @@ void zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter, char *id, | |||
1429 | atomic_set(&adapter->erp_counter, 0); | 1437 | atomic_set(&adapter->erp_counter, 0); |
1430 | } | 1438 | } |
1431 | 1439 | ||
1432 | if (common_mask) | 1440 | if (common_mask) { |
1433 | list_for_each_entry(port, &adapter->port_list_head, list) | 1441 | read_lock_irqsave(&adapter->port_list_lock, flags); |
1442 | list_for_each_entry(port, &adapter->port_list, list) | ||
1434 | zfcp_erp_modify_port_status(port, id, ref, common_mask, | 1443 | zfcp_erp_modify_port_status(port, id, ref, common_mask, |
1435 | set_or_clear); | 1444 | set_or_clear); |
1445 | read_unlock_irqrestore(&adapter->port_list_lock, flags); | ||
1446 | } | ||
1436 | } | 1447 | } |
1437 | 1448 | ||
1438 | /** | 1449 | /** |
@@ -1449,6 +1460,7 @@ void zfcp_erp_modify_port_status(struct zfcp_port *port, char *id, void *ref, | |||
1449 | u32 mask, int set_or_clear) | 1460 | u32 mask, int set_or_clear) |
1450 | { | 1461 | { |
1451 | struct zfcp_unit *unit; | 1462 | struct zfcp_unit *unit; |
1463 | unsigned long flags; | ||
1452 | u32 common_mask = mask & ZFCP_COMMON_FLAGS; | 1464 | u32 common_mask = mask & ZFCP_COMMON_FLAGS; |
1453 | 1465 | ||
1454 | if (set_or_clear == ZFCP_SET) { | 1466 | if (set_or_clear == ZFCP_SET) { |
@@ -1463,10 +1475,13 @@ void zfcp_erp_modify_port_status(struct zfcp_port *port, char *id, void *ref, | |||
1463 | atomic_set(&port->erp_counter, 0); | 1475 | atomic_set(&port->erp_counter, 0); |
1464 | } | 1476 | } |
1465 | 1477 | ||
1466 | if (common_mask) | 1478 | if (common_mask) { |
1467 | list_for_each_entry(unit, &port->unit_list_head, list) | 1479 | read_lock_irqsave(&port->unit_list_lock, flags); |
1480 | list_for_each_entry(unit, &port->unit_list, list) | ||
1468 | zfcp_erp_modify_unit_status(unit, id, ref, common_mask, | 1481 | zfcp_erp_modify_unit_status(unit, id, ref, common_mask, |
1469 | set_or_clear); | 1482 | set_or_clear); |
1483 | read_unlock_irqrestore(&port->unit_list_lock, flags); | ||
1484 | } | ||
1470 | } | 1485 | } |
1471 | 1486 | ||
1472 | /** | 1487 | /** |
@@ -1502,12 +1517,8 @@ void zfcp_erp_modify_unit_status(struct zfcp_unit *unit, char *id, void *ref, | |||
1502 | */ | 1517 | */ |
1503 | void zfcp_erp_port_boxed(struct zfcp_port *port, char *id, void *ref) | 1518 | void zfcp_erp_port_boxed(struct zfcp_port *port, char *id, void *ref) |
1504 | { | 1519 | { |
1505 | unsigned long flags; | ||
1506 | |||
1507 | read_lock_irqsave(&zfcp_data.config_lock, flags); | ||
1508 | zfcp_erp_modify_port_status(port, id, ref, | 1520 | zfcp_erp_modify_port_status(port, id, ref, |
1509 | ZFCP_STATUS_COMMON_ACCESS_BOXED, ZFCP_SET); | 1521 | ZFCP_STATUS_COMMON_ACCESS_BOXED, ZFCP_SET); |
1510 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | ||
1511 | zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref); | 1522 | zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref); |
1512 | } | 1523 | } |
1513 | 1524 | ||
@@ -1535,13 +1546,9 @@ void zfcp_erp_unit_boxed(struct zfcp_unit *unit, char *id, void *ref) | |||
1535 | */ | 1546 | */ |
1536 | void zfcp_erp_port_access_denied(struct zfcp_port *port, char *id, void *ref) | 1547 | void zfcp_erp_port_access_denied(struct zfcp_port *port, char *id, void *ref) |
1537 | { | 1548 | { |
1538 | unsigned long flags; | ||
1539 | |||
1540 | read_lock_irqsave(&zfcp_data.config_lock, flags); | ||
1541 | zfcp_erp_modify_port_status(port, id, ref, | 1549 | zfcp_erp_modify_port_status(port, id, ref, |
1542 | ZFCP_STATUS_COMMON_ERP_FAILED | | 1550 | ZFCP_STATUS_COMMON_ERP_FAILED | |
1543 | ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET); | 1551 | ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET); |
1544 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | ||
1545 | } | 1552 | } |
1546 | 1553 | ||
1547 | /** | 1554 | /** |
@@ -1574,12 +1581,15 @@ static void zfcp_erp_port_access_changed(struct zfcp_port *port, char *id, | |||
1574 | void *ref) | 1581 | void *ref) |
1575 | { | 1582 | { |
1576 | struct zfcp_unit *unit; | 1583 | struct zfcp_unit *unit; |
1584 | unsigned long flags; | ||
1577 | int status = atomic_read(&port->status); | 1585 | int status = atomic_read(&port->status); |
1578 | 1586 | ||
1579 | if (!(status & (ZFCP_STATUS_COMMON_ACCESS_DENIED | | 1587 | if (!(status & (ZFCP_STATUS_COMMON_ACCESS_DENIED | |
1580 | ZFCP_STATUS_COMMON_ACCESS_BOXED))) { | 1588 | ZFCP_STATUS_COMMON_ACCESS_BOXED))) { |
1581 | list_for_each_entry(unit, &port->unit_list_head, list) | 1589 | read_lock_irqsave(&port->unit_list_lock, flags); |
1590 | list_for_each_entry(unit, &port->unit_list, list) | ||
1582 | zfcp_erp_unit_access_changed(unit, id, ref); | 1591 | zfcp_erp_unit_access_changed(unit, id, ref); |
1592 | read_unlock_irqrestore(&port->unit_list_lock, flags); | ||
1583 | return; | 1593 | return; |
1584 | } | 1594 | } |
1585 | 1595 | ||
@@ -1595,14 +1605,14 @@ static void zfcp_erp_port_access_changed(struct zfcp_port *port, char *id, | |||
1595 | void zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter, char *id, | 1605 | void zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter, char *id, |
1596 | void *ref) | 1606 | void *ref) |
1597 | { | 1607 | { |
1598 | struct zfcp_port *port; | ||
1599 | unsigned long flags; | 1608 | unsigned long flags; |
1609 | struct zfcp_port *port; | ||
1600 | 1610 | ||
1601 | if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) | 1611 | if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) |
1602 | return; | 1612 | return; |
1603 | 1613 | ||
1604 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 1614 | read_lock_irqsave(&adapter->port_list_lock, flags); |
1605 | list_for_each_entry(port, &adapter->port_list_head, list) | 1615 | list_for_each_entry(port, &adapter->port_list, list) |
1606 | zfcp_erp_port_access_changed(port, id, ref); | 1616 | zfcp_erp_port_access_changed(port, id, ref); |
1607 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | 1617 | read_unlock_irqrestore(&adapter->port_list_lock, flags); |
1608 | } | 1618 | } |