static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status, struct zfcp_adapter *adapter, struct zfcp_port *port, struct scsi_device *sdev) { struct zfcp_erp_action *erp_action; struct zfcp_scsi_dev *zfcp_sdev; switch (need) { case ZFCP_ERP_ACTION_REOPEN_LUN: zfcp_sdev = sdev_to_zfcp(sdev); if (!(act_status & ZFCP_STATUS_ERP_NO_REF)) if (scsi_device_get(sdev)) return NULL; atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &zfcp_sdev->status); erp_action = &zfcp_sdev->erp_action; memset(erp_action, 0, sizeof(struct zfcp_erp_action)); erp_action->port = port; erp_action->sdev = sdev; if (!(atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_RUNNING)) act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; break; case ZFCP_ERP_ACTION_REOPEN_PORT: case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: if (!get_device(&port->dev)) return NULL; zfcp_erp_action_dismiss_port(port); atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status); erp_action = &port->erp_action; memset(erp_action, 0, sizeof(struct zfcp_erp_action)); erp_action->port = port; if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_RUNNING)) act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; break; case ZFCP_ERP_ACTION_REOPEN_ADAPTER: kref_get(&adapter->ref); zfcp_erp_action_dismiss_adapter(adapter); atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status); erp_action = &adapter->erp_action; memset(erp_action, 0, sizeof(struct zfcp_erp_action)); if (!(atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_RUNNING)) act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; break; default: return NULL; } erp_action->adapter = adapter; erp_action->action = need; erp_action->status = act_status; return erp_action; }
static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter) { struct zfcp_port *port; if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_INUSE) zfcp_erp_action_dismiss(&adapter->erp_action); else list_for_each_entry(port, &adapter->port_list_head, list) zfcp_erp_action_dismiss_port(port); }
static struct zfcp_erp_action *zfcp_erp_setup_act(int need, struct zfcp_adapter *adapter, struct zfcp_port *port, struct zfcp_unit *unit) { struct zfcp_erp_action *erp_action; u32 status = 0; switch (need) { case ZFCP_ERP_ACTION_REOPEN_UNIT: zfcp_unit_get(unit); atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status); erp_action = &unit->erp_action; if (!(atomic_read(&unit->status) & ZFCP_STATUS_COMMON_RUNNING)) status = ZFCP_STATUS_ERP_CLOSE_ONLY; break; case ZFCP_ERP_ACTION_REOPEN_PORT: case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: zfcp_port_get(port); zfcp_erp_action_dismiss_port(port); atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status); erp_action = &port->erp_action; if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_RUNNING)) status = ZFCP_STATUS_ERP_CLOSE_ONLY; break; case ZFCP_ERP_ACTION_REOPEN_ADAPTER: zfcp_adapter_get(adapter); zfcp_erp_action_dismiss_adapter(adapter); atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status); erp_action = &adapter->erp_action; if (!(atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_RUNNING)) status = ZFCP_STATUS_ERP_CLOSE_ONLY; break; default: return NULL; } memset(erp_action, 0, sizeof(struct zfcp_erp_action)); erp_action->adapter = adapter; erp_action->port = port; erp_action->unit = unit; erp_action->action = need; erp_action->status = status; return erp_action; }