This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / drivers / s390 / scsi / zfcp_erp.c
index 505e16f..55759e8 100644 (file)
 #define ZFCP_LOG_AREA                  ZFCP_LOG_AREA_ERP
 
 /* this drivers version (do not edit !!! generated and updated by cvs) */
-#define ZFCP_ERP_REVISION "$Revision: 1.54 $"
+#define ZFCP_ERP_REVISION "$Revision: 1.65 $"
 
 #include "zfcp_ext.h"
 
 static int zfcp_els(struct zfcp_port *, u8);
-static int zfcp_els_handler(unsigned long);
+static void zfcp_els_handler(unsigned long);
 
 static int zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *, int);
 static int zfcp_erp_port_forced_reopen_internal(struct zfcp_port *, int);
@@ -126,6 +126,25 @@ static void zfcp_erp_memwait_handler(unsigned long);
 static void zfcp_erp_timeout_handler(unsigned long);
 static inline void zfcp_erp_timeout_init(struct zfcp_erp_action *);
 
+/**
+ * zfcp_fsf_request_timeout_handler - called if a request timed out
+ * @data: pointer to adapter for handler function
+ *
+ * This function needs to be called if requests (ELS, Generic Service,
+ * or SCSI commands) exceed a certain time limit. The assumption is
+ * that after the time limit the adapter get stuck. So we trigger a reopen of
+ * the adapter. This should not be used for error recovery, SCSI abort
+ * commands and SCSI requests from SCSI mid-layer.
+ */
+void
+zfcp_fsf_request_timeout_handler(unsigned long data)
+{
+       struct zfcp_adapter *adapter;
+
+       adapter = (struct zfcp_adapter *) data;
+
+       zfcp_erp_adapter_reopen(adapter, 0);
+}
 
 /*
  * function:   zfcp_fsf_scsi_er_timeout_handler
@@ -324,6 +343,7 @@ zfcp_els(struct zfcp_port *port, u8 ls_code)
        send_els->completion = NULL;
 
        req = zfcp_sg_to_address(send_els->req);
+       memset(req, 0, PAGE_SIZE);
 
        *(u32*)req = 0;
        *(u8*)req = ls_code;
@@ -412,173 +432,99 @@ out:
 }
 
 
-/*
- * function:    zfcp_els_handler
- *
- * purpose:     Handler for all kind of ELSs
- *
- * returns:     0       - Operation completed successfuly
- *              -ENXIO  - ELS has been rejected
- *              -EPERM  - Port forced reopen failed
+/**
+ * zfcp_els_handler - handler for ELS commands
+ * @data: pointer to struct zfcp_send_els
+ * If ELS failed (LS_RJT or timed out) forced reopen of the port is triggered.
  */
-int
+void
 zfcp_els_handler(unsigned long data)
 {
        struct zfcp_send_els *send_els = (struct zfcp_send_els*)data;
        struct zfcp_port *port = send_els->port;
-       struct zfcp_ls_rjt *rjt;
        struct zfcp_ls_rtv_acc *rtv;
        struct zfcp_ls_rls_acc *rls;
        struct zfcp_ls_pdisc_acc *pdisc;
        struct zfcp_ls_adisc_acc *adisc;
        void *req, *resp;
-       u8 req_code, resp_code;
-       int retval = 0;
+       u8 req_code;
 
-       if (send_els->status != 0)
-               goto skip_fsfstatus;
+       /* request rejected or timed out */
+       if (send_els->status != 0) {
+               ZFCP_LOG_NORMAL("ELS request timed out, force physical port "
+                               "reopen of port 0x%016Lx on adapter %s\n",
+                               port->wwpn, zfcp_get_busid_by_port(port));
+               debug_text_event(port->adapter->erp_dbf, 3, "forcreop");
+               if (zfcp_erp_port_forced_reopen(port, 0))
+                       ZFCP_LOG_NORMAL("reopen of remote port 0x%016Lx "
+                                       "on adapter %s failed\n", port->wwpn,
+                                       zfcp_get_busid_by_port(port));
+               goto out;
+       }
 
-       req = (void*)((page_to_pfn(send_els->req->page) << PAGE_SHIFT) + send_els->req->offset);
-       resp = (void*)((page_to_pfn(send_els->resp->page) << PAGE_SHIFT) + send_els->resp->offset);
+       req = zfcp_sg_to_address(send_els->req);
+       resp = zfcp_sg_to_address(send_els->resp);
        req_code = *(u8*)req;
-       resp_code = *(u8*)resp;
-
-       switch (resp_code) {
 
-       case ZFCP_LS_RJT:
-               rjt = (struct zfcp_ls_rjt*)resp;
+       switch (req_code) {
 
-               switch (rjt->reason_code) {
-
-               case ZFCP_LS_RJT_INVALID_COMMAND_CODE:
-                       ZFCP_LOG_INFO("invalid LS command code "
-                                     "(wwpn=0x%016Lx, command=0x%02x)\n",
-                                     port->wwpn, req_code);
-                       break;
-
-               case ZFCP_LS_RJT_LOGICAL_ERROR:
-                       ZFCP_LOG_INFO("logical error (wwpn=0x%016Lx, "
-                                     "reason_expl=0x%02x)\n",
-                                     port->wwpn, rjt->reason_expl);
-                       break;
-
-               case ZFCP_LS_RJT_LOGICAL_BUSY:
-                       ZFCP_LOG_INFO("logical busy (wwpn=0x%016Lx, "
-                                     "reason_expl=0x%02x)\n",
-                                     port->wwpn, rjt->reason_expl);
-                       break;
-
-               case ZFCP_LS_RJT_PROTOCOL_ERROR:
-                       ZFCP_LOG_INFO("protocol error (wwpn=0x%016Lx, "
-                                     "reason_expl=0x%02x)\n",
-                                     port->wwpn, rjt->reason_expl);
-                       break;
-
-               case ZFCP_LS_RJT_UNABLE_TO_PERFORM:
-                       ZFCP_LOG_INFO("unable to perform command requested "
-                                     "(wwpn=0x%016Lx, reason_expl=0x%02x)\n",
-                                     port->wwpn, rjt->reason_expl);
-                       break;
-
-               case ZFCP_LS_RJT_COMMAND_NOT_SUPPORTED:
-                       ZFCP_LOG_INFO("command not supported (wwpn=0x%016Lx, "
-                                     "command=0x%02x)\n",
-                                     port->wwpn, req_code);
-                       break;
-
-               case ZFCP_LS_RJT_VENDOR_UNIQUE_ERROR:
-                       ZFCP_LOG_INFO("vendor specific error (wwpn=0x%016Lx, "
-                                     "vendor_unique=0x%02x)\n",
-                                     port->wwpn, rjt->vendor_unique);
-                       break;
-
-               default:
-                       ZFCP_LOG_NORMAL("ELS rejected by remote port 0x%016Lx "
-                                       "on adapter %s (reason_code=0x%02x)\n",
-                                       port->wwpn,
-                                       zfcp_get_busid_by_port(port),
-                                       rjt->reason_code);
-               }
-               retval = -ENXIO;
+       case ZFCP_LS_RTV:
+               rtv = (struct zfcp_ls_rtv_acc*)resp;
+               ZFCP_LOG_INFO("RTV response from d_id 0x%08x to s_id "
+                             "0x%08x (R_A_TOV=%ds E_D_TOV=%d%cs)\n",
+                             port->d_id, port->adapter->s_id,
+                             rtv->r_a_tov, rtv->e_d_tov,
+                             rtv->qualifier &
+                             ZFCP_LS_RTV_E_D_TOV_FLAG ? 'n' : 'm');
                break;
 
-       case ZFCP_LS_ACC:
-               switch (req_code) {
-
-               case ZFCP_LS_RTV:
-                       rtv = (struct zfcp_ls_rtv_acc*)resp;
-                       ZFCP_LOG_INFO("RTV response from d_id 0x%08x to s_id "
-                                     "0x%08x (R_A_TOV=%ds E_D_TOV=%d%cs)\n",
-                                     port->d_id, port->adapter->s_id,
-                                     rtv->r_a_tov, rtv->e_d_tov,
-                                     rtv->qualifier &
-                                     ZFCP_LS_RTV_E_D_TOV_FLAG ? 'n' : 'm');
-                       break;
-
-               case ZFCP_LS_RLS:
-                       rls = (struct zfcp_ls_rls_acc*)resp;
-                       ZFCP_LOG_INFO("RLS response from d_id 0x%08x to s_id "
-                                     "0x%08x (link_failure_count=%u, "
-                                     "loss_of_sync_count=%u, "
-                                     "loss_of_signal_count=%u, "
-                                     "primitive_sequence_protocol_error=%u, "
-                                     "invalid_transmition_word=%u, "
-                                     "invalid_crc_count=%u)\n",
-                                     port->d_id, port->adapter->s_id,
-                                     rls->link_failure_count,
-                                     rls->loss_of_sync_count,
-                                     rls->loss_of_signal_count,
-                                     rls->prim_seq_prot_error,
-                                     rls->invalid_transmition_word,
-                                     rls->invalid_crc_count);
-                       break;
-
-               case ZFCP_LS_PDISC:
-                       pdisc = (struct zfcp_ls_pdisc_acc*)resp;
-                       ZFCP_LOG_INFO("PDISC response from d_id 0x%08x to s_id "
-                                     "0x%08x (wwpn=0x%016Lx, wwnn=0x%016Lx, "
-                                     "vendor='%-16s')\n", port->d_id,
-                                     port->adapter->s_id, pdisc->wwpn,
-                                     pdisc->wwnn, pdisc->vendor_version);
-                       break;
+       case ZFCP_LS_RLS:
+               rls = (struct zfcp_ls_rls_acc*)resp;
+               ZFCP_LOG_INFO("RLS response from d_id 0x%08x to s_id "
+                             "0x%08x (link_failure_count=%u, "
+                             "loss_of_sync_count=%u, "
+                             "loss_of_signal_count=%u, "
+                             "primitive_sequence_protocol_error=%u, "
+                             "invalid_transmition_word=%u, "
+                             "invalid_crc_count=%u)\n",
+                             port->d_id, port->adapter->s_id,
+                             rls->link_failure_count,
+                             rls->loss_of_sync_count,
+                             rls->loss_of_signal_count,
+                             rls->prim_seq_prot_error,
+                             rls->invalid_transmition_word,
+                             rls->invalid_crc_count);
+               break;
 
-               case ZFCP_LS_ADISC:
-                       adisc = (struct zfcp_ls_adisc_acc*)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", port->d_id,
-                                     port->adapter->s_id, adisc->wwpn,
-                                     adisc->wwnn, adisc->hard_nport_id,
-                                     adisc->nport_id);
-                       /* FIXME: set wwnn in during open port */
-                       if (port->wwnn == 0)
-                               port->wwnn = adisc->wwnn;
-                       break;
-               }
+       case ZFCP_LS_PDISC:
+               pdisc = (struct zfcp_ls_pdisc_acc*)resp;
+               ZFCP_LOG_INFO("PDISC response from d_id 0x%08x to s_id "
+                             "0x%08x (wwpn=0x%016Lx, wwnn=0x%016Lx, "
+                             "vendor='%-16s')\n", port->d_id,
+                             port->adapter->s_id, pdisc->wwpn,
+                             pdisc->wwnn, pdisc->vendor_version);
                break;
 
-       default:
-               ZFCP_LOG_NORMAL("unknown payload code 0x%02x received for "
-                               "request 0x%02x to d_id 0x%08x, reopen needed "
-                               "for port 0x%016Lx on adapter %s\n", resp_code,
-                               req_code, port->d_id,  port->wwpn,
-                               zfcp_get_busid_by_port(port));
-               retval = zfcp_erp_port_forced_reopen(port, 0);
-               if (retval != 0) {
-                       ZFCP_LOG_NORMAL("reopen of remote port 0x%016Lx on "
-                                       "adapter %s failed\n", port->wwpn,
-                                       zfcp_get_busid_by_port(port));
-                       retval = -EPERM;
-               }
+       case ZFCP_LS_ADISC:
+               adisc = (struct zfcp_ls_adisc_acc*)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", port->d_id,
+                             port->adapter->s_id, adisc->wwpn,
+                             adisc->wwnn, adisc->hard_nport_id,
+                             adisc->nport_id);
+               /* FIXME: set wwnn in during open port */
+               if (port->wwnn == 0)
+                       port->wwnn = adisc->wwnn;
+               break;
        }
 
-skip_fsfstatus:
+ out:
        __free_pages(send_els->req->page, 0);
        kfree(send_els->req);
        kfree(send_els->resp);
-
-       return retval;
+       kfree(send_els);
 }
 
 
@@ -723,14 +669,15 @@ zfcp_erp_port_reopen_internal(struct zfcp_port *port, int clear_mask)
        return retval;
 }
 
-/*
- * function:   
- *
- * purpose:    Wrappper for zfcp_erp_port_reopen_internal
- *              used to ensure the correct locking
+/**
+ * zfcp_erp_port_reopen - initiate reopen of a remote port
+ * @port: port to be reopened
+ * @clear_mask: specifies flags in port status to be cleared
+ * Return: 0 on success, < 0 on error
  *
- * returns:    0       - initiated action succesfully
- *             <0      - failed to initiate action
+ * This is a wrappper function for zfcp_erp_port_reopen_internal. It ensures
+ * correct locking. An error recovery task is initiated to do the reopen.
+ * To wait for the completion of the reopen zfcp_erp_wait should be used.
  */
 int
 zfcp_erp_port_reopen(struct zfcp_port *port, int clear_mask)
@@ -790,14 +737,15 @@ zfcp_erp_unit_reopen_internal(struct zfcp_unit *unit, int clear_mask)
        return retval;
 }
 
-/*
- * function:   
- *
- * purpose:    Wrappper for zfcp_erp_unit_reopen_internal
- *              used to ensure the correct locking
+/**
+ * zfcp_erp_unit_reopen - initiate reopen of a unit
+ * @unit: unit to be reopened
+ * @clear_mask: specifies flags in unit status to be cleared
+ * Return: 0 on success, < 0 on error
  *
- * returns:    0       - initiated action succesfully
- *             <0      - failed to initiate action
+ * This is a wrappper for zfcp_erp_unit_reopen_internal. It ensures correct
+ * locking. An error recovery task is initiated to do the reopen.
+ * To wait for the completion of the reopen zfcp_erp_wait should be used.
  */
 int
 zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear_mask)
@@ -1975,12 +1923,10 @@ zfcp_erp_strategy_check_queues(struct zfcp_adapter *adapter)
        return retval;
 }
 
-/*
- * function:   
- *
- * purpose:    
- *
- * returns:
+/**
+ * zfcp_erp_wait - wait for completion of error recovery on an adapter
+ * @adapter: adapter for which to wait for completion of its error recovery
+ * Return: 0
  */
 int
 zfcp_erp_wait(struct zfcp_adapter *adapter)
@@ -2118,7 +2064,7 @@ zfcp_erp_port_reopen_all_internal(struct zfcp_adapter *adapter, int clear_mask)
        struct zfcp_port *port;
 
        list_for_each_entry(port, &adapter->port_list_head, list)
-               if (!atomic_test_mask(ZFCP_STATUS_PORT_NAMESERVER, &port->status))
+               if (!atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status))
                        zfcp_erp_port_reopen_internal(port, clear_mask);
 
        return retval;
@@ -2158,7 +2104,6 @@ static int
 zfcp_erp_adapter_strategy(struct zfcp_erp_action *erp_action)
 {
        int retval;
-       unsigned long timeout;
        struct zfcp_adapter *adapter = erp_action->adapter;
 
        retval = zfcp_erp_adapter_strategy_close(erp_action);
@@ -2175,14 +2120,7 @@ zfcp_erp_adapter_strategy(struct zfcp_erp_action *erp_action)
                ZFCP_LOG_INFO("Waiting to allow the adapter %s "
                              "to recover itself\n",
                              zfcp_get_busid_by_adapter(adapter));
-               /*
-                * SUGGESTION: substitute by
-                * timeout = ZFCP_TYPE2_RECOVERY_TIME;
-                * __ZFCP_WAIT_EVENT_TIMEOUT(timeout, 0);
-                */
-               timeout = ZFCP_TYPE2_RECOVERY_TIME;
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(timeout);
+               msleep(jiffies_to_msecs(ZFCP_TYPE2_RECOVERY_TIME));
        }
 
        return retval;
@@ -2286,7 +2224,6 @@ zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action)
        int i;
        volatile struct qdio_buffer_element *sbale;
        struct zfcp_adapter *adapter = erp_action->adapter;
-       int retval_cleanup = 0;
 
        if (atomic_test_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status)) {
                ZFCP_LOG_NORMAL("bug: second attempt to set up QDIO on "
@@ -2301,7 +2238,7 @@ zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action)
                              zfcp_get_busid_by_adapter(adapter));
                goto failed_qdio_establish;
        }
-       ZFCP_LOG_DEBUG("queues established\n");
+       debug_text_event(adapter->erp_dbf, 3, "qdio_est");
 
        if (qdio_activate(adapter->ccw_device, 0) != 0) {
                ZFCP_LOG_INFO("error: activation of QDIO queues failed "
@@ -2309,7 +2246,7 @@ zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action)
                              zfcp_get_busid_by_adapter(adapter));
                goto failed_qdio_activate;
        }
-       ZFCP_LOG_DEBUG("queues activated\n");
+       debug_text_event(adapter->erp_dbf, 3, "qdio_act");
 
        /*
         * put buffers into response queue,
@@ -2357,19 +2294,13 @@ zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action)
        /* NOP */
 
  failed_qdio_activate:
-       /* DEBUG */
-       //__ZFCP_WAIT_EVENT_TIMEOUT(timeout, 0);
-       /* cleanup queues previously established */
-       retval_cleanup = qdio_shutdown(adapter->ccw_device,
-                                      QDIO_FLAG_CLEANUP_USING_CLEAR);
-       if (retval_cleanup) {
-               ZFCP_LOG_NORMAL("bug: shutdown of QDIO queues failed "
-                               "(retval=%d)\n", retval_cleanup);
-       }
+       debug_text_event(adapter->erp_dbf, 3, "qdio_down1a");
+       while (qdio_shutdown(adapter->ccw_device,
+                            QDIO_FLAG_CLEANUP_USING_CLEAR) == -EINPROGRESS)
+               msleep(1000);
+       debug_text_event(adapter->erp_dbf, 3, "qdio_down1b");
 
  failed_qdio_establish:
-       atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
-
  failed_sanity:
        retval = ZFCP_ERP_FAILED;
 
@@ -2401,42 +2332,20 @@ zfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *erp_action)
                goto out;
        }
 
-       /* cleanup queues previously established */
-
        /*
-        * MUST NOT LOCK - qdio_cleanup might call schedule
-        * FIXME: need another way to make cleanup safe
-        */
-       /* Note:
-        * We need the request_queue lock here, otherwise there exists the 
-        * following race:
-        * 
-        * queuecommand calls create_fcp_commmand_task...calls req_create, 
-        * gets sbal x to x+y - meanwhile adapter reopen is called, completes 
-        * - req_send calls do_QDIO for sbal x to x+y, i.e. wrong indices.
-        *
-        * with lock:
-        * queuecommand calls create_fcp_commmand_task...calls req_create, 
-        * gets sbal x to x+y - meanwhile adapter reopen is called, waits 
-        * - req_send calls do_QDIO for sbal x to x+y, i.e. wrong indices 
-        * but do_QDIO fails as adapter_reopen is still waiting for the lock
-        * OR
-        * queuecommand calls create_fcp_commmand_task...calls req_create 
-        * - meanwhile adapter reopen is called...completes,
-        * - gets sbal 0 to 0+y, - req_send calls do_QDIO for sbal 0 to 0+y, 
-        * i.e. correct indices...though an fcp command is called before 
-        * exchange config data...that should be fine, however
+        * Get queue_lock and clear QDIOUP flag. Thus it's guaranteed that
+        * do_QDIO won't be called while qdio_shutdown is in progress.
         */
-       if (qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR)) {
-               /*
-                * FIXME(design):
-                * What went wrong? What to do best? Proper retval?
-                */
-               ZFCP_LOG_NORMAL("bug: shutdown of QDIO queues failed on "
-                               "adapter %s\n",
-                               zfcp_get_busid_by_adapter(adapter));
-       } else
-               ZFCP_LOG_DEBUG("queues cleaned up\n");
+
+       write_lock_irq(&adapter->request_queue.queue_lock);
+       atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
+       write_unlock_irq(&adapter->request_queue.queue_lock);
+
+       debug_text_event(adapter->erp_dbf, 3, "qdio_down2a");
+       while (qdio_shutdown(adapter->ccw_device,
+                            QDIO_FLAG_CLEANUP_USING_CLEAR) == -EINPROGRESS)
+               msleep(1000);
+       debug_text_event(adapter->erp_dbf, 3, "qdio_down2b");
 
        /*
         * First we had to stop QDIO operation.
@@ -2459,8 +2368,6 @@ zfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *erp_action)
        adapter->request_queue.free_index = 0;
        atomic_set(&adapter->request_queue.free_count, 0);
        adapter->request_queue.distance_from_int = 0;
-
-       atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
  out:
        return retval;
 }
@@ -2548,8 +2455,7 @@ zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action)
                        ZFCP_LOG_DEBUG("host connection still initialising... "
                                       "waiting and retrying...\n");
                        /* sleep a little bit before retry */
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout(ZFCP_EXCHANGE_CONFIG_DATA_SLEEP);
+                       msleep(jiffies_to_msecs(ZFCP_EXCHANGE_CONFIG_DATA_SLEEP));
                }
        } while ((retries--) &&
                 atomic_test_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,
@@ -2753,7 +2659,7 @@ zfcp_erp_port_strategy_open(struct zfcp_erp_action *erp_action)
 {
        int retval;
 
-       if (atomic_test_mask(ZFCP_STATUS_PORT_NAMESERVER,
+       if (atomic_test_mask(ZFCP_STATUS_PORT_WKA,
                             &erp_action->port->status))
                retval = zfcp_erp_port_strategy_open_nameserver(erp_action);
        else
@@ -2891,10 +2797,10 @@ zfcp_erp_port_strategy_open_nameserver(struct zfcp_erp_action *erp_action)
 
        case ZFCP_ERP_STEP_PORT_OPENING:
                if (atomic_test_mask(ZFCP_STATUS_COMMON_OPEN, &port->status)) {
-                       ZFCP_LOG_DEBUG("nameserver port is open\n");
+                       ZFCP_LOG_DEBUG("WKA port is open\n");
                        retval = ZFCP_ERP_SUCCEEDED;
                } else {
-                       ZFCP_LOG_DEBUG("open failed for nameserver port\n");
+                       ZFCP_LOG_DEBUG("open failed for WKA port\n");
                        retval = ZFCP_ERP_FAILED;
                }
                /* this is needed anyway (dont care for retval of wakeup) */