Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / s390 / scsi / zfcp_qdio.c
index 06e862d..1c32751 100644 (file)
@@ -29,8 +29,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#define ZFCP_QDIO_C_REVISION "$Revision: 1.20 $"
-
 #include "zfcp_ext.h"
 
 static inline void zfcp_qdio_sbal_limit(struct zfcp_fsf_req *, int);
@@ -54,8 +52,7 @@ static inline int zfcp_qdio_sbals_from_buffer
 static qdio_handler_t zfcp_qdio_request_handler;
 static qdio_handler_t zfcp_qdio_response_handler;
 static int zfcp_qdio_handler_error_check(struct zfcp_adapter *,
-                                        unsigned int,
-                                        unsigned int, unsigned int);
+       unsigned int, unsigned int, unsigned int, int, int);
 
 #define ZFCP_LOG_AREA                   ZFCP_LOG_AREA_QDIO
 
@@ -214,70 +211,23 @@ zfcp_qdio_allocate(struct zfcp_adapter *adapter)
  *
  */
 static inline int
-zfcp_qdio_handler_error_check(struct zfcp_adapter *adapter,
-                             unsigned int status,
-                             unsigned int qdio_error, unsigned int siga_error)
+zfcp_qdio_handler_error_check(struct zfcp_adapter *adapter, unsigned int status,
+                             unsigned int qdio_error, unsigned int siga_error,
+                             int first_element, int elements_processed)
 {
        int retval = 0;
 
-       if (ZFCP_LOG_CHECK(ZFCP_LOG_LEVEL_TRACE)) {
-               if (status & QDIO_STATUS_INBOUND_INT) {
-                       ZFCP_LOG_TRACE("status is"
-                                      " QDIO_STATUS_INBOUND_INT \n");
-               }
-               if (status & QDIO_STATUS_OUTBOUND_INT) {
-                       ZFCP_LOG_TRACE("status is"
-                                      " QDIO_STATUS_OUTBOUND_INT \n");
-               }
-       }                       // if (ZFCP_LOG_CHECK(ZFCP_LOG_LEVEL_TRACE))
        if (unlikely(status & QDIO_STATUS_LOOK_FOR_ERROR)) {
                retval = -EIO;
 
-               ZFCP_LOG_FLAGS(1, "QDIO_STATUS_LOOK_FOR_ERROR \n");
-
                ZFCP_LOG_INFO("QDIO problem occurred (status=0x%x, "
                              "qdio_error=0x%x, siga_error=0x%x)\n",
                              status, qdio_error, siga_error);
 
-               if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION) {
-                       ZFCP_LOG_FLAGS(2,
-                                      "QDIO_STATUS_ACTIVATE_CHECK_CONDITION\n");
-               }
-               if (status & QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR) {
-                       ZFCP_LOG_FLAGS(2,
-                                      "QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR\n");
-               }
-               if (status & QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR) {
-                       ZFCP_LOG_FLAGS(2,
-                                      "QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR\n");
-               }
-
-               if (siga_error & QDIO_SIGA_ERROR_ACCESS_EXCEPTION) {
-                       ZFCP_LOG_FLAGS(2, "QDIO_SIGA_ERROR_ACCESS_EXCEPTION\n");
-               }
-
-               if (siga_error & QDIO_SIGA_ERROR_B_BIT_SET) {
-                       ZFCP_LOG_FLAGS(2, "QDIO_SIGA_ERROR_B_BIT_SET\n");
-               }
-
-               switch (qdio_error) {
-               case 0:
-                       ZFCP_LOG_FLAGS(3, "QDIO_OK");
-                       break;
-               case SLSB_P_INPUT_ERROR:
-                       ZFCP_LOG_FLAGS(1, "SLSB_P_INPUT_ERROR\n");
-                       break;
-               case SLSB_P_OUTPUT_ERROR:
-                       ZFCP_LOG_FLAGS(1, "SLSB_P_OUTPUT_ERROR\n");
-                       break;
-               default:
-                       ZFCP_LOG_NORMAL("bug: unknown QDIO error 0x%x\n",
-                                       qdio_error);
-                       break;
-               }
-               /* Restarting IO on the failed adapter from scratch */
-               debug_text_event(adapter->erp_dbf, 1, "qdio_err");
+               zfcp_hba_dbf_event_qdio(adapter, status, qdio_error, siga_error,
+                               first_element, elements_processed);
                /*
+                       * Restarting IO on the failed adapter from scratch.
                 * Since we have been using this adapter, it is save to assume
                 * that it is not failed but recoverable. The card seems to
                 * report link-up events by self-initiated queue shutdown.
@@ -320,7 +270,8 @@ zfcp_qdio_request_handler(struct ccw_device *ccw_device,
                       first_element, elements_processed);
 
        if (unlikely(zfcp_qdio_handler_error_check(adapter, status, qdio_error,
-                                                  siga_error)))
+                                                  siga_error, first_element,
+                                                  elements_processed)))
                goto out;
        /*
         * we stored address of struct zfcp_adapter  data structure
@@ -372,7 +323,8 @@ zfcp_qdio_response_handler(struct ccw_device *ccw_device,
        queue = &adapter->response_queue;
 
        if (unlikely(zfcp_qdio_handler_error_check(adapter, status, qdio_error,
-                                                  siga_error)))
+                                                  siga_error, first_element,
+                                                  elements_processed)))
                goto out;
 
        /*
@@ -484,37 +436,37 @@ int
 zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, void *sbale_addr)
 {
        struct zfcp_fsf_req *fsf_req;
-       int retval = 0;
 
        /* invalid (per convention used in this driver) */
        if (unlikely(!sbale_addr)) {
                ZFCP_LOG_NORMAL("bug: invalid reqid\n");
-               retval = -EINVAL;
-               goto out;
+               return -EINVAL;
        }
 
        /* valid request id and thus (hopefully :) valid fsf_req address */
        fsf_req = (struct zfcp_fsf_req *) sbale_addr;
 
+       /* serialize with zfcp_fsf_req_dismiss_all */
+       spin_lock(&adapter->fsf_req_list_lock);
+       if (list_empty(&adapter->fsf_req_list_head)) {
+               spin_unlock(&adapter->fsf_req_list_lock);
+               return 0;
+       }
+       list_del(&fsf_req->list);
+       atomic_dec(&adapter->fsf_reqs_active);
+       spin_unlock(&adapter->fsf_req_list_lock);
+       
        if (unlikely(adapter != fsf_req->adapter)) {
                ZFCP_LOG_NORMAL("bug: invalid reqid (fsf_req=%p, "
                                "fsf_req->adapter=%p, adapter=%p)\n",
                                fsf_req, fsf_req->adapter, adapter);
-               retval = -EINVAL;
-               goto out;
-       }
-
-       ZFCP_LOG_TRACE("fsf_req at %p, QTCB at %p\n", fsf_req, fsf_req->qtcb);
-       if (likely(fsf_req->qtcb)) {
-               ZFCP_LOG_TRACE("hex dump of QTCB:\n");
-               ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE, (char *) fsf_req->qtcb,
-                             sizeof(struct fsf_qtcb));
+               return -EINVAL;
        }
 
        /* finish the FSF request */
        zfcp_fsf_req_complete(fsf_req);
- out:
-       return retval;
+
+       return 0;
 }
 
 /**