diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_erp.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_erp.c | 56 |
1 files changed, 11 insertions, 45 deletions
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 65addf6a91ec..dee1cc3ce21b 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Error Recovery Procedures (ERP). | 4 | * Error Recovery Procedures (ERP). |
5 | * | 5 | * |
6 | * Copyright IBM Corporation 2002, 2008 | 6 | * Copyright IBM Corporation 2002, 2009 |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #define KMSG_COMPONENT "zfcp" | 9 | #define KMSG_COMPONENT "zfcp" |
@@ -240,6 +240,7 @@ static int _zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, | |||
240 | int clear_mask, char *id, void *ref) | 240 | int clear_mask, char *id, void *ref) |
241 | { | 241 | { |
242 | zfcp_erp_adapter_block(adapter, clear_mask); | 242 | zfcp_erp_adapter_block(adapter, clear_mask); |
243 | zfcp_scsi_schedule_rports_block(adapter); | ||
243 | 244 | ||
244 | /* ensure propagation of failed status to new devices */ | 245 | /* ensure propagation of failed status to new devices */ |
245 | if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_FAILED) { | 246 | if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_FAILED) { |
@@ -322,6 +323,7 @@ static void _zfcp_erp_port_forced_reopen(struct zfcp_port *port, | |||
322 | int clear, char *id, void *ref) | 323 | int clear, char *id, void *ref) |
323 | { | 324 | { |
324 | zfcp_erp_port_block(port, clear); | 325 | zfcp_erp_port_block(port, clear); |
326 | zfcp_scsi_schedule_rport_block(port); | ||
325 | 327 | ||
326 | if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED) | 328 | if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED) |
327 | return; | 329 | return; |
@@ -353,6 +355,7 @@ static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id, | |||
353 | void *ref) | 355 | void *ref) |
354 | { | 356 | { |
355 | zfcp_erp_port_block(port, clear); | 357 | zfcp_erp_port_block(port, clear); |
358 | zfcp_scsi_schedule_rport_block(port); | ||
356 | 359 | ||
357 | if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED) { | 360 | if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED) { |
358 | /* ensure propagation of failed status to new devices */ | 361 | /* ensure propagation of failed status to new devices */ |
@@ -1211,37 +1214,6 @@ static void zfcp_erp_schedule_work(struct zfcp_unit *unit) | |||
1211 | queue_work(zfcp_data.work_queue, &p->work); | 1214 | queue_work(zfcp_data.work_queue, &p->work); |
1212 | } | 1215 | } |
1213 | 1216 | ||
1214 | static void zfcp_erp_rport_register(struct zfcp_port *port) | ||
1215 | { | ||
1216 | struct fc_rport_identifiers ids; | ||
1217 | ids.node_name = port->wwnn; | ||
1218 | ids.port_name = port->wwpn; | ||
1219 | ids.port_id = port->d_id; | ||
1220 | ids.roles = FC_RPORT_ROLE_FCP_TARGET; | ||
1221 | port->rport = fc_remote_port_add(port->adapter->scsi_host, 0, &ids); | ||
1222 | if (!port->rport) { | ||
1223 | dev_err(&port->adapter->ccw_device->dev, | ||
1224 | "Registering port 0x%016Lx failed\n", | ||
1225 | (unsigned long long)port->wwpn); | ||
1226 | return; | ||
1227 | } | ||
1228 | |||
1229 | scsi_target_unblock(&port->rport->dev); | ||
1230 | port->rport->maxframe_size = port->maxframe_size; | ||
1231 | port->rport->supported_classes = port->supported_classes; | ||
1232 | } | ||
1233 | |||
1234 | static void zfcp_erp_rports_del(struct zfcp_adapter *adapter) | ||
1235 | { | ||
1236 | struct zfcp_port *port; | ||
1237 | list_for_each_entry(port, &adapter->port_list_head, list) { | ||
1238 | if (!port->rport) | ||
1239 | continue; | ||
1240 | fc_remote_port_delete(port->rport); | ||
1241 | port->rport = NULL; | ||
1242 | } | ||
1243 | } | ||
1244 | |||
1245 | static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result) | 1217 | static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result) |
1246 | { | 1218 | { |
1247 | struct zfcp_adapter *adapter = act->adapter; | 1219 | struct zfcp_adapter *adapter = act->adapter; |
@@ -1250,8 +1222,8 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result) | |||
1250 | 1222 | ||
1251 | switch (act->action) { | 1223 | switch (act->action) { |
1252 | case ZFCP_ERP_ACTION_REOPEN_UNIT: | 1224 | case ZFCP_ERP_ACTION_REOPEN_UNIT: |
1253 | if ((result == ZFCP_ERP_SUCCEEDED) && | 1225 | flush_work(&port->rport_work); |
1254 | !unit->device && port->rport) { | 1226 | if ((result == ZFCP_ERP_SUCCEEDED) && !unit->device) { |
1255 | if (!(atomic_read(&unit->status) & | 1227 | if (!(atomic_read(&unit->status) & |
1256 | ZFCP_STATUS_UNIT_SCSI_WORK_PENDING)) | 1228 | ZFCP_STATUS_UNIT_SCSI_WORK_PENDING)) |
1257 | zfcp_erp_schedule_work(unit); | 1229 | zfcp_erp_schedule_work(unit); |
@@ -1261,23 +1233,17 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result) | |||
1261 | 1233 | ||
1262 | case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: | 1234 | case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: |
1263 | case ZFCP_ERP_ACTION_REOPEN_PORT: | 1235 | case ZFCP_ERP_ACTION_REOPEN_PORT: |
1264 | if ((result == ZFCP_ERP_SUCCEEDED) && !port->rport) | 1236 | if (result == ZFCP_ERP_SUCCEEDED) |
1265 | zfcp_erp_rport_register(port); | 1237 | zfcp_scsi_schedule_rport_register(port); |
1266 | if ((result != ZFCP_ERP_SUCCEEDED) && port->rport) { | ||
1267 | fc_remote_port_delete(port->rport); | ||
1268 | port->rport = NULL; | ||
1269 | } | ||
1270 | zfcp_port_put(port); | 1238 | zfcp_port_put(port); |
1271 | break; | 1239 | break; |
1272 | 1240 | ||
1273 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: | 1241 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: |
1274 | if (result != ZFCP_ERP_SUCCEEDED) { | 1242 | if (result == ZFCP_ERP_SUCCEEDED) { |
1275 | unregister_service_level(&adapter->service_level); | ||
1276 | zfcp_erp_rports_del(adapter); | ||
1277 | } else { | ||
1278 | register_service_level(&adapter->service_level); | 1243 | register_service_level(&adapter->service_level); |
1279 | schedule_work(&adapter->scan_work); | 1244 | schedule_work(&adapter->scan_work); |
1280 | } | 1245 | } else |
1246 | unregister_service_level(&adapter->service_level); | ||
1281 | zfcp_adapter_put(adapter); | 1247 | zfcp_adapter_put(adapter); |
1282 | break; | 1248 | break; |
1283 | } | 1249 | } |