Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
[safe/jmp/linux-2.6] / drivers / s390 / scsi / zfcp_erp.c
index 464f047..e3dbeda 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Error Recovery Procedures (ERP).
  *
- * Copyright IBM Corporation 2002, 2009
+ * Copyright IBM Corporation 2002, 2010
  */
 
 #define KMSG_COMPONENT "zfcp"
@@ -11,6 +11,7 @@
 
 #include <linux/kthread.h>
 #include "zfcp_ext.h"
+#include "zfcp_reqlist.h"
 
 #define ZFCP_MAX_ERPS                   3
 
@@ -174,7 +175,8 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need,
 
        switch (need) {
        case ZFCP_ERP_ACTION_REOPEN_UNIT:
-               zfcp_unit_get(unit);
+               if (!get_device(&unit->dev))
+                       return NULL;
                atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status);
                erp_action = &unit->erp_action;
                if (!(atomic_read(&unit->status) & ZFCP_STATUS_COMMON_RUNNING))
@@ -183,7 +185,8 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need,
 
        case ZFCP_ERP_ACTION_REOPEN_PORT:
        case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
-               zfcp_port_get(port);
+               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;
@@ -192,7 +195,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need,
                break;
 
        case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
-               zfcp_adapter_get(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;
@@ -476,26 +479,27 @@ static void zfcp_erp_action_to_running(struct zfcp_erp_action *erp_action)
 static void zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *act)
 {
        struct zfcp_adapter *adapter = act->adapter;
+       struct zfcp_fsf_req *req;
 
-       if (!act->fsf_req)
+       if (!act->fsf_req_id)
                return;
 
-       spin_lock(&adapter->req_list_lock);
-       if (zfcp_reqlist_find_safe(adapter, act->fsf_req) &&
-           act->fsf_req->erp_action == act) {
+       spin_lock(&adapter->req_list->lock);
+       req = _zfcp_reqlist_find(adapter->req_list, act->fsf_req_id);
+       if (req && req->erp_action == act) {
                if (act->status & (ZFCP_STATUS_ERP_DISMISSED |
                                   ZFCP_STATUS_ERP_TIMEDOUT)) {
-                       act->fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
+                       req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
                        zfcp_dbf_rec_action("erscf_1", act);
-                       act->fsf_req->erp_action = NULL;
+                       req->erp_action = NULL;
                }
                if (act->status & ZFCP_STATUS_ERP_TIMEDOUT)
                        zfcp_dbf_rec_action("erscf_2", act);
-               if (act->fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED)
-                       act->fsf_req = NULL;
+               if (req->status & ZFCP_STATUS_FSFREQ_DISMISSED)
+                       act->fsf_req_id = 0;
        } else
-               act->fsf_req = NULL;
-       spin_unlock(&adapter->req_list_lock);
+               act->fsf_req_id = 0;
+       spin_unlock(&adapter->req_list->lock);
 }
 
 /**
@@ -710,7 +714,7 @@ static int zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *act)
        if (zfcp_erp_adapter_strategy_open_fsf_xport(act) == ZFCP_ERP_FAILED)
                return ZFCP_ERP_FAILED;
 
-       atomic_set(&act->adapter->stat_miss, 16);
+       atomic_set(&act->adapter->stat_miss, act->adapter->stat_read_buf_num);
        if (zfcp_status_read_refill(act->adapter))
                return ZFCP_ERP_FAILED;
 
@@ -1177,28 +1181,28 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
        switch (act->action) {
        case ZFCP_ERP_ACTION_REOPEN_UNIT:
                if ((result == ZFCP_ERP_SUCCEEDED) && !unit->device) {
-                       zfcp_unit_get(unit);
+                       get_device(&unit->dev);
                        if (scsi_queue_work(unit->port->adapter->scsi_host,
                                            &unit->scsi_work) <= 0)
-                               zfcp_unit_put(unit);
+                               put_device(&unit->dev);
                }
-               zfcp_unit_put(unit);
+               put_device(&unit->dev);
                break;
 
        case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
        case ZFCP_ERP_ACTION_REOPEN_PORT:
                if (result == ZFCP_ERP_SUCCEEDED)
                        zfcp_scsi_schedule_rport_register(port);
-               zfcp_port_put(port);
+               put_device(&port->dev);
                break;
 
        case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
                if (result == ZFCP_ERP_SUCCEEDED) {
                        register_service_level(&adapter->service_level);
-                       schedule_work(&adapter->scan_work);
+                       queue_work(adapter->work_queue, &adapter->scan_work);
                } else
                        unregister_service_level(&adapter->service_level);
-               zfcp_adapter_put(adapter);
+               kref_put(&adapter->ref, zfcp_adapter_release);
                break;
        }
 }
@@ -1224,8 +1228,9 @@ static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
        unsigned long flags;
        struct zfcp_adapter *adapter = erp_action->adapter;
 
-       write_lock_irqsave(&adapter->erp_lock, flags);
+       kref_get(&adapter->ref);
 
+       write_lock_irqsave(&adapter->erp_lock, flags);
        zfcp_erp_strategy_check_fsfreq(erp_action);
 
        if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) {
@@ -1282,6 +1287,7 @@ static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
        if (retval != ZFCP_ERP_CONTINUES)
                zfcp_erp_action_cleanup(erp_action, retval);
 
+       kref_put(&adapter->ref, zfcp_adapter_release);
        return retval;
 }