[SCSI] zfcp: fix initialization of FSF timer
[safe/jmp/linux-2.6] / drivers / s390 / scsi / zfcp_fsf.c
index fbc81b0..4c0a59a 100644 (file)
@@ -1,19 +1,8 @@
 /*
+ * This file is part of the zfcp device driver for
+ * FCP adapters for IBM System z9 and zSeries.
  *
- * linux/drivers/s390/scsi/zfcp_fsf.c
- *
- * FCP adapter driver for IBM eServer zSeries
- *
- * (C) Copyright IBM Corp. 2002, 2004
- *
- * Author(s): Martin Peschke <mpeschke@de.ibm.com>
- *            Raimund Schroeder <raimund.schroeder@de.ibm.com>
- *            Aron Zeh
- *            Wolfgang Taphorn
- *            Stefan Bader <stefan.bader@de.ibm.com>
- *            Heiko Carstens <heiko.carstens@de.ibm.com>
- *            Andreas Herrmann <aherrman@de.ibm.com>
- *            Volker Sameske <sameske@de.ibm.com>
+ * (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
@@ -30,8 +19,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define ZFCP_FSF_C_REVISION "$Revision: 1.92 $"
-
 #include "zfcp_ext.h"
 
 static int zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *);
@@ -55,14 +42,13 @@ static inline int zfcp_fsf_req_sbal_check(
 static inline int zfcp_use_one_sbal(
        struct scatterlist *, int, struct scatterlist *, int);
 static struct zfcp_fsf_req *zfcp_fsf_req_alloc(mempool_t *, int);
-static int zfcp_fsf_req_send(struct zfcp_fsf_req *, struct timer_list *);
+static int zfcp_fsf_req_send(struct zfcp_fsf_req *);
 static int zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *);
 static int zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *);
 static int zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *);
 static void zfcp_fsf_link_down_info_eval(struct zfcp_adapter *,
        struct fsf_link_down_info *);
 static int zfcp_fsf_req_dispatch(struct zfcp_fsf_req *);
-static void zfcp_fsf_req_dismiss(struct zfcp_fsf_req *);
 
 /* association between FSF command and FSF QTCB type */
 static u32 fsf_qtcb_type[] = {
@@ -114,14 +100,19 @@ zfcp_fsf_req_alloc(mempool_t *pool, int req_flags)
        if (req_flags & ZFCP_REQ_NO_QTCB)
                size = sizeof(struct zfcp_fsf_req);
        else
-               size = sizeof(struct zfcp_fsf_req_pool_element);
+               size = sizeof(struct zfcp_fsf_req_qtcb);
 
-       if (likely(pool != NULL))
+       if (likely(pool))
                ptr = mempool_alloc(pool, GFP_ATOMIC);
-       else
-               ptr = kmalloc(size, GFP_ATOMIC);
+       else {
+               if (req_flags & ZFCP_REQ_NO_QTCB)
+                       ptr = kmalloc(size, GFP_ATOMIC);
+               else
+                       ptr = kmem_cache_alloc(zfcp_data.fsf_req_qtcb_cache,
+                                              GFP_ATOMIC);
+       }
 
-       if (unlikely(NULL == ptr))
+       if (unlikely(!ptr))
                goto out;
 
        memset(ptr, 0, size);
@@ -129,9 +120,8 @@ zfcp_fsf_req_alloc(mempool_t *pool, int req_flags)
        if (req_flags & ZFCP_REQ_NO_QTCB) {
                fsf_req = (struct zfcp_fsf_req *) ptr;
        } else {
-               fsf_req = &((struct zfcp_fsf_req_pool_element *) ptr)->fsf_req;
-               fsf_req->qtcb =
-                       &((struct zfcp_fsf_req_pool_element *) ptr)->qtcb;
+               fsf_req = &((struct zfcp_fsf_req_qtcb *) ptr)->fsf_req;
+               fsf_req->qtcb = &((struct zfcp_fsf_req_qtcb *) ptr)->qtcb;
        }
 
        fsf_req->pool = pool;
@@ -153,55 +143,60 @@ zfcp_fsf_req_alloc(mempool_t *pool, int req_flags)
 void
 zfcp_fsf_req_free(struct zfcp_fsf_req *fsf_req)
 {
-       if (likely(fsf_req->pool != NULL))
+       if (likely(fsf_req->pool)) {
                mempool_free(fsf_req, fsf_req->pool);
-       else
-               kfree(fsf_req);
-}
-
-/*
- * function:   
- *
- * purpose:    
- *
- * returns:
- *
- * note: qdio queues shall be down (no ongoing inbound processing)
- */
-int
-zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
-{
-       struct zfcp_fsf_req *fsf_req, *tmp;
-       unsigned long flags;
-       LIST_HEAD(remove_queue);
-
-       spin_lock_irqsave(&adapter->fsf_req_list_lock, flags);
-       list_splice_init(&adapter->fsf_req_list_head, &remove_queue);
-       atomic_set(&adapter->fsf_reqs_active, 0);
-       spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
+               return;
+       }
 
-       list_for_each_entry_safe(fsf_req, tmp, &remove_queue, list) {
-               list_del(&fsf_req->list);
-               zfcp_fsf_req_dismiss(fsf_req);
+       if (fsf_req->qtcb) {
+               kmem_cache_free(zfcp_data.fsf_req_qtcb_cache, fsf_req);
+               return;
        }
 
-       return 0;
+       kfree(fsf_req);
 }
 
-/*
- * function:   
- *
- * purpose:    
- *
- * returns:
+/**
+ * zfcp_fsf_req_dismiss - dismiss a single fsf request
  */
-static void
-zfcp_fsf_req_dismiss(struct zfcp_fsf_req *fsf_req)
+static void zfcp_fsf_req_dismiss(struct zfcp_adapter *adapter,
+                                struct zfcp_fsf_req *fsf_req,
+                                unsigned int counter)
 {
+       u64 dbg_tmp[2];
+
+       dbg_tmp[0] = (u64) atomic_read(&adapter->reqs_active);
+       dbg_tmp[1] = (u64) counter;
+       debug_event(adapter->erp_dbf, 4, (void *) dbg_tmp, 16);
+       list_del(&fsf_req->list);
        fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
        zfcp_fsf_req_complete(fsf_req);
 }
 
+/**
+ * zfcp_fsf_req_dismiss_all - dismiss all remaining fsf requests
+ */
+void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
+{
+       struct zfcp_fsf_req *request, *tmp;
+       unsigned long flags;
+       LIST_HEAD(remove_queue);
+       unsigned int i, counter;
+
+       spin_lock_irqsave(&adapter->req_list_lock, flags);
+       atomic_set(&adapter->reqs_active, 0);
+       for (i=0; i<REQUEST_LIST_SIZE; i++)
+               list_splice_init(&adapter->req_list[i], &remove_queue);
+
+       spin_unlock_irqrestore(&adapter->req_list_lock, flags);
+
+       counter = 0;
+       list_for_each_entry_safe(request, tmp, &remove_queue, list) {
+               zfcp_fsf_req_dismiss(adapter, request, counter);
+               counter++;
+       }
+}
+
 /*
  * function:    zfcp_fsf_req_complete
  *
@@ -227,8 +222,10 @@ zfcp_fsf_req_complete(struct zfcp_fsf_req *fsf_req)
                 */
                zfcp_fsf_status_read_handler(fsf_req);
                goto out;
-       } else
+       } else {
+               del_timer(&fsf_req->timer);
                zfcp_fsf_protstatus_eval(fsf_req);
+       }
 
        /*
         * fsf_req may be deleted due to waking up functions, so 
@@ -302,9 +299,10 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
        }
 
        /* log additional information provided by FSF (if any) */
-       if (unlikely(qtcb->header.log_length)) {
+       if (likely(qtcb->header.log_length)) {
                /* do not trust them ;-) */
-               if (qtcb->header.log_start > sizeof(struct fsf_qtcb)) {
+               if (unlikely(qtcb->header.log_start >
+                            sizeof(struct fsf_qtcb))) {
                        ZFCP_LOG_NORMAL
                            ("bug: ULP (FSF logging) log data starts "
                             "beyond end of packet header. Ignored. "
@@ -313,8 +311,9 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
                             sizeof(struct fsf_qtcb));
                        goto forget_log;
                }
-               if ((size_t) (qtcb->header.log_start + qtcb->header.log_length)
-                   > sizeof(struct fsf_qtcb)) {
+               if (unlikely((size_t) (qtcb->header.log_start +
+                                      qtcb->header.log_length) >
+                            sizeof(struct fsf_qtcb))) {
                        ZFCP_LOG_NORMAL("bug: ULP (FSF logging) log data ends "
                                        "beyond end of packet header. Ignored. "
                                        "(start=%i, length=%i, size=%li)\n",
@@ -390,6 +389,7 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
        case FSF_PROT_LINK_DOWN:
                zfcp_fsf_link_down_info_eval(adapter,
                                             &prot_status_qual->link_down_info);
+               zfcp_erp_adapter_reopen(adapter, 0);
                fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
                break;
 
@@ -554,6 +554,15 @@ static void
 zfcp_fsf_link_down_info_eval(struct zfcp_adapter *adapter,
                             struct fsf_link_down_info *link_down)
 {
+       if (atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
+                            &adapter->status))
+               return;
+
+       atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status);
+
+       if (link_down == NULL)
+               goto out;
+
        switch (link_down->error_code) {
        case FSF_PSQ_LINK_NO_LIGHT:
                ZFCP_LOG_NORMAL("The local link to adapter %s is down "
@@ -634,21 +643,8 @@ zfcp_fsf_link_down_info_eval(struct zfcp_adapter *adapter,
                                link_down->explanation_code,
                                link_down->vendor_specific_code);
 
-       if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
-                             &adapter->status)) {
-               atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
-                               &adapter->status);
-               switch (link_down->error_code) {
-               case FSF_PSQ_LINK_NO_LIGHT:
-               case FSF_PSQ_LINK_WRAP_PLUG:
-               case FSF_PSQ_LINK_NO_FCP:
-               case FSF_PSQ_LINK_FIRMWARE_UPDATE:
-                       zfcp_erp_adapter_reopen(adapter, 0);
-                       break;
-               default:
-                       zfcp_erp_adapter_failed(adapter);
-               }
-       }
+ out:
+       zfcp_erp_adapter_failed(adapter);
 }
 
 /*
@@ -790,8 +786,7 @@ zfcp_fsf_status_read(struct zfcp_adapter *adapter, int req_flags)
        sbale->addr = (void *) status_buffer;
        sbale->length = sizeof(struct fsf_status_read_buffer);
 
-       /* start QDIO request for this FSF request */
-       retval = zfcp_fsf_req_send(fsf_req, NULL);
+       retval = zfcp_fsf_req_send(fsf_req);
        if (retval) {
                ZFCP_LOG_DEBUG("error: Could not set-up unsolicited status "
                               "environment.\n");
@@ -882,6 +877,7 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req)
        struct zfcp_adapter *adapter = fsf_req->adapter;
        struct fsf_status_read_buffer *status_buffer =
                (struct fsf_status_read_buffer *) fsf_req->data;
+       struct fsf_bit_error_payload *fsf_bit_error;
 
        if (fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED) {
                zfcp_hba_dbf_event_fsf_unsol("dism", adapter, status_buffer);
@@ -908,10 +904,37 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req)
                break;
 
        case FSF_STATUS_READ_BIT_ERROR_THRESHOLD:
-               ZFCP_LOG_NORMAL("Bit error threshold data received:\n");
-               ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL,
-                             (char *) status_buffer,
-                             sizeof (struct fsf_status_read_buffer));
+               fsf_bit_error = (struct fsf_bit_error_payload *)
+                       status_buffer->payload;
+               ZFCP_LOG_NORMAL("Warning: bit error threshold data "
+                   "received (adapter %s, "
+                   "link failures = %i, loss of sync errors = %i, "
+                   "loss of signal errors = %i, "
+                   "primitive sequence errors = %i, "
+                   "invalid transmission word errors = %i, "
+                   "CRC errors = %i)\n",
+                   zfcp_get_busid_by_adapter(adapter),
+                   fsf_bit_error->link_failure_error_count,
+                   fsf_bit_error->loss_of_sync_error_count,
+                   fsf_bit_error->loss_of_signal_error_count,
+                   fsf_bit_error->primitive_sequence_error_count,
+                   fsf_bit_error->invalid_transmission_word_error_count,
+                   fsf_bit_error->crc_error_count);
+               ZFCP_LOG_INFO("Additional bit error threshold data "
+                   "(adapter %s, "
+                   "primitive sequence event time-outs = %i, "
+                   "elastic buffer overrun errors = %i, "
+                   "advertised receive buffer-to-buffer credit = %i, "
+                   "current receice buffer-to-buffer credit = %i, "
+                   "advertised transmit buffer-to-buffer credit = %i, "
+                   "current transmit buffer-to-buffer credit = %i)\n",
+                   zfcp_get_busid_by_adapter(adapter),
+                   fsf_bit_error->primitive_sequence_event_timeout_count,
+                   fsf_bit_error->elastic_buffer_overrun_error_count,
+                   fsf_bit_error->advertised_receive_b2b_credit,
+                   fsf_bit_error->current_receive_b2b_credit,
+                   fsf_bit_error->advertised_transmit_b2b_credit,
+                   fsf_bit_error->current_transmit_b2b_credit);
                break;
 
        case FSF_STATUS_READ_LINK_DOWN:
@@ -919,30 +942,36 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req)
                case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK:
                        ZFCP_LOG_INFO("Physical link to adapter %s is down\n",
                                      zfcp_get_busid_by_adapter(adapter));
+                       zfcp_fsf_link_down_info_eval(adapter,
+                               (struct fsf_link_down_info *)
+                               &status_buffer->payload);
                        break;
                case FSF_STATUS_READ_SUB_FDISC_FAILED:
                        ZFCP_LOG_INFO("Local link to adapter %s is down "
                                      "due to failed FDISC login\n",
-                             zfcp_get_busid_by_adapter(adapter));
+                                     zfcp_get_busid_by_adapter(adapter));
+                       zfcp_fsf_link_down_info_eval(adapter,
+                               (struct fsf_link_down_info *)
+                               &status_buffer->payload);
                        break;
                case FSF_STATUS_READ_SUB_FIRMWARE_UPDATE:
                        ZFCP_LOG_INFO("Local link to adapter %s is down "
                                      "due to firmware update on adapter\n",
                                      zfcp_get_busid_by_adapter(adapter));
+                       zfcp_fsf_link_down_info_eval(adapter, NULL);
                        break;
                default:
                        ZFCP_LOG_INFO("Local link to adapter %s is down "
                                      "due to unknown reason\n",
                                      zfcp_get_busid_by_adapter(adapter));
+                       zfcp_fsf_link_down_info_eval(adapter, NULL);
                };
-               zfcp_fsf_link_down_info_eval(adapter,
-                       (struct fsf_link_down_info *) &status_buffer->payload);
                break;
 
        case FSF_STATUS_READ_LINK_UP:
                ZFCP_LOG_NORMAL("Local link to adapter %s was replugged. "
-                             "Restarting operations on this adapter\n",
-                             zfcp_get_busid_by_adapter(adapter));
+                               "Restarting operations on this adapter\n",
+                               zfcp_get_busid_by_adapter(adapter));
                /* All ports should be marked as ready to run again */
                zfcp_erp_modify_adapter_status(adapter,
                                               ZFCP_STATUS_COMMON_RUNNING,
@@ -952,6 +981,40 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req)
                                        | ZFCP_STATUS_COMMON_ERP_FAILED);
                break;
 
+       case FSF_STATUS_READ_NOTIFICATION_LOST:
+               ZFCP_LOG_NORMAL("Unsolicited status notification(s) lost: "
+                               "adapter %s%s%s%s%s%s%s%s%s\n",
+                               zfcp_get_busid_by_adapter(adapter),
+                               (status_buffer->status_subtype &
+                                       FSF_STATUS_READ_SUB_INCOMING_ELS) ?
+                                       ", incoming ELS" : "",
+                               (status_buffer->status_subtype &
+                                       FSF_STATUS_READ_SUB_SENSE_DATA) ?
+                                       ", sense data" : "",
+                               (status_buffer->status_subtype &
+                                       FSF_STATUS_READ_SUB_LINK_STATUS) ?
+                                       ", link status change" : "",
+                               (status_buffer->status_subtype &
+                                       FSF_STATUS_READ_SUB_PORT_CLOSED) ?
+                                       ", port close" : "",
+                               (status_buffer->status_subtype &
+                                       FSF_STATUS_READ_SUB_BIT_ERROR_THRESHOLD) ?
+                                       ", bit error exception" : "",
+                               (status_buffer->status_subtype &
+                                       FSF_STATUS_READ_SUB_ACT_UPDATED) ?
+                                       ", ACT update" : "",
+                               (status_buffer->status_subtype &
+                                       FSF_STATUS_READ_SUB_ACT_HARDENED) ?
+                                       ", ACT hardening" : "",
+                               (status_buffer->status_subtype &
+                                       FSF_STATUS_READ_SUB_FEATURE_UPDATE_ALERT) ?
+                                       ", adapter feature change" : "");
+
+               if (status_buffer->status_subtype &
+                   FSF_STATUS_READ_SUB_ACT_UPDATED)
+                       zfcp_erp_adapter_access_changed(adapter);
+               break;
+
        case FSF_STATUS_READ_CFDC_UPDATED:
                ZFCP_LOG_NORMAL("CFDC has been updated on the adapter %s\n",
                              zfcp_get_busid_by_adapter(adapter));
@@ -1049,8 +1112,8 @@ zfcp_fsf_abort_fcp_command(unsigned long old_req_id,
                           struct zfcp_unit *unit, int req_flags)
 {
        volatile struct qdio_buffer_element *sbale;
-       unsigned long lock_flags;
        struct zfcp_fsf_req *fsf_req = NULL;
+       unsigned long lock_flags;
        int retval = 0;
 
        /* setup new FSF request */
@@ -1080,12 +1143,9 @@ zfcp_fsf_abort_fcp_command(unsigned long old_req_id,
        /* set handle of request which should be aborted */
        fsf_req->qtcb->bottom.support.req_handle = (u64) old_req_id;
 
-       /* start QDIO request for this FSF request */
-
-       zfcp_fsf_start_scsi_er_timer(adapter);
-       retval = zfcp_fsf_req_send(fsf_req, NULL);
+       zfcp_fsf_start_timer(fsf_req, ZFCP_SCSI_ER_TIMEOUT);
+       retval = zfcp_fsf_req_send(fsf_req);
        if (retval) {
-               del_timer(&adapter->scsi_er_timer);
                ZFCP_LOG_INFO("error: Failed to send abort command request "
                              "on adapter %s, port 0x%016Lx, unit 0x%016Lx\n",
                              zfcp_get_busid_by_adapter(adapter),
@@ -1121,8 +1181,6 @@ zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req)
        unsigned char status_qual =
            new_fsf_req->qtcb->header.fsf_status_qual.word[0];
 
-       del_timer(&new_fsf_req->adapter->scsi_er_timer);
-
        if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) {
                /* do not set ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED */
                goto skip_fsfstatus;
@@ -1328,11 +1386,6 @@ zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool,
                goto failed_req;
        }
 
-        if (erp_action != NULL) {
-                erp_action->fsf_req = fsf_req;
-                fsf_req->erp_action = erp_action;
-        }
-
        sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
         if (zfcp_use_one_sbal(ct->req, ct->req_count,
                               ct->resp, ct->resp_count)){
@@ -1392,14 +1445,21 @@ zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool,
 
        /* settings in QTCB */
        fsf_req->qtcb->header.port_handle = port->handle;
-       fsf_req->qtcb->bottom.support.service_class = adapter->fc_service_class;
+       fsf_req->qtcb->bottom.support.service_class =
+               ZFCP_FC_SERVICE_CLASS_DEFAULT;
        fsf_req->qtcb->bottom.support.timeout = ct->timeout;
         fsf_req->data = (unsigned long) ct;
 
        zfcp_san_dbf_event_ct_request(fsf_req);
 
-       /* start QDIO request for this FSF request */
-       ret = zfcp_fsf_req_send(fsf_req, ct->timer);
+       if (erp_action) {
+               erp_action->fsf_req = fsf_req;
+               fsf_req->erp_action = erp_action;
+               zfcp_erp_start_timer(fsf_req);
+       } else
+               zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT);
+
+       ret = zfcp_fsf_req_send(fsf_req);
        if (ret) {
                ZFCP_LOG_DEBUG("error: initiation of CT request failed "
                               "(adapter %s, port 0x%016Lx)\n",
@@ -1461,18 +1521,10 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req)
                break;
 
         case FSF_SERVICE_CLASS_NOT_SUPPORTED:
-               if (adapter->fc_service_class <= 3) {
-                       ZFCP_LOG_INFO("error: adapter %s does not support fc "
-                                     "class %d.\n",
-                                     zfcp_get_busid_by_port(port),
-                                     adapter->fc_service_class);
-               } else {
-                       ZFCP_LOG_INFO("bug: The fibre channel class at the "
-                                     "adapter %s is invalid. "
-                                     "(debug info %d)\n",
-                                     zfcp_get_busid_by_port(port),
-                                     adapter->fc_service_class);
-               }
+               ZFCP_LOG_INFO("error: adapter %s does not support fc "
+                             "class %d.\n",
+                             zfcp_get_busid_by_port(port),
+                             ZFCP_FC_SERVICE_CLASS_DEFAULT);
                /* stop operation for this adapter */
                debug_text_exception(adapter->erp_dbf, 0, "fsf_s_class_nsup");
                zfcp_erp_adapter_shutdown(adapter, 0);
@@ -1695,7 +1747,8 @@ zfcp_fsf_send_els(struct zfcp_send_els *els)
 
        /* settings in QTCB */
        fsf_req->qtcb->bottom.support.d_id = d_id;
-       fsf_req->qtcb->bottom.support.service_class = adapter->fc_service_class;
+       fsf_req->qtcb->bottom.support.service_class =
+               ZFCP_FC_SERVICE_CLASS_DEFAULT;
        fsf_req->qtcb->bottom.support.timeout = ZFCP_ELS_TIMEOUT;
        fsf_req->data = (unsigned long) els;
 
@@ -1703,8 +1756,8 @@ zfcp_fsf_send_els(struct zfcp_send_els *els)
 
        zfcp_san_dbf_event_els_request(fsf_req);
 
-       /* start QDIO request for this FSF request */
-       ret = zfcp_fsf_req_send(fsf_req, els->timer);
+       zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT);
+       ret = zfcp_fsf_req_send(fsf_req);
        if (ret) {
                ZFCP_LOG_DEBUG("error: initiation of ELS request failed "
                               "(adapter %s, port d_id: 0x%08x)\n",
@@ -1765,18 +1818,10 @@ static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req)
                break;
 
        case FSF_SERVICE_CLASS_NOT_SUPPORTED:
-               if (adapter->fc_service_class <= 3) {
-                       ZFCP_LOG_INFO("error: adapter %s does "
-                                     "not support fibrechannel class %d.\n",
-                                     zfcp_get_busid_by_adapter(adapter),
-                                     adapter->fc_service_class);
-               } else {
-                       ZFCP_LOG_INFO("bug: The fibrechannel class at "
-                                     "adapter %s is invalid. "
-                                     "(debug info %d)\n",
-                                     zfcp_get_busid_by_adapter(adapter),
-                                     adapter->fc_service_class);
-               }
+               ZFCP_LOG_INFO("error: adapter %s does not support fc "
+                             "class %d.\n",
+                             zfcp_get_busid_by_adapter(adapter),
+                             ZFCP_FC_SERVICE_CLASS_DEFAULT);
                /* stop operation for this adapter */
                debug_text_exception(adapter->erp_dbf, 0, "fsf_s_class_nsup");
                zfcp_erp_adapter_shutdown(adapter, 0);
@@ -1905,18 +1950,11 @@ skip_fsfstatus:
        return retval;
 }
 
-/*
- * function:
- *
- * purpose:
- *
- * returns:    address of initiated FSF request
- *             NULL - request could not be initiated
- */
 int
 zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
 {
        volatile struct qdio_buffer_element *sbale;
+       struct zfcp_fsf_req *fsf_req;
        unsigned long lock_flags;
        int retval = 0;
 
@@ -1925,7 +1963,7 @@ zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
                                     FSF_QTCB_EXCHANGE_CONFIG_DATA,
                                     ZFCP_REQ_AUTO_CLEANUP,
                                     erp_action->adapter->pool.fsf_req_erp,
-                                    &lock_flags, &(erp_action->fsf_req));
+                                    &lock_flags, &fsf_req);
        if (retval < 0) {
                ZFCP_LOG_INFO("error: Could not create exchange configuration "
                              "data request for adapter %s.\n",
@@ -1933,25 +1971,26 @@ zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
                goto out;
        }
 
-       sbale = zfcp_qdio_sbale_req(erp_action->fsf_req,
-                                    erp_action->fsf_req->sbal_curr, 0);
+       sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
         sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
         sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
-       erp_action->fsf_req->erp_action = erp_action;
-       erp_action->fsf_req->qtcb->bottom.config.feature_selection =
+       fsf_req->qtcb->bottom.config.feature_selection =
                        FSF_FEATURE_CFDC |
                        FSF_FEATURE_LUN_SHARING |
+                       FSF_FEATURE_NOTIFICATION_LOST |
                        FSF_FEATURE_UPDATE_ALERT;
+       fsf_req->erp_action = erp_action;
+       erp_action->fsf_req = fsf_req;
 
-       /* start QDIO request for this FSF request */
-       retval = zfcp_fsf_req_send(erp_action->fsf_req, &erp_action->timer);
+       zfcp_erp_start_timer(fsf_req);
+       retval = zfcp_fsf_req_send(fsf_req);
        if (retval) {
                ZFCP_LOG_INFO
                    ("error: Could not send exchange configuration data "
                     "command on the adapter %s\n",
                     zfcp_get_busid_by_adapter(erp_action->adapter));
-               zfcp_fsf_req_free(erp_action->fsf_req);
+               zfcp_fsf_req_free(fsf_req);
                erp_action->fsf_req = NULL;
                goto out;
        }
@@ -1996,27 +2035,30 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
                fc_host_port_id(shost) = bottom->s_id & ZFCP_DID_MASK;
                fc_host_speed(shost) = bottom->fc_link_speed;
                fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3;
-               adapter->fc_topology = bottom->fc_topology;
                adapter->hydra_version = bottom->adapter_type;
-               if (adapter->physical_wwpn == 0)
-                       adapter->physical_wwpn = fc_host_port_name(shost);
-               if (adapter->physical_s_id == 0)
-                       adapter->physical_s_id = fc_host_port_id(shost);
+               if (fc_host_permanent_port_name(shost) == -1)
+                       fc_host_permanent_port_name(shost) =
+                               fc_host_port_name(shost);
+               if (bottom->fc_topology == FSF_TOPO_P2P) {
+                       adapter->peer_d_id = bottom->peer_d_id & ZFCP_DID_MASK;
+                       adapter->peer_wwpn = bottom->plogi_payload.wwpn;
+                       adapter->peer_wwnn = bottom->plogi_payload.wwnn;
+                       fc_host_port_type(shost) = FC_PORTTYPE_PTP;
+               } else if (bottom->fc_topology == FSF_TOPO_FABRIC)
+                       fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
+               else if (bottom->fc_topology == FSF_TOPO_AL)
+                       fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
+               else
+                       fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
        } else {
                fc_host_node_name(shost) = 0;
                fc_host_port_name(shost) = 0;
                fc_host_port_id(shost) = 0;
                fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
-               adapter->fc_topology = 0;
+               fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
                adapter->hydra_version = 0;
        }
 
-       if (adapter->fc_topology == FSF_TOPO_P2P) {
-               adapter->peer_d_id = bottom->peer_d_id & ZFCP_DID_MASK;
-               adapter->peer_wwpn = bottom->plogi_payload.wwpn;
-               adapter->peer_wwnn = bottom->plogi_payload.wwnn;
-       }
-
        if (adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT) {
                adapter->hardware_version = bottom->hardware_version;
                memcpy(fc_host_serial_number(shost), bottom->serial_number,
@@ -2085,8 +2127,8 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
                if (zfcp_fsf_exchange_config_evaluate(fsf_req, 1))
                        return -EIO;
 
-               switch (adapter->fc_topology) {
-               case FSF_TOPO_P2P:
+               switch (fc_host_port_type(adapter->scsi_host)) {
+               case FC_PORTTYPE_PTP:
                        ZFCP_LOG_NORMAL("Point-to-Point fibrechannel "
                                        "configuration detected at adapter %s\n"
                                        "Peer WWNN 0x%016llx, "
@@ -2099,7 +2141,7 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
                        debug_text_event(fsf_req->adapter->erp_dbf, 0,
                                         "top-p-to-p");
                        break;
-               case FSF_TOPO_AL:
+               case FC_PORTTYPE_NLPORT:
                        ZFCP_LOG_NORMAL("error: Arbitrated loop fibrechannel "
                                        "topology detected at adapter %s "
                                        "unsupported, shutting down adapter\n",
@@ -2108,7 +2150,7 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
                                         "top-al");
                        zfcp_erp_adapter_shutdown(adapter, 0);
                        return -EIO;
-               case FSF_TOPO_FABRIC:
+               case FC_PORTTYPE_NPORT:
                        ZFCP_LOG_NORMAL("Switched fabric fibrechannel "
                                      "network detected at adapter %s.\n",
                                      zfcp_get_busid_by_adapter(adapter));
@@ -2121,7 +2163,6 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
                                        "of a type known to the zfcp "
                                        "driver, shutting down adapter\n",
                                        zfcp_get_busid_by_adapter(adapter));
-                       adapter->fc_topology = FSF_TOPO_ERROR;
                        debug_text_exception(fsf_req->adapter->erp_dbf, 0,
                                             "unknown-topo");
                        zfcp_erp_adapter_shutdown(adapter, 0);
@@ -2179,10 +2220,9 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
                            struct fsf_qtcb_bottom_port *data)
 {
        volatile struct qdio_buffer_element *sbale;
-       int retval = 0;
-       unsigned long lock_flags;
         struct zfcp_fsf_req *fsf_req;
-       struct timer_list *timer;
+       unsigned long lock_flags;
+       int retval = 0;
 
        if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) {
                ZFCP_LOG_INFO("error: exchange port data "
@@ -2194,7 +2234,7 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
        /* setup new FSF request */
        retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA,
                                     erp_action ? ZFCP_REQ_AUTO_CLEANUP : 0,
-                                    0, &lock_flags, &fsf_req);
+                                    NULL, &lock_flags, &fsf_req);
        if (retval < 0) {
                ZFCP_LOG_INFO("error: Out of resources. Could not create an "
                               "exchange port data request for"
@@ -2215,22 +2255,11 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
        if (erp_action) {
                erp_action->fsf_req = fsf_req;
                fsf_req->erp_action = erp_action;
-               timer = &erp_action->timer;
-       } else {
-               timer = kmalloc(sizeof(struct timer_list), GFP_ATOMIC);
-               if (!timer) {
-                       write_unlock_irqrestore(&adapter->request_queue.queue_lock,
-                                               lock_flags);
-                       zfcp_fsf_req_free(fsf_req);
-                       return -ENOMEM;
-               }
-               init_timer(timer);
-               timer->function = zfcp_fsf_request_timeout_handler;
-               timer->data = (unsigned long) adapter;
-               timer->expires = ZFCP_FSF_REQUEST_TIMEOUT;
-       }
+               zfcp_erp_start_timer(fsf_req);
+       } else
+               zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT);
 
-       retval = zfcp_fsf_req_send(fsf_req, timer);
+       retval = zfcp_fsf_req_send(fsf_req);
        if (retval) {
                ZFCP_LOG_INFO("error: Could not send an exchange port data "
                               "command on the adapter %s\n",
@@ -2238,8 +2267,6 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
                zfcp_fsf_req_free(fsf_req);
                if (erp_action)
                        erp_action->fsf_req = NULL;
-               else
-                       kfree(timer);
                write_unlock_irqrestore(&adapter->request_queue.queue_lock,
                                        lock_flags);
                return retval;
@@ -2250,13 +2277,40 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
        if (!erp_action) {
                wait_event(fsf_req->completion_wq,
                           fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
-               del_timer_sync(timer);
                zfcp_fsf_req_free(fsf_req);
-               kfree(timer);
        }
        return retval;
 }
 
+/**
+ * zfcp_fsf_exchange_port_evaluate
+ * @fsf_req: fsf_req which belongs to xchg port data request
+ * @xchg_ok: specifies if xchg port data was incomplete or complete (0/1)
+ */
+static void
+zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
+{
+       struct zfcp_adapter *adapter;
+       struct fsf_qtcb *qtcb;
+       struct fsf_qtcb_bottom_port *bottom, *data;
+       struct Scsi_Host *shost;
+
+       adapter = fsf_req->adapter;
+       qtcb = fsf_req->qtcb;
+       bottom = &qtcb->bottom.port;
+       shost = adapter->scsi_host;
+
+       data = (struct fsf_qtcb_bottom_port*) fsf_req->data;
+       if (data)
+               memcpy(data, bottom, sizeof(struct fsf_qtcb_bottom_port));
+
+       if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
+               fc_host_permanent_port_name(shost) = bottom->wwpn;
+       else
+               fc_host_permanent_port_name(shost) = fc_host_port_name(shost);
+       fc_host_maxframe_size(shost) = bottom->maximum_frame_size;
+       fc_host_supported_speeds(shost) = bottom->supported_speed;
+}
 
 /**
  * zfcp_fsf_exchange_port_data_handler - handler for exchange_port_data request
@@ -2265,39 +2319,26 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
 static void
 zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *fsf_req)
 {
-       struct zfcp_adapter *adapter = fsf_req->adapter;
-       struct Scsi_Host *shost = adapter->scsi_host;
-       struct fsf_qtcb *qtcb = fsf_req->qtcb;
-       struct fsf_qtcb_bottom_port *bottom, *data;
+       struct zfcp_adapter *adapter;
+       struct fsf_qtcb *qtcb;
+
+       adapter = fsf_req->adapter;
+       qtcb = fsf_req->qtcb;
 
        if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)
                return;
 
        switch (qtcb->header.fsf_status) {
         case FSF_GOOD:
+               zfcp_fsf_exchange_port_evaluate(fsf_req, 1);
                atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);
-
-               bottom = &qtcb->bottom.port;
-               data = (struct fsf_qtcb_bottom_port*) fsf_req->data;
-               if (data)
-                       memcpy(data, bottom, sizeof(struct fsf_qtcb_bottom_port));
-               if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) {
-                       adapter->physical_wwpn = bottom->wwpn;
-                       adapter->physical_s_id = bottom->fc_port_id;
-               } else {
-                       adapter->physical_wwpn = fc_host_port_name(shost);
-                       adapter->physical_s_id = fc_host_port_id(shost);
-               }
-               fc_host_maxframe_size(shost) = bottom->maximum_frame_size;
                break;
-
        case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE:
+               zfcp_fsf_exchange_port_evaluate(fsf_req, 0);
                atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);
-
                zfcp_fsf_link_down_info_eval(adapter,
                        &qtcb->header.fsf_status_qual.link_down_info);
                 break;
-
         default:
                debug_text_event(adapter->erp_dbf, 0, "xchg-port-ng");
                debug_event(adapter->erp_dbf, 0,
@@ -2318,6 +2359,7 @@ int
 zfcp_fsf_open_port(struct zfcp_erp_action *erp_action)
 {
        volatile struct qdio_buffer_element *sbale;
+       struct zfcp_fsf_req *fsf_req;
        unsigned long lock_flags;
        int retval = 0;
 
@@ -2326,7 +2368,7 @@ zfcp_fsf_open_port(struct zfcp_erp_action *erp_action)
                                     FSF_QTCB_OPEN_PORT_WITH_DID,
                                     ZFCP_WAIT_FOR_SBAL | ZFCP_REQ_AUTO_CLEANUP,
                                     erp_action->adapter->pool.fsf_req_erp,
-                                    &lock_flags, &(erp_action->fsf_req));
+                                    &lock_flags, &fsf_req);
        if (retval < 0) {
                ZFCP_LOG_INFO("error: Could not create open port request "
                              "for port 0x%016Lx on adapter %s.\n",
@@ -2335,24 +2377,24 @@ zfcp_fsf_open_port(struct zfcp_erp_action *erp_action)
                goto out;
        }
 
-       sbale = zfcp_qdio_sbale_req(erp_action->fsf_req,
-                                    erp_action->fsf_req->sbal_curr, 0);
+       sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
         sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
         sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
-       erp_action->fsf_req->qtcb->bottom.support.d_id = erp_action->port->d_id;
+       fsf_req->qtcb->bottom.support.d_id = erp_action->port->d_id;
        atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &erp_action->port->status);
-       erp_action->fsf_req->data = (unsigned long) erp_action->port;
-       erp_action->fsf_req->erp_action = erp_action;
+       fsf_req->data = (unsigned long) erp_action->port;
+       fsf_req->erp_action = erp_action;
+       erp_action->fsf_req = fsf_req;
 
-       /* start QDIO request for this FSF request */
-       retval = zfcp_fsf_req_send(erp_action->fsf_req, &erp_action->timer);
+       zfcp_erp_start_timer(fsf_req);
+       retval = zfcp_fsf_req_send(fsf_req);
        if (retval) {
                ZFCP_LOG_INFO("error: Could not send open port request for "
                              "port 0x%016Lx on adapter %s.\n",
                              erp_action->port->wwpn,
                              zfcp_get_busid_by_adapter(erp_action->adapter));
-               zfcp_fsf_req_free(erp_action->fsf_req);
+               zfcp_fsf_req_free(fsf_req);
                erp_action->fsf_req = NULL;
                goto out;
        }
@@ -2511,8 +2553,7 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req)
                if (!atomic_test_mask(ZFCP_STATUS_PORT_NO_WWPN, &port->status))
                {
                        if (fsf_req->qtcb->bottom.support.els1_length <
-                           ((((unsigned long) &plogi->serv_param.wwpn) -
-                             ((unsigned long) plogi)) + sizeof (u64))) {
+                           sizeof (struct fsf_plogi)) {
                                ZFCP_LOG_INFO(
                                        "warning: insufficient length of "
                                        "PLOGI payload (%i)\n",
@@ -2531,8 +2572,10 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req)
                                        atomic_clear_mask(
                                                ZFCP_STATUS_PORT_DID_DID,
                                                &port->status);
-                               } else
+                               } else {
                                        port->wwnn = plogi->serv_param.wwnn;
+                                       zfcp_plogi_evaluate(port, plogi);
+                               }
                        }
                }
                break;
@@ -2573,6 +2616,7 @@ int
 zfcp_fsf_close_port(struct zfcp_erp_action *erp_action)
 {
        volatile struct qdio_buffer_element *sbale;
+       struct zfcp_fsf_req *fsf_req;
        unsigned long lock_flags;
        int retval = 0;
 
@@ -2581,7 +2625,7 @@ zfcp_fsf_close_port(struct zfcp_erp_action *erp_action)
                                     FSF_QTCB_CLOSE_PORT,
                                     ZFCP_WAIT_FOR_SBAL | ZFCP_REQ_AUTO_CLEANUP,
                                     erp_action->adapter->pool.fsf_req_erp,
-                                    &lock_flags, &(erp_action->fsf_req));
+                                    &lock_flags, &fsf_req);
        if (retval < 0) {
                ZFCP_LOG_INFO("error: Could not create a close port request "
                              "for port 0x%016Lx on adapter %s.\n",
@@ -2590,25 +2634,25 @@ zfcp_fsf_close_port(struct zfcp_erp_action *erp_action)
                goto out;
        }
 
-       sbale = zfcp_qdio_sbale_req(erp_action->fsf_req,
-                                    erp_action->fsf_req->sbal_curr, 0);
+       sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
         sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
         sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
        atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING, &erp_action->port->status);
-       erp_action->fsf_req->data = (unsigned long) erp_action->port;
-       erp_action->fsf_req->erp_action = erp_action;
-       erp_action->fsf_req->qtcb->header.port_handle =
-           erp_action->port->handle;
-
-       /* start QDIO request for this FSF request */
-       retval = zfcp_fsf_req_send(erp_action->fsf_req, &erp_action->timer);
+       fsf_req->data = (unsigned long) erp_action->port;
+       fsf_req->erp_action = erp_action;
+       fsf_req->qtcb->header.port_handle = erp_action->port->handle;
+       fsf_req->erp_action = erp_action;
+       erp_action->fsf_req = fsf_req;
+
+       zfcp_erp_start_timer(fsf_req);
+       retval = zfcp_fsf_req_send(fsf_req);
        if (retval) {
                ZFCP_LOG_INFO("error: Could not send a close port request for "
                              "port 0x%016Lx on adapter %s.\n",
                              erp_action->port->wwpn,
                              zfcp_get_busid_by_adapter(erp_action->adapter));
-               zfcp_fsf_req_free(erp_action->fsf_req);
+               zfcp_fsf_req_free(fsf_req);
                erp_action->fsf_req = NULL;
                goto out;
        }
@@ -2705,16 +2749,17 @@ zfcp_fsf_close_port_handler(struct zfcp_fsf_req *fsf_req)
 int
 zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action)
 {
-       int retval = 0;
-       unsigned long lock_flags;
        volatile struct qdio_buffer_element *sbale;
+       struct zfcp_fsf_req *fsf_req;
+       unsigned long lock_flags;
+       int retval = 0;
 
        /* setup new FSF request */
        retval = zfcp_fsf_req_create(erp_action->adapter,
                                     FSF_QTCB_CLOSE_PHYSICAL_PORT,
                                     ZFCP_WAIT_FOR_SBAL | ZFCP_REQ_AUTO_CLEANUP,
                                     erp_action->adapter->pool.fsf_req_erp,
-                                    &lock_flags, &erp_action->fsf_req);
+                                    &lock_flags, &fsf_req);
        if (retval < 0) {
                ZFCP_LOG_INFO("error: Could not create close physical port "
                              "request (adapter %s, port 0x%016Lx)\n",
@@ -2724,8 +2769,7 @@ zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action)
                goto out;
        }
 
-       sbale = zfcp_qdio_sbale_req(erp_action->fsf_req,
-                                   erp_action->fsf_req->sbal_curr, 0);
+       sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
        sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
        sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
@@ -2733,20 +2777,19 @@ zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action)
        atomic_set_mask(ZFCP_STATUS_PORT_PHYS_CLOSING,
                        &erp_action->port->status);
        /* save a pointer to this port */
-       erp_action->fsf_req->data = (unsigned long) erp_action->port;
-       /* port to be closed */
-       erp_action->fsf_req->qtcb->header.port_handle =
-           erp_action->port->handle;
-       erp_action->fsf_req->erp_action = erp_action;
-
-       /* start QDIO request for this FSF request */
-       retval = zfcp_fsf_req_send(erp_action->fsf_req, &erp_action->timer);
+       fsf_req->data = (unsigned long) erp_action->port;
+       fsf_req->qtcb->header.port_handle = erp_action->port->handle;
+       fsf_req->erp_action = erp_action;
+       erp_action->fsf_req = fsf_req;
+
+       zfcp_erp_start_timer(fsf_req);
+       retval = zfcp_fsf_req_send(fsf_req);
        if (retval) {
                ZFCP_LOG_INFO("error: Could not send close physical port "
                              "request (adapter %s, port 0x%016Lx)\n",
                              zfcp_get_busid_by_adapter(erp_action->adapter),
                              erp_action->port->wwpn);
-               zfcp_fsf_req_free(erp_action->fsf_req);
+               zfcp_fsf_req_free(fsf_req);
                erp_action->fsf_req = NULL;
                goto out;
        }
@@ -2911,6 +2954,7 @@ int
 zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action)
 {
        volatile struct qdio_buffer_element *sbale;
+       struct zfcp_fsf_req *fsf_req;
        unsigned long lock_flags;
        int retval = 0;
 
@@ -2919,7 +2963,7 @@ zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action)
                                     FSF_QTCB_OPEN_LUN,
                                     ZFCP_WAIT_FOR_SBAL | ZFCP_REQ_AUTO_CLEANUP,
                                     erp_action->adapter->pool.fsf_req_erp,
-                                    &lock_flags, &(erp_action->fsf_req));
+                                    &lock_flags, &fsf_req);
        if (retval < 0) {
                ZFCP_LOG_INFO("error: Could not create open unit request for "
                              "unit 0x%016Lx on port 0x%016Lx on adapter %s.\n",
@@ -2929,24 +2973,22 @@ zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action)
                goto out;
        }
 
-       sbale = zfcp_qdio_sbale_req(erp_action->fsf_req,
-                                    erp_action->fsf_req->sbal_curr, 0);
+       sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
         sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
         sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
-       erp_action->fsf_req->qtcb->header.port_handle =
-               erp_action->port->handle;
-       erp_action->fsf_req->qtcb->bottom.support.fcp_lun =
-               erp_action->unit->fcp_lun;
+       fsf_req->qtcb->header.port_handle = erp_action->port->handle;
+       fsf_req->qtcb->bottom.support.fcp_lun = erp_action->unit->fcp_lun;
        if (!(erp_action->adapter->connection_features & FSF_FEATURE_NPIV_MODE))
-       erp_action->fsf_req->qtcb->bottom.support.option =
-               FSF_OPEN_LUN_SUPPRESS_BOXING;
+               fsf_req->qtcb->bottom.support.option =
+                       FSF_OPEN_LUN_SUPPRESS_BOXING;
        atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &erp_action->unit->status);
-       erp_action->fsf_req->data = (unsigned long) erp_action->unit;
-       erp_action->fsf_req->erp_action = erp_action;
+       fsf_req->data = (unsigned long) erp_action->unit;
+       fsf_req->erp_action = erp_action;
+       erp_action->fsf_req = fsf_req;
 
-       /* start QDIO request for this FSF request */
-       retval = zfcp_fsf_req_send(erp_action->fsf_req, &erp_action->timer);
+       zfcp_erp_start_timer(fsf_req);
+       retval = zfcp_fsf_req_send(erp_action->fsf_req);
        if (retval) {
                ZFCP_LOG_INFO("error: Could not send an open unit request "
                              "on the adapter %s, port 0x%016Lx for "
@@ -2954,7 +2996,7 @@ zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action)
                              zfcp_get_busid_by_adapter(erp_action->adapter),
                              erp_action->port->wwpn,
                              erp_action->unit->fcp_lun);
-               zfcp_fsf_req_free(erp_action->fsf_req);
+               zfcp_fsf_req_free(fsf_req);
                erp_action->fsf_req = NULL;
                goto out;
        }
@@ -3247,6 +3289,7 @@ int
 zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action)
 {
        volatile struct qdio_buffer_element *sbale;
+       struct zfcp_fsf_req *fsf_req;
        unsigned long lock_flags;
        int retval = 0;
 
@@ -3255,7 +3298,7 @@ zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action)
                                     FSF_QTCB_CLOSE_LUN,
                                     ZFCP_WAIT_FOR_SBAL | ZFCP_REQ_AUTO_CLEANUP,
                                     erp_action->adapter->pool.fsf_req_erp,
-                                    &lock_flags, &(erp_action->fsf_req));
+                                    &lock_flags, &fsf_req);
        if (retval < 0) {
                ZFCP_LOG_INFO("error: Could not create close unit request for "
                              "unit 0x%016Lx on port 0x%016Lx on adapter %s.\n",
@@ -3265,27 +3308,26 @@ zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action)
                goto out;
        }
 
-       sbale = zfcp_qdio_sbale_req(erp_action->fsf_req,
-                                    erp_action->fsf_req->sbal_curr, 0);
+       sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
         sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
         sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
-       erp_action->fsf_req->qtcb->header.port_handle =
-           erp_action->port->handle;
-       erp_action->fsf_req->qtcb->header.lun_handle = erp_action->unit->handle;
+       fsf_req->qtcb->header.port_handle = erp_action->port->handle;
+       fsf_req->qtcb->header.lun_handle = erp_action->unit->handle;
        atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING, &erp_action->unit->status);
-       erp_action->fsf_req->data = (unsigned long) erp_action->unit;
-       erp_action->fsf_req->erp_action = erp_action;
+       fsf_req->data = (unsigned long) erp_action->unit;
+       fsf_req->erp_action = erp_action;
+       erp_action->fsf_req = fsf_req;
 
-       /* start QDIO request for this FSF request */
-       retval = zfcp_fsf_req_send(erp_action->fsf_req, &erp_action->timer);
+       zfcp_erp_start_timer(fsf_req);
+       retval = zfcp_fsf_req_send(erp_action->fsf_req);
        if (retval) {
                ZFCP_LOG_INFO("error: Could not send a close unit request for "
                              "unit 0x%016Lx on port 0x%016Lx onadapter %s.\n",
                              erp_action->unit->fcp_lun,
                              erp_action->port->wwpn,
                              zfcp_get_busid_by_adapter(erp_action->adapter));
-               zfcp_fsf_req_free(erp_action->fsf_req);
+               zfcp_fsf_req_free(fsf_req);
                erp_action->fsf_req = NULL;
                goto out;
        }
@@ -3438,7 +3480,7 @@ int
 zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
                               struct zfcp_unit *unit,
                               struct scsi_cmnd * scsi_cmnd,
-                              struct timer_list *timer, int req_flags)
+                              int use_timer, int req_flags)
 {
        struct zfcp_fsf_req *fsf_req = NULL;
        struct fcp_cmnd_iu *fcp_cmnd_iu;
@@ -3466,7 +3508,7 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
        fsf_req->unit = unit;
 
        /* associate FSF request with SCSI request (for look up on abort) */
-       scsi_cmnd->host_scribble = (char *) fsf_req;
+       scsi_cmnd->host_scribble = (unsigned char *) fsf_req->req_id;
 
        /* associate SCSI command with FSF request */
        fsf_req->data = (unsigned long) scsi_cmnd;
@@ -3515,7 +3557,7 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
        }
 
        /* set FC service class in QTCB (3 per default) */
-       fsf_req->qtcb->bottom.io.service_class = adapter->fc_service_class;
+       fsf_req->qtcb->bottom.io.service_class = ZFCP_FC_SERVICE_CLASS_DEFAULT;
 
        /* set FCP_LUN in FCP_CMND IU in QTCB */
        fcp_cmnd_iu->fcp_lun = unit->fcp_lun;
@@ -3579,11 +3621,10 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
        ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
                      (char *) scsi_cmnd->cmnd, scsi_cmnd->cmd_len);
 
-       /*
-        * start QDIO request for this FSF request
-        *  covered by an SBALE)
-        */
-       retval = zfcp_fsf_req_send(fsf_req, timer);
+       if (use_timer)
+               zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT);
+
+       retval = zfcp_fsf_req_send(fsf_req);
        if (unlikely(retval < 0)) {
                ZFCP_LOG_INFO("error: Could not send FCP command request "
                              "on adapter %s, port 0x%016Lx, unit 0x%016Lx\n",
@@ -3613,18 +3654,6 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
        return retval;
 }
 
-/*
- * function:    zfcp_fsf_send_fcp_command_task_management
- *
- * purpose:
- *
- * returns:
- *
- * FIXME(design): should be watched by a timeout!!!
- * FIXME(design) shouldn't this be modified to return an int
- *               also...don't know how though
- *
- */
 struct zfcp_fsf_req *
 zfcp_fsf_send_fcp_command_task_management(struct zfcp_adapter *adapter,
                                          struct zfcp_unit *unit,
@@ -3666,7 +3695,7 @@ zfcp_fsf_send_fcp_command_task_management(struct zfcp_adapter *adapter,
        fsf_req->qtcb->header.lun_handle = unit->handle;
        fsf_req->qtcb->header.port_handle = unit->port->handle;
        fsf_req->qtcb->bottom.io.data_direction = FSF_DATADIR_CMND;
-       fsf_req->qtcb->bottom.io.service_class = adapter->fc_service_class;
+       fsf_req->qtcb->bottom.io.service_class = ZFCP_FC_SERVICE_CLASS_DEFAULT;
        fsf_req->qtcb->bottom.io.fcp_cmnd_length =
                sizeof (struct fcp_cmnd_iu) + sizeof (fcp_dl_t);
 
@@ -3680,11 +3709,9 @@ zfcp_fsf_send_fcp_command_task_management(struct zfcp_adapter *adapter,
        fcp_cmnd_iu->fcp_lun = unit->fcp_lun;
        fcp_cmnd_iu->task_management_flags = tm_flags;
 
-       /* start QDIO request for this FSF request */
-       zfcp_fsf_start_scsi_er_timer(adapter);
-       retval = zfcp_fsf_req_send(fsf_req, NULL);
+       zfcp_fsf_start_timer(fsf_req, ZFCP_SCSI_ER_TIMEOUT);
+       retval = zfcp_fsf_req_send(fsf_req);
        if (retval) {
-               del_timer(&adapter->scsi_er_timer);
                ZFCP_LOG_INFO("error: Could not send an FCP-command (task "
                              "management) on adapter %s, port 0x%016Lx for "
                              "unit LUN 0x%016Lx\n",
@@ -3789,18 +3816,10 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
                break;
 
        case FSF_SERVICE_CLASS_NOT_SUPPORTED:
-               if (fsf_req->adapter->fc_service_class <= 3) {
-                       ZFCP_LOG_NORMAL("error: The adapter %s does "
-                                       "not support fibrechannel class %d.\n",
-                                       zfcp_get_busid_by_unit(unit),
-                                       fsf_req->adapter->fc_service_class);
-               } else {
-                       ZFCP_LOG_NORMAL("bug: The fibrechannel class at "
-                                       "adapter %s is invalid. "
-                                       "(debug info %d)\n",
-                                       zfcp_get_busid_by_unit(unit),
-                                       fsf_req->adapter->fc_service_class);
-               }
+               ZFCP_LOG_INFO("error: adapter %s does not support fc "
+                             "class %d.\n",
+                             zfcp_get_busid_by_unit(unit),
+                             ZFCP_FC_SERVICE_CLASS_DEFAULT);
                /* stop operation for this adapter */
                debug_text_exception(fsf_req->adapter->erp_dbf, 0,
                                     "fsf_s_class_nsup");
@@ -4157,11 +4176,11 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req)
        ZFCP_LOG_DEBUG("scpnt->result =0x%x\n", scpnt->result);
 
        if (scpnt->result != 0)
-               zfcp_scsi_dbf_event_result("erro", 3, fsf_req->adapter, scpnt);
+               zfcp_scsi_dbf_event_result("erro", 3, fsf_req->adapter, scpnt, fsf_req);
        else if (scpnt->retries > 0)
-               zfcp_scsi_dbf_event_result("retr", 4, fsf_req->adapter, scpnt);
+               zfcp_scsi_dbf_event_result("retr", 4, fsf_req->adapter, scpnt, fsf_req);
        else
-               zfcp_scsi_dbf_event_result("norm", 6, fsf_req->adapter, scpnt);
+               zfcp_scsi_dbf_event_result("norm", 6, fsf_req->adapter, scpnt, fsf_req);
 
        /* cleanup pointer (need this especially for abort) */
        scpnt->host_scribble = NULL;
@@ -4196,7 +4215,6 @@ zfcp_fsf_send_fcp_command_task_management_handler(struct zfcp_fsf_req *fsf_req)
        char *fcp_rsp_info = zfcp_get_fcp_rsp_info_ptr(fcp_rsp_iu);
        struct zfcp_unit *unit = (struct zfcp_unit *) fsf_req->data;
 
-       del_timer(&fsf_req->adapter->scsi_er_timer);
        if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) {
                fsf_req->status |= ZFCP_STATUS_FSFREQ_TMFUNCFAILED;
                goto skip_fsfstatus;
@@ -4265,7 +4283,6 @@ zfcp_fsf_control_file(struct zfcp_adapter *adapter,
        struct zfcp_fsf_req *fsf_req;
        struct fsf_qtcb_bottom_support *bottom;
        volatile struct qdio_buffer_element *sbale;
-       struct timer_list *timer;
        unsigned long lock_flags;
        int req_flags = 0;
        int direction;
@@ -4297,12 +4314,6 @@ zfcp_fsf_control_file(struct zfcp_adapter *adapter,
                goto out;
        }
 
-       timer = kmalloc(sizeof(struct timer_list), GFP_KERNEL);
-       if (!timer) {
-               retval = -ENOMEM;
-               goto out;
-       }
-
        retval = zfcp_fsf_req_create(adapter, fsf_command, req_flags,
                                     NULL, &lock_flags, &fsf_req);
        if (retval < 0) {
@@ -4337,12 +4348,8 @@ zfcp_fsf_control_file(struct zfcp_adapter *adapter,
        } else
                sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
-       init_timer(timer);
-       timer->function = zfcp_fsf_request_timeout_handler;
-       timer->data = (unsigned long) adapter;
-       timer->expires = ZFCP_FSF_REQUEST_TIMEOUT;
-
-       retval = zfcp_fsf_req_send(fsf_req, timer);
+       zfcp_fsf_start_timer(fsf_req, ZFCP_FSF_REQUEST_TIMEOUT);
+       retval = zfcp_fsf_req_send(fsf_req);
        if (retval < 0) {
                ZFCP_LOG_INFO("initiation of cfdc up/download failed"
                              "(adapter %s)\n",
@@ -4362,15 +4369,12 @@ zfcp_fsf_control_file(struct zfcp_adapter *adapter,
                   fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
 
        *fsf_req_ptr = fsf_req;
-       del_timer_sync(timer);
-       goto free_timer;
+       goto out;
 
  free_fsf_req:
        zfcp_fsf_req_free(fsf_req);
  unlock_queue_lock:
        write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags);
- free_timer:
-       kfree(timer);
  out:
        return retval;
 }
@@ -4558,16 +4562,18 @@ zfcp_fsf_req_sbal_check(unsigned long *flags,
 /*
  * set qtcb pointer in fsf_req and initialize QTCB
  */
-static inline void
+static void
 zfcp_fsf_req_qtcb_init(struct zfcp_fsf_req *fsf_req)
 {
        if (likely(fsf_req->qtcb != NULL)) {
-               fsf_req->qtcb->prefix.req_seq_no = fsf_req->adapter->fsf_req_seq_no;
-               fsf_req->qtcb->prefix.req_id = (unsigned long)fsf_req;
+               fsf_req->qtcb->prefix.req_seq_no =
+                       fsf_req->adapter->fsf_req_seq_no;
+               fsf_req->qtcb->prefix.req_id = fsf_req->req_id;
                fsf_req->qtcb->prefix.ulp_info = ZFCP_ULP_INFO_VERSION;
-               fsf_req->qtcb->prefix.qtcb_type = fsf_qtcb_type[fsf_req->fsf_command];
+               fsf_req->qtcb->prefix.qtcb_type =
+                       fsf_qtcb_type[fsf_req->fsf_command];
                fsf_req->qtcb->prefix.qtcb_version = ZFCP_QTCB_VERSION;
-               fsf_req->qtcb->header.req_handle = (unsigned long)fsf_req;
+               fsf_req->qtcb->header.req_handle = fsf_req->req_id;
                fsf_req->qtcb->header.fsf_command = fsf_req->fsf_command;
        }
 }
@@ -4638,8 +4644,15 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags,
 
        fsf_req->adapter = adapter;
        fsf_req->fsf_command = fsf_cmd;
+       INIT_LIST_HEAD(&fsf_req->list);
+       
+       /* this is serialized (we are holding req_queue-lock of adapter */
+       if (adapter->req_no == 0)
+               adapter->req_no++;
+       fsf_req->req_id = adapter->req_no++;
 
-        zfcp_fsf_req_qtcb_init(fsf_req);
+       init_timer(&fsf_req->timer);
+       zfcp_fsf_req_qtcb_init(fsf_req);
 
        /* initialize waitqueue which may be used to wait on 
           this request completion */
@@ -4677,7 +4690,7 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags,
        sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
 
        /* setup common SBALE fields */
-       sbale[0].addr = fsf_req;
+       sbale[0].addr = (void *) fsf_req->req_id;
        sbale[0].flags |= SBAL_FLAGS0_COMMAND;
        if (likely(fsf_req->qtcb != NULL)) {
                sbale[1].addr = (void *) fsf_req->qtcb;
@@ -4709,15 +4722,14 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags,
  * returns:    0 - request transfer succesfully started
  *             !0 - start of request transfer failed
  */
-static int
-zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer)
+static int zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req)
 {
        struct zfcp_adapter *adapter;
        struct zfcp_qdio_queue *req_queue;
        volatile struct qdio_buffer_element *sbale;
        int inc_seq_no;
        int new_distance_from_int;
-       unsigned long flags;
+       u64 dbg_tmp[2];
        int retval = 0;
 
        adapter = fsf_req->adapter;
@@ -4731,19 +4743,13 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer)
        ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE, (char *) sbale[1].addr,
                      sbale[1].length);
 
-       /* put allocated FSF request at list tail */
-       spin_lock_irqsave(&adapter->fsf_req_list_lock, flags);
-       list_add_tail(&fsf_req->list, &adapter->fsf_req_list_head);
-       spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
+       /* put allocated FSF request into hash table */
+       spin_lock(&adapter->req_list_lock);
+       zfcp_reqlist_add(adapter, fsf_req);
+       spin_unlock(&adapter->req_list_lock);
 
        inc_seq_no = (fsf_req->qtcb != NULL);
 
-       /* figure out expiration time of timeout and start timeout */
-       if (unlikely(timer)) {
-               timer->expires += jiffies;
-               add_timer(timer);
-       }
-
        ZFCP_LOG_TRACE("request queue of adapter %s: "
                       "next free SBAL is %i, %i free SBALs\n",
                       zfcp_get_busid_by_adapter(adapter),
@@ -4773,31 +4779,25 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer)
                         QDIO_FLAG_SYNC_OUTPUT,
                         0, fsf_req->sbal_first, fsf_req->sbal_number, NULL);
 
+       dbg_tmp[0] = (unsigned long) sbale[0].addr;
+       dbg_tmp[1] = (u64) retval;
+       debug_event(adapter->erp_dbf, 4, (void *) dbg_tmp, 16);
+
        if (unlikely(retval)) {
                /* Queues are down..... */
                retval = -EIO;
-               /*
-                * FIXME(potential race):
-                * timer might be expired (absolutely unlikely)
-                */
-               if (timer)
-                       del_timer(timer);
-               spin_lock_irqsave(&adapter->fsf_req_list_lock, flags);
-               list_del(&fsf_req->list);
-               spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
-               /*
-                * adjust the number of free SBALs in request queue as well as
-                * position of first one
-                */
+               del_timer(&fsf_req->timer);
+               spin_lock(&adapter->req_list_lock);
+               zfcp_reqlist_remove(adapter, fsf_req->req_id);
+               spin_unlock(&adapter->req_list_lock);
+               /* undo changes in request queue made for this request */
                zfcp_qdio_zero_sbals(req_queue->buffer,
                                     fsf_req->sbal_first, fsf_req->sbal_number);
                atomic_add(fsf_req->sbal_number, &req_queue->free_count);
-               req_queue->free_index -= fsf_req->sbal_number;   /* increase */
+               req_queue->free_index -= fsf_req->sbal_number;
                req_queue->free_index += QDIO_MAX_BUFFERS_PER_Q;
                req_queue->free_index %= QDIO_MAX_BUFFERS_PER_Q; /* wrap */
-               ZFCP_LOG_DEBUG
-                       ("error: do_QDIO failed. Buffers could not be enqueued "
-                        "to request queue.\n");
+               zfcp_erp_adapter_reopen(adapter, 0);
        } else {
                req_queue->distance_from_int = new_distance_from_int;
                /*
@@ -4813,7 +4813,7 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer)
                        adapter->fsf_req_seq_no++;
 
                /* count FSF requests pending */
-               atomic_inc(&adapter->fsf_reqs_active);
+               atomic_inc(&adapter->reqs_active);
        }
        return retval;
 }