SG: Change sg_set_page() to take length and offset argument
[linux-3.10.git] / drivers / s390 / scsi / zfcp_erp.c
index 862a411..5552b75 100644 (file)
@@ -1,22 +1,22 @@
-/* 
+/*
  * This file is part of the zfcp device driver for
  * FCP adapters for IBM System z9 and zSeries.
  *
  * (C) Copyright IBM Corp. 2002, 2006
- * 
- * This program is free software; you can redistribute it and/or modify 
- * it under the terms of the GNU General Public License as published by 
- * the Free Software Foundation; either version 2, or (at your option) 
- * any later version. 
- * 
- * This program is distributed in the hope that it will be useful, 
- * but WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
- * GNU General Public License for more details. 
- * 
- * You should have received a copy of the GNU General Public License 
- * along with this program; if not, write to the Free Software 
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #define ZFCP_LOG_AREA                  ZFCP_LOG_AREA_ERP
@@ -54,7 +54,7 @@ static int zfcp_erp_strategy_check_adapter(struct zfcp_adapter *, int);
 static int zfcp_erp_strategy_statechange(int, u32, struct zfcp_adapter *,
                                         struct zfcp_port *,
                                         struct zfcp_unit *, int);
-static inline int zfcp_erp_strategy_statechange_detected(atomic_t *, u32);
+static int zfcp_erp_strategy_statechange_detected(atomic_t *, u32);
 static int zfcp_erp_strategy_followup_actions(int, struct zfcp_adapter *,
                                              struct zfcp_port *,
                                              struct zfcp_unit *, int);
@@ -106,8 +106,8 @@ static void zfcp_erp_action_cleanup(int, struct zfcp_adapter *,
 static void zfcp_erp_action_ready(struct zfcp_erp_action *);
 static int  zfcp_erp_action_exists(struct zfcp_erp_action *);
 
-static inline void zfcp_erp_action_to_ready(struct zfcp_erp_action *);
-static inline void zfcp_erp_action_to_running(struct zfcp_erp_action *);
+static void zfcp_erp_action_to_ready(struct zfcp_erp_action *);
+static void zfcp_erp_action_to_running(struct zfcp_erp_action *);
 
 static void zfcp_erp_memwait_handler(unsigned long);
 
@@ -179,19 +179,19 @@ static void zfcp_close_fsf(struct zfcp_adapter *adapter)
 static void zfcp_fsf_request_timeout_handler(unsigned long data)
 {
        struct zfcp_adapter *adapter = (struct zfcp_adapter *) data;
-       zfcp_erp_adapter_reopen(adapter, 0);
+       zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED);
 }
 
 void zfcp_fsf_start_timer(struct zfcp_fsf_req *fsf_req, unsigned long timeout)
 {
        fsf_req->timer.function = zfcp_fsf_request_timeout_handler;
        fsf_req->timer.data = (unsigned long) fsf_req->adapter;
-       fsf_req->timer.expires = timeout;
+       fsf_req->timer.expires = jiffies + timeout;
        add_timer(&fsf_req->timer);
 }
 
 /*
- * function:   
+ * function:
  *
  * purpose:    called if an adapter failed,
  *             initiates adapter recovery which is done
@@ -200,7 +200,7 @@ void zfcp_fsf_start_timer(struct zfcp_fsf_req *fsf_req, unsigned long timeout)
  * returns:    0       - initiated action successfully
  *             <0      - failed to initiate action
  */
-int
+static int
 zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *adapter, int clear_mask)
 {
        int retval;
@@ -228,7 +228,7 @@ zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *adapter, int clear_mask)
 }
 
 /*
- * function:   
+ * function:
  *
  * purpose:    Wrappper for zfcp_erp_adapter_reopen_internal
  *              used to ensure the correct locking
@@ -295,7 +295,7 @@ zfcp_erp_unit_shutdown(struct zfcp_unit *unit, int clear_mask)
  * zfcp_erp_adisc - send ADISC ELS command
  * @port: port structure
  */
-int
+static int
 zfcp_erp_adisc(struct zfcp_port *port)
 {
        struct zfcp_adapter *adapter = port->adapter;
@@ -308,21 +308,23 @@ zfcp_erp_adisc(struct zfcp_port *port)
        if (send_els == NULL)
                goto nomem;
 
-       send_els->req = kzalloc(sizeof(struct scatterlist), GFP_ATOMIC);
+       send_els->req = kmalloc(sizeof(struct scatterlist), GFP_ATOMIC);
        if (send_els->req == NULL)
                goto nomem;
+       sg_init_table(send_els->req, 1);
 
-       send_els->resp = kzalloc(sizeof(struct scatterlist), GFP_ATOMIC);
+       send_els->resp = kmalloc(sizeof(struct scatterlist), GFP_ATOMIC);
        if (send_els->resp == NULL)
                goto nomem;
+       sg_init_table(send_els->resp, 1);
 
        address = (void *) get_zeroed_page(GFP_ATOMIC);
        if (address == NULL)
                goto nomem;
 
-       zfcp_address_to_sg(address, send_els->req);
+       zfcp_address_to_sg(address, send_els->req, sizeof(struct zfcp_ls_adisc));
        address += PAGE_SIZE >> 1;
-       zfcp_address_to_sg(address, send_els->resp);
+       zfcp_address_to_sg(address, send_els->resp, sizeof(struct zfcp_ls_adisc_acc));
        send_els->req_count = send_els->resp_count = 1;
 
        send_els->adapter = adapter;
@@ -334,17 +336,14 @@ zfcp_erp_adisc(struct zfcp_port *port)
        adisc = zfcp_sg_to_address(send_els->req);
        send_els->ls_code = adisc->code = ZFCP_LS_ADISC;
 
-       send_els->req->length = sizeof(struct zfcp_ls_adisc);
-       send_els->resp->length = sizeof(struct zfcp_ls_adisc_acc);
-
        /* acc. to FC-FS, hard_nport_id in ADISC should not be set for ports
           without FC-AL-2 capability, so we don't set it */
        adisc->wwpn = fc_host_port_name(adapter->scsi_host);
        adisc->wwnn = fc_host_node_name(adapter->scsi_host);
        adisc->nport_id = fc_host_port_id(adapter->scsi_host);
-       ZFCP_LOG_INFO("ADISC request from s_id 0x%08x to d_id 0x%08x "
+       ZFCP_LOG_INFO("ADISC request from s_id 0x%06x to d_id 0x%06x "
                      "(wwpn=0x%016Lx, wwnn=0x%016Lx, "
-                     "hard_nport_id=0x%08x, nport_id=0x%08x)\n",
+                     "hard_nport_id=0x%06x, nport_id=0x%06x)\n",
                      adisc->nport_id, send_els->d_id, (wwn_t) adisc->wwpn,
                      (wwn_t) adisc->wwnn, adisc->hard_nport_id,
                      adisc->nport_id);
@@ -352,7 +351,7 @@ zfcp_erp_adisc(struct zfcp_port *port)
        retval = zfcp_fsf_send_els(send_els);
        if (retval != 0) {
                ZFCP_LOG_NORMAL("error: initiation of Send ELS failed for port "
-                               "0x%08x on adapter %s\n", send_els->d_id,
+                               "0x%06x on adapter %s\n", send_els->d_id,
                                zfcp_get_busid_by_adapter(adapter));
                goto freemem;
        }
@@ -363,7 +362,7 @@ zfcp_erp_adisc(struct zfcp_port *port)
        retval = -ENOMEM;
  freemem:
        if (address != NULL)
-               __free_pages(send_els->req->page, 0);
+               __free_pages(sg_page(send_els->req), 0);
        if (send_els != NULL) {
                kfree(send_els->req);
                kfree(send_els->resp);
@@ -380,7 +379,7 @@ zfcp_erp_adisc(struct zfcp_port *port)
  *
  * If ADISC failed (LS_RJT or timed out) forced reopen of the port is triggered.
  */
-void
+static void
 zfcp_erp_adisc_handler(unsigned long data)
 {
        struct zfcp_send_els *send_els;
@@ -398,7 +397,7 @@ zfcp_erp_adisc_handler(unsigned long data)
        if (send_els->status != 0) {
                ZFCP_LOG_NORMAL("ELS request rejected/timed out, "
                                "force physical port reopen "
-                               "(adapter %s, port d_id=0x%08x)\n",
+                               "(adapter %s, port d_id=0x%06x)\n",
                                zfcp_get_busid_by_adapter(adapter), d_id);
                debug_text_event(adapter->erp_dbf, 3, "forcreop");
                if (zfcp_erp_port_forced_reopen(port, 0))
@@ -411,9 +410,9 @@ zfcp_erp_adisc_handler(unsigned long data)
 
        adisc = zfcp_sg_to_address(send_els->resp);
 
-       ZFCP_LOG_INFO("ADISC response from d_id 0x%08x to s_id "
-                     "0x%08x (wwpn=0x%016Lx, wwnn=0x%016Lx, "
-                     "hard_nport_id=0x%08x, nport_id=0x%08x)\n",
+       ZFCP_LOG_INFO("ADISC response from d_id 0x%06x to s_id "
+                     "0x%06x (wwpn=0x%016Lx, wwnn=0x%016Lx, "
+                     "hard_nport_id=0x%06x, nport_id=0x%06x)\n",
                      d_id, fc_host_port_id(adapter->scsi_host),
                      (wwn_t) adisc->wwpn, (wwn_t) adisc->wwnn,
                      adisc->hard_nport_id, adisc->nport_id);
@@ -437,7 +436,7 @@ zfcp_erp_adisc_handler(unsigned long data)
 
  out:
        zfcp_port_put(port);
-       __free_pages(send_els->req->page, 0);
+       __free_pages(sg_page(send_els->req), 0);
        kfree(send_els->req);
        kfree(send_els->resp);
        kfree(send_els);
@@ -476,7 +475,7 @@ zfcp_test_link(struct zfcp_port *port)
 
 
 /*
- * function:   
+ * function:
  *
  * purpose:    called if a port failed to be opened normally
  *             initiates Forced Reopen recovery which is done
@@ -517,7 +516,7 @@ zfcp_erp_port_forced_reopen_internal(struct zfcp_port *port, int clear_mask)
 }
 
 /*
- * function:   
+ * function:
  *
  * purpose:    Wrappper for zfcp_erp_port_forced_reopen_internal
  *              used to ensure the correct locking
@@ -543,7 +542,7 @@ zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear_mask)
 }
 
 /*
- * function:   
+ * function:
  *
  * purpose:    called if a port is to be opened
  *             initiates Reopen recovery which is done
@@ -612,7 +611,7 @@ zfcp_erp_port_reopen(struct zfcp_port *port, int clear_mask)
 }
 
 /*
- * function:   
+ * function:
  *
  * purpose:    called if a unit is to be opened
  *             initiates Reopen recovery which is done
@@ -704,7 +703,7 @@ static void zfcp_erp_adapter_unblock(struct zfcp_adapter *adapter)
 }
 
 /*
- * function:   
+ * function:
  *
  * purpose:    disable I/O,
  *             return any open requests and clean them up,
@@ -725,7 +724,7 @@ zfcp_erp_port_block(struct zfcp_port *port, int clear_mask)
 }
 
 /*
- * function:   
+ * function:
  *
  * purpose:    enable I/O
  *
@@ -742,7 +741,7 @@ zfcp_erp_port_unblock(struct zfcp_port *port)
 }
 
 /*
- * function:   
+ * function:
  *
  * purpose:    disable I/O,
  *             return any open requests and clean them up,
@@ -763,7 +762,7 @@ zfcp_erp_unit_block(struct zfcp_unit *unit, int clear_mask)
 }
 
 /*
- * function:   
+ * function:
  *
  * purpose:    enable I/O
  *
@@ -792,7 +791,7 @@ zfcp_erp_action_ready(struct zfcp_erp_action *erp_action)
 }
 
 /*
- * function:   
+ * function:
  *
  * purpose:
  *
@@ -838,32 +837,27 @@ zfcp_erp_action_exists(struct zfcp_erp_action *erp_action)
  *             and does appropriate preparations (dismiss fsf request, ...)
  *
  * locks:      called under erp_lock (disabled interrupts)
- *
- * returns:    0
  */
-static int
+static void
 zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action)
 {
-       int retval = 0;
-       struct zfcp_fsf_req *fsf_req = NULL;
        struct zfcp_adapter *adapter = erp_action->adapter;
 
        if (erp_action->fsf_req) {
                /* take lock to ensure that request is not deleted meanwhile */
                spin_lock(&adapter->req_list_lock);
-               if ((!zfcp_reqlist_ismember(adapter,
-                                           erp_action->fsf_req->req_id)) &&
-                   (fsf_req->erp_action == erp_action)) {
+               if (zfcp_reqlist_find(adapter, erp_action->fsf_req->req_id)) {
                        /* fsf_req still exists */
                        debug_text_event(adapter->erp_dbf, 3, "a_ca_req");
-                       debug_event(adapter->erp_dbf, 3, &fsf_req,
+                       debug_event(adapter->erp_dbf, 3, &erp_action->fsf_req,
                                    sizeof (unsigned long));
                        /* dismiss fsf_req of timed out/dismissed erp_action */
                        if (erp_action->status & (ZFCP_STATUS_ERP_DISMISSED |
                                                  ZFCP_STATUS_ERP_TIMEDOUT)) {
                                debug_text_event(adapter->erp_dbf, 3,
                                                 "a_ca_disreq");
-                               fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
+                               erp_action->fsf_req->status |=
+                                       ZFCP_STATUS_FSFREQ_DISMISSED;
                        }
                        if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) {
                                ZFCP_LOG_NORMAL("error: erp step timed out "
@@ -876,11 +870,11 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action)
                         * then keep it running asynchronously and don't mess
                         * with the association of erp_action and fsf_req.
                         */
-                       if (fsf_req->status & (ZFCP_STATUS_FSFREQ_COMPLETED |
+                       if (erp_action->fsf_req->status &
+                                       (ZFCP_STATUS_FSFREQ_COMPLETED |
                                               ZFCP_STATUS_FSFREQ_DISMISSED)) {
                                /* forget about association between fsf_req
                                   and erp_action */
-                               fsf_req->erp_action = NULL;
                                erp_action->fsf_req = NULL;
                        }
                } else {
@@ -894,8 +888,6 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action)
                spin_unlock(&adapter->req_list_lock);
        } else
                debug_text_event(adapter->erp_dbf, 3, "a_ca_noreq");
-
-       return retval;
 }
 
 /**
@@ -959,7 +951,7 @@ zfcp_erp_memwait_handler(unsigned long data)
  *             action gets an appropriate flag and will be processed
  *             accordingly
  */
-void zfcp_erp_timeout_handler(unsigned long data)
+static void zfcp_erp_timeout_handler(unsigned long data)
 {
        struct zfcp_erp_action *erp_action = (struct zfcp_erp_action *) data;
        struct zfcp_adapter *adapter = erp_action->adapter;
@@ -974,7 +966,7 @@ void zfcp_erp_timeout_handler(unsigned long data)
  * zfcp_erp_action_dismiss - dismiss an erp_action
  *
  * adapter->erp_lock must be held
- * 
+ *
  * Dismissal of an erp_action is usually required if an erp_action of
  * higher priority is generated.
  */
@@ -1012,9 +1004,9 @@ zfcp_erp_thread_setup(struct zfcp_adapter *adapter)
 }
 
 /*
- * function:   
+ * function:
  *
- * purpose:    
+ * purpose:
  *
  * returns:
  *
@@ -1101,7 +1093,7 @@ zfcp_erp_thread(void *data)
 }
 
 /*
- * function:   
+ * function:
  *
  * purpose:    drives single error recovery action and schedules higher and
  *             subordinate actions, if necessary
@@ -1213,7 +1205,7 @@ zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
 
        /*
         * put this target through the erp mill again if someone has
-        * requested to change the status of a target being online 
+        * requested to change the status of a target being online
         * to offline or the other way around
         * (old retval is preserved if nothing has to be done here)
         */
@@ -1235,7 +1227,7 @@ zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
  unlock:
        write_unlock(&adapter->erp_lock);
        read_unlock_irqrestore(&zfcp_data.config_lock, flags);
-       
+
        if (retval != ZFCP_ERP_CONTINUES)
                zfcp_erp_action_cleanup(action, adapter, port, unit, retval);
 
@@ -1257,9 +1249,9 @@ zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
 }
 
 /*
- * function:   
+ * function:
  *
- * purpose:    
+ * purpose:
  *
  * returns:    ZFCP_ERP_DISMISSED      - if action has been dismissed
  *             retval                  - otherwise
@@ -1329,7 +1321,7 @@ zfcp_erp_strategy_do_action(struct zfcp_erp_action *erp_action)
 }
 
 /*
- * function:   
+ * function:
  *
  * purpose:    triggers retry of this action after a certain amount of time
  *             by means of timer provided by erp_action
@@ -1353,7 +1345,7 @@ zfcp_erp_strategy_memwait(struct zfcp_erp_action *erp_action)
        return retval;
 }
 
-/* 
+/*
  * function:    zfcp_erp_adapter_failed
  *
  * purpose:     sets the adapter and all underlying devices to ERP_FAILED
@@ -1369,7 +1361,7 @@ zfcp_erp_adapter_failed(struct zfcp_adapter *adapter)
        debug_text_event(adapter->erp_dbf, 2, "a_afail");
 }
 
-/* 
+/*
  * function:    zfcp_erp_port_failed
  *
  * purpose:     sets the port and all underlying devices to ERP_FAILED
@@ -1383,7 +1375,7 @@ zfcp_erp_port_failed(struct zfcp_port *port)
 
        if (atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status))
                ZFCP_LOG_NORMAL("port erp failed (adapter %s, "
-                               "port d_id=0x%08x)\n",
+                               "port d_id=0x%06x)\n",
                                zfcp_get_busid_by_port(port), port->d_id);
        else
                ZFCP_LOG_NORMAL("port erp failed (adapter %s, wwpn=0x%016Lx)\n",
@@ -1393,7 +1385,7 @@ zfcp_erp_port_failed(struct zfcp_port *port)
        debug_event(port->adapter->erp_dbf, 2, &port->wwpn, sizeof (wwn_t));
 }
 
-/* 
+/*
  * function:    zfcp_erp_unit_failed
  *
  * purpose:     sets the unit to ERP_FAILED
@@ -1424,7 +1416,7 @@ zfcp_erp_unit_failed(struct zfcp_unit *unit)
  *              successfully is reset.
  *
  * returns:    ZFCP_ERP_CONTINUES      - action continues (not considered)
- *             ZFCP_ERP_SUCCEEDED      - action finished successfully 
+ *             ZFCP_ERP_SUCCEEDED      - action finished successfully
  *             ZFCP_ERP_EXIT           - action failed and will not continue
  */
 static int
@@ -1498,7 +1490,7 @@ zfcp_erp_strategy_statechange(int action,
        return retval;
 }
 
-static inline int
+static int
 zfcp_erp_strategy_statechange_detected(atomic_t * target_status, u32 erp_status)
 {
        return
@@ -1597,8 +1589,63 @@ zfcp_erp_strategy_check_adapter(struct zfcp_adapter *adapter, int result)
        return result;
 }
 
+struct zfcp_erp_add_work {
+       struct zfcp_unit  *unit;
+       struct work_struct work;
+};
+
+/**
+ * zfcp_erp_scsi_scan
+ * @data: pointer to a struct zfcp_erp_add_work
+ *
+ * Registers a logical unit with the SCSI stack.
+ */
+static void zfcp_erp_scsi_scan(struct work_struct *work)
+{
+       struct zfcp_erp_add_work *p =
+               container_of(work, struct zfcp_erp_add_work, work);
+       struct zfcp_unit *unit = p->unit;
+       struct fc_rport *rport = unit->port->rport;
+       scsi_scan_target(&rport->dev, 0, rport->scsi_target_id,
+                        unit->scsi_lun, 0);
+       atomic_clear_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status);
+       wake_up(&unit->scsi_scan_wq);
+       zfcp_unit_put(unit);
+       kfree(p);
+}
+
+/**
+ * zfcp_erp_schedule_work
+ * @unit: pointer to unit which should be registered with SCSI stack
+ *
+ * Schedules work which registers a unit with the SCSI stack
+ */
+static void
+zfcp_erp_schedule_work(struct zfcp_unit *unit)
+{
+       struct zfcp_erp_add_work *p;
+
+       p = kzalloc(sizeof(*p), GFP_KERNEL);
+       if (!p) {
+               ZFCP_LOG_NORMAL("error: Out of resources. Could not register "
+                               "the FCP-LUN 0x%Lx connected to "
+                               "the port with WWPN 0x%Lx connected to "
+                               "the adapter %s with the SCSI stack.\n",
+                               unit->fcp_lun,
+                               unit->port->wwpn,
+                               zfcp_get_busid_by_unit(unit));
+               return;
+       }
+
+       zfcp_unit_get(unit);
+       atomic_set_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status);
+       INIT_WORK(&p->work, zfcp_erp_scsi_scan);
+       p->unit = unit;
+       schedule_work(&p->work);
+}
+
 /*
- * function:   
+ * function:
  *
  * purpose:    remaining things in good cases,
  *             escalation in bad cases
@@ -1639,8 +1686,8 @@ zfcp_erp_strategy_followup_actions(int action,
                break;
 
        case ZFCP_ERP_ACTION_REOPEN_UNIT:
-               if (status == ZFCP_ERP_SUCCEEDED) ;     /* no further action */
-               else
+               /* Nothing to do if status == ZFCP_ERP_SUCCEEDED */
+               if (status != ZFCP_ERP_SUCCEEDED)
                        zfcp_erp_port_reopen_internal(unit->port, 0);
                break;
        }
@@ -1767,7 +1814,7 @@ zfcp_erp_modify_unit_status(struct zfcp_unit *unit, u32 mask, int set_or_clear)
 }
 
 /*
- * function:   
+ * function:
  *
  * purpose:    Wrappper for zfcp_erp_port_reopen_all_internal
  *              used to ensure the correct locking
@@ -1804,9 +1851,9 @@ zfcp_erp_port_reopen_all_internal(struct zfcp_adapter *adapter, int clear_mask)
 }
 
 /*
- * function:   
+ * function:
  *
- * purpose:    
+ * purpose:
  *
  * returns:    FIXME
  */
@@ -1823,7 +1870,7 @@ zfcp_erp_unit_reopen_all_internal(struct zfcp_port *port, int clear_mask)
 }
 
 /*
- * function:   
+ * function:
  *
  * purpose:    this routine executes the 'Reopen Adapter' action
  *             (the entire action is processed synchronously, since
@@ -1860,9 +1907,9 @@ zfcp_erp_adapter_strategy(struct zfcp_erp_action *erp_action)
 }
 
 /*
- * function:   
+ * function:
  *
- * purpose:    
+ * purpose:
  *
  * returns:    ZFCP_ERP_SUCCEEDED      - action finished successfully
  *              ZFCP_ERP_FAILED         - action finished unsuccessfully
@@ -1882,9 +1929,9 @@ zfcp_erp_adapter_strategy_close(struct zfcp_erp_action *erp_action)
 }
 
 /*
- * function:   
+ * function:
  *
- * purpose:    
+ * purpose:
  *
  * returns:    ZFCP_ERP_SUCCEEDED      - action finished successfully
  *              ZFCP_ERP_FAILED         - action finished unsuccessfully
@@ -1909,7 +1956,7 @@ zfcp_erp_adapter_strategy_open(struct zfcp_erp_action *erp_action)
  * purpose:    allocate the irq associated with this devno and register
  *             the FSF adapter with the SCSI stack
  *
- * returns:    
+ * returns:
  */
 static int
 zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *erp_action, int close)
@@ -1937,6 +1984,10 @@ zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *erp_action, int close)
  failed_openfcp:
        zfcp_close_fsf(erp_action->adapter);
  failed_qdio:
+       atomic_clear_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK |
+                         ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
+                         ZFCP_STATUS_ADAPTER_XPORT_OK,
+                         &erp_action->adapter->status);
  out:
        return retval;
 }
@@ -1949,7 +2000,7 @@ zfcp_erp_adapter_strategy_generic(struct zfcp_erp_action *erp_action, int close)
  * returns:    0 - successful setup
  *             !0 - failed setup
  */
-int
+static int
 zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action)
 {
        int retval;
@@ -1987,7 +2038,7 @@ zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action)
                sbale = &(adapter->response_queue.buffer[i]->element[0]);
                sbale->length = 0;
                sbale->flags = SBAL_FLAGS_LAST_ENTRY;
-               sbale->addr = 0;
+               sbale->addr = NULL;
        }
 
        ZFCP_LOG_TRACE("calling do_QDIO on adapter %s (flags=0x%x, "
@@ -2118,6 +2169,9 @@ zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action)
                sleep *= 2;
        }
 
+       atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,
+                         &adapter->status);
+
        if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK,
                              &adapter->status)) {
                ZFCP_LOG_INFO("error: exchange of configuration data for "
@@ -2142,7 +2196,7 @@ zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action)
        zfcp_erp_action_to_running(erp_action);
        write_unlock_irq(&adapter->erp_lock);
 
-       ret = zfcp_fsf_exchange_port_data(erp_action, adapter, NULL);
+       ret = zfcp_fsf_exchange_port_data(erp_action);
        if (ret == -EOPNOTSUPP) {
                debug_text_event(adapter->erp_dbf, 3, "a_xport_notsupp");
                return ZFCP_ERP_SUCCEEDED;
@@ -2194,7 +2248,7 @@ zfcp_erp_adapter_strategy_open_fsf_statusread(struct zfcp_erp_action
 }
 
 /*
- * function:   
+ * function:
  *
  * purpose:    this routine executes the 'Reopen Physical Port' action
  *
@@ -2253,7 +2307,7 @@ zfcp_erp_port_forced_strategy(struct zfcp_erp_action *erp_action)
 }
 
 /*
- * function:   
+ * function:
  *
  * purpose:    this routine executes the 'Reopen Port' action
  *
@@ -2407,7 +2461,7 @@ zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *erp_action)
                                retval = ZFCP_ERP_FAILED;
                        }
                } else {
-                       ZFCP_LOG_DEBUG("port 0x%016Lx has d_id=0x%08x -> "
+                       ZFCP_LOG_DEBUG("port 0x%016Lx has d_id=0x%06x -> "
                                       "trying open\n", port->wwpn, port->d_id);
                        retval = zfcp_erp_port_strategy_open_port(erp_action);
                }
@@ -2447,7 +2501,7 @@ zfcp_erp_port_strategy_open_nameserver(struct zfcp_erp_action *erp_action)
        case ZFCP_ERP_STEP_UNINITIALIZED:
        case ZFCP_ERP_STEP_PHYS_PORT_CLOSING:
        case ZFCP_ERP_STEP_PORT_CLOSING:
-               ZFCP_LOG_DEBUG("port 0x%016Lx has d_id=0x%08x -> trying open\n",
+               ZFCP_LOG_DEBUG("port 0x%016Lx has d_id=0x%06x -> trying open\n",
                               port->wwpn, port->d_id);
                retval = zfcp_erp_port_strategy_open_port(erp_action);
                break;
@@ -2475,7 +2529,7 @@ zfcp_erp_port_strategy_open_nameserver(struct zfcp_erp_action *erp_action)
 }
 
 /*
- * function:   
+ * function:
  *
  * purpose:    makes the erp thread continue with reopen (physical) port
  *             actions which have been paused until the name server port
@@ -2515,9 +2569,9 @@ zfcp_erp_port_strategy_open_nameserver_wakeup(struct zfcp_erp_action
 }
 
 /*
- * function:   
+ * function:
  *
- * purpose:    
+ * purpose:
  *
  * returns:    ZFCP_ERP_CONTINUES      - action continues (asynchronously)
  *             ZFCP_ERP_FAILED         - action finished unsuccessfully
@@ -2571,9 +2625,9 @@ zfcp_erp_port_strategy_clearstati(struct zfcp_port *port)
 }
 
 /*
- * function:   
+ * function:
  *
- * purpose:    
+ * purpose:
  *
  * returns:    ZFCP_ERP_CONTINUES      - action continues (asynchronously)
  *             ZFCP_ERP_FAILED         - action finished unsuccessfully
@@ -2608,9 +2662,9 @@ zfcp_erp_port_strategy_close(struct zfcp_erp_action *erp_action)
 }
 
 /*
- * function:   
+ * function:
  *
- * purpose:    
+ * purpose:
  *
  * returns:    ZFCP_ERP_CONTINUES      - action continues (asynchronously)
  *             ZFCP_ERP_FAILED         - action finished unsuccessfully
@@ -2645,9 +2699,9 @@ zfcp_erp_port_strategy_open_port(struct zfcp_erp_action *erp_action)
 }
 
 /*
- * function:   
+ * function:
  *
- * purpose:    
+ * purpose:
  *
  * returns:    ZFCP_ERP_CONTINUES      - action continues (asynchronously)
  *             ZFCP_ERP_FAILED         - action finished unsuccessfully
@@ -2682,7 +2736,7 @@ zfcp_erp_port_strategy_open_common_lookup(struct zfcp_erp_action *erp_action)
 }
 
 /*
- * function:   
+ * function:
  *
  * purpose:    this routine executes the 'Reopen Unit' action
  *             currently no retries
@@ -2770,9 +2824,9 @@ zfcp_erp_unit_strategy_clearstati(struct zfcp_unit *unit)
 }
 
 /*
- * function:   
+ * function:
  *
- * purpose:    
+ * purpose:
  *
  * returns:    ZFCP_ERP_CONTINUES      - action continues (asynchronously)
  *             ZFCP_ERP_FAILED         - action finished unsuccessfully
@@ -2810,9 +2864,9 @@ zfcp_erp_unit_strategy_close(struct zfcp_erp_action *erp_action)
 }
 
 /*
- * function:   
+ * function:
  *
- * purpose:    
+ * purpose:
  *
  * returns:    ZFCP_ERP_CONTINUES      - action continues (asynchronously)
  *             ZFCP_ERP_FAILED         - action finished unsuccessfully
@@ -2858,7 +2912,7 @@ void zfcp_erp_start_timer(struct zfcp_fsf_req *fsf_req)
 }
 
 /*
- * function:   
+ * function:
  *
  * purpose:    enqueue the specified error recovery action, if needed
  *
@@ -2937,7 +2991,7 @@ zfcp_erp_action_enqueue(int action,
                                              port->erp_action.action);
                                debug_text_event(adapter->erp_dbf, 4,
                                                 "pf_actenq_drp");
-                       } else 
+                       } else
                                debug_text_event(adapter->erp_dbf, 4,
                                                 "pf_actenq_drpcp");
                        debug_event(adapter->erp_dbf, 4, &port->wwpn,
@@ -3098,9 +3152,9 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter,
                    && port->rport) {
                        atomic_set_mask(ZFCP_STATUS_UNIT_REGISTERED,
                                        &unit->status);
-                       scsi_scan_target(&port->rport->dev, 0,
-                                        port->rport->scsi_target_id,
-                                        unit->scsi_lun, 0);
+                       if (atomic_test_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING,
+                                            &unit->status) == 0)
+                               zfcp_erp_schedule_work(unit);
                }
                zfcp_unit_put(unit);
                break;
@@ -3127,7 +3181,7 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter,
                                                zfcp_get_busid_by_port(port),
                                                port->wwpn);
                        else {
-                               scsi_flush_work(adapter->scsi_host);
+                               scsi_target_unblock(&port->rport->dev);
                                port->rport->maxframe_size = port->maxframe_size;
                                port->rport->supported_classes =
                                        port->supported_classes;
@@ -3141,7 +3195,6 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter,
                break;
        case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
                if (result != ZFCP_ERP_SUCCEEDED) {
-                       struct zfcp_port *port;
                        list_for_each_entry(port, &adapter->port_list_head, list)
                                if (port->rport &&
                                    !atomic_test_mask(ZFCP_STATUS_PORT_WKA,
@@ -3194,8 +3247,7 @@ static void zfcp_erp_action_dismiss_unit(struct zfcp_unit *unit)
                zfcp_erp_action_dismiss(&unit->erp_action);
 }
 
-static inline void
-zfcp_erp_action_to_running(struct zfcp_erp_action *erp_action)
+static void zfcp_erp_action_to_running(struct zfcp_erp_action *erp_action)
 {
        struct zfcp_adapter *adapter = erp_action->adapter;
 
@@ -3204,8 +3256,7 @@ zfcp_erp_action_to_running(struct zfcp_erp_action *erp_action)
        list_move(&erp_action->list, &erp_action->adapter->erp_running_head);
 }
 
-static inline void
-zfcp_erp_action_to_ready(struct zfcp_erp_action *erp_action)
+static void zfcp_erp_action_to_ready(struct zfcp_erp_action *erp_action)
 {
        struct zfcp_adapter *adapter = erp_action->adapter;