[SCSI] zfcp: improve management of request IDs

Improve request handling. Use hash table to manage request IDs.

Signed-off-by: Volker Sameske <sameske@de.ibm.com>
Signed-off-by: Andreas Herrmann <aherrman@de.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index 49ea5ad..dbd9f48 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -282,6 +282,37 @@
 	return;
 }
 
+/**
+ * zfcp_qdio_reqid_check - checks for valid reqids or unsolicited status
+ */
+static int zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, 
+				 unsigned long req_id)
+{
+	struct zfcp_fsf_req *fsf_req;
+	unsigned long flags;
+
+	debug_long_event(adapter->erp_dbf, 4, req_id);
+
+	spin_lock_irqsave(&adapter->req_list_lock, flags);
+	fsf_req = zfcp_reqlist_ismember(adapter, req_id);
+
+	if (!fsf_req) {
+		spin_unlock_irqrestore(&adapter->req_list_lock, flags);
+		ZFCP_LOG_NORMAL("error: unknown request id (%ld).\n", req_id);
+		zfcp_erp_adapter_reopen(adapter, 0);
+		return -EINVAL;
+	}
+
+	zfcp_reqlist_remove(adapter, req_id);
+	atomic_dec(&adapter->reqs_active);
+	spin_unlock_irqrestore(&adapter->req_list_lock, flags);
+
+	/* finish the FSF request */
+	zfcp_fsf_req_complete(fsf_req);
+
+	return 0;
+}
+
 /*
  * function:   	zfcp_qdio_response_handler
  *
@@ -344,7 +375,7 @@
 			/* look for QDIO request identifiers in SB */
 			buffere = &buffer->element[buffere_index];
 			retval = zfcp_qdio_reqid_check(adapter,
-						       (void *) buffere->addr);
+					(unsigned long) buffere->addr);
 
 			if (retval) {
 				ZFCP_LOG_NORMAL("bug: unexpected inbound "
@@ -415,52 +446,6 @@
 	return;
 }
 
-/*
- * function:	zfcp_qdio_reqid_check
- *
- * purpose:	checks for valid reqids or unsolicited status
- *
- * returns:	0 - valid request id or unsolicited status
- *		!0 - otherwise
- */
-int
-zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, void *sbale_addr)
-{
-	struct zfcp_fsf_req *fsf_req;
-	unsigned long flags;
-
-	/* invalid (per convention used in this driver) */
-	if (unlikely(!sbale_addr)) {
-		ZFCP_LOG_NORMAL("bug: invalid reqid\n");
-		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_irqsave(&adapter->fsf_req_list_lock, flags);
-	if (list_empty(&adapter->fsf_req_list_head)) {
-		spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
-		return 0;
-	}
-	list_del(&fsf_req->list);
-	atomic_dec(&adapter->fsf_reqs_active);
-	spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
-
-	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);
-		return -EINVAL;
-	}
-
-	/* finish the FSF request */
-	zfcp_fsf_req_complete(fsf_req);
-
-	return 0;
-}
-
 /**
  * zfcp_qdio_sbale_get - return pointer to SBALE of qdio_queue
  * @queue: queue from which SBALE should be returned