|
@@ -143,6 +143,49 @@ static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int zfcp_erp_handle_failed(int want, struct zfcp_adapter *adapter,
|
|
|
|
+ struct zfcp_port *port,
|
|
|
|
+ struct scsi_device *sdev)
|
|
|
|
+{
|
|
|
|
+ int need = want;
|
|
|
|
+ struct zfcp_scsi_dev *zsdev;
|
|
|
|
+
|
|
|
|
+ switch (want) {
|
|
|
|
+ case ZFCP_ERP_ACTION_REOPEN_LUN:
|
|
|
|
+ zsdev = sdev_to_zfcp(sdev);
|
|
|
|
+ if (atomic_read(&zsdev->status) & ZFCP_STATUS_COMMON_ERP_FAILED)
|
|
|
|
+ need = 0;
|
|
|
|
+ break;
|
|
|
|
+ case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
|
|
|
|
+ if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED)
|
|
|
|
+ need = 0;
|
|
|
|
+ break;
|
|
|
|
+ case ZFCP_ERP_ACTION_REOPEN_PORT:
|
|
|
|
+ if (atomic_read(&port->status) &
|
|
|
|
+ ZFCP_STATUS_COMMON_ERP_FAILED) {
|
|
|
|
+ need = 0;
|
|
|
|
+ /* ensure propagation of failed status to new devices */
|
|
|
|
+ zfcp_erp_set_port_status(
|
|
|
|
+ port, ZFCP_STATUS_COMMON_ERP_FAILED);
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
|
|
|
|
+ if (atomic_read(&adapter->status) &
|
|
|
|
+ ZFCP_STATUS_COMMON_ERP_FAILED) {
|
|
|
|
+ need = 0;
|
|
|
|
+ /* ensure propagation of failed status to new devices */
|
|
|
|
+ zfcp_erp_set_adapter_status(
|
|
|
|
+ adapter, ZFCP_STATUS_COMMON_ERP_FAILED);
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ need = 0;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return need;
|
|
|
|
+}
|
|
|
|
+
|
|
static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter,
|
|
static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter,
|
|
struct zfcp_port *port,
|
|
struct zfcp_port *port,
|
|
struct scsi_device *sdev)
|
|
struct scsi_device *sdev)
|
|
@@ -266,6 +309,12 @@ static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter,
|
|
int retval = 1, need;
|
|
int retval = 1, need;
|
|
struct zfcp_erp_action *act;
|
|
struct zfcp_erp_action *act;
|
|
|
|
|
|
|
|
+ need = zfcp_erp_handle_failed(want, adapter, port, sdev);
|
|
|
|
+ if (!need) {
|
|
|
|
+ need = ZFCP_ERP_ACTION_FAILED; /* marker for trace */
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
+
|
|
if (!adapter->erp_thread)
|
|
if (!adapter->erp_thread)
|
|
return -EIO;
|
|
return -EIO;
|
|
|
|
|
|
@@ -314,12 +363,6 @@ static int _zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter,
|
|
zfcp_erp_adapter_block(adapter, clear_mask);
|
|
zfcp_erp_adapter_block(adapter, clear_mask);
|
|
zfcp_scsi_schedule_rports_block(adapter);
|
|
zfcp_scsi_schedule_rports_block(adapter);
|
|
|
|
|
|
- /* ensure propagation of failed status to new devices */
|
|
|
|
- if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_FAILED) {
|
|
|
|
- zfcp_erp_set_adapter_status(adapter,
|
|
|
|
- ZFCP_STATUS_COMMON_ERP_FAILED);
|
|
|
|
- return -EIO;
|
|
|
|
- }
|
|
|
|
return zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER,
|
|
return zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER,
|
|
adapter, NULL, NULL, id, 0);
|
|
adapter, NULL, NULL, id, 0);
|
|
}
|
|
}
|
|
@@ -338,12 +381,8 @@ void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear, char *id)
|
|
zfcp_scsi_schedule_rports_block(adapter);
|
|
zfcp_scsi_schedule_rports_block(adapter);
|
|
|
|
|
|
write_lock_irqsave(&adapter->erp_lock, flags);
|
|
write_lock_irqsave(&adapter->erp_lock, flags);
|
|
- if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_FAILED)
|
|
|
|
- zfcp_erp_set_adapter_status(adapter,
|
|
|
|
- ZFCP_STATUS_COMMON_ERP_FAILED);
|
|
|
|
- else
|
|
|
|
- zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER, adapter,
|
|
|
|
- NULL, NULL, id, 0);
|
|
|
|
|
|
+ zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER, adapter,
|
|
|
|
+ NULL, NULL, id, 0);
|
|
write_unlock_irqrestore(&adapter->erp_lock, flags);
|
|
write_unlock_irqrestore(&adapter->erp_lock, flags);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -384,13 +423,6 @@ static void _zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear,
|
|
zfcp_erp_port_block(port, clear);
|
|
zfcp_erp_port_block(port, clear);
|
|
zfcp_scsi_schedule_rport_block(port);
|
|
zfcp_scsi_schedule_rport_block(port);
|
|
|
|
|
|
- if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED) {
|
|
|
|
- zfcp_dbf_rec_trig(id, port->adapter, port, NULL,
|
|
|
|
- ZFCP_ERP_ACTION_REOPEN_PORT_FORCED,
|
|
|
|
- ZFCP_ERP_ACTION_FAILED);
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT_FORCED,
|
|
zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT_FORCED,
|
|
port->adapter, port, NULL, id, 0);
|
|
port->adapter, port, NULL, id, 0);
|
|
}
|
|
}
|
|
@@ -416,12 +448,6 @@ static int _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id)
|
|
zfcp_erp_port_block(port, clear);
|
|
zfcp_erp_port_block(port, clear);
|
|
zfcp_scsi_schedule_rport_block(port);
|
|
zfcp_scsi_schedule_rport_block(port);
|
|
|
|
|
|
- if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED) {
|
|
|
|
- /* ensure propagation of failed status to new devices */
|
|
|
|
- zfcp_erp_set_port_status(port, ZFCP_STATUS_COMMON_ERP_FAILED);
|
|
|
|
- return -EIO;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
return zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT,
|
|
return zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT,
|
|
port->adapter, port, NULL, id, 0);
|
|
port->adapter, port, NULL, id, 0);
|
|
}
|
|
}
|
|
@@ -461,9 +487,6 @@ static void _zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, char *id,
|
|
|
|
|
|
zfcp_erp_lun_block(sdev, clear);
|
|
zfcp_erp_lun_block(sdev, clear);
|
|
|
|
|
|
- if (atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_ERP_FAILED)
|
|
|
|
- return;
|
|
|
|
-
|
|
|
|
zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_LUN, adapter,
|
|
zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_LUN, adapter,
|
|
zfcp_sdev->port, sdev, id, act_status);
|
|
zfcp_sdev->port, sdev, id, act_status);
|
|
}
|
|
}
|