[SCSI] zfcp: fix layering oddities between zfcp_fsf and zfcp_qdio
authorSwen Schillig <swen@vnet.ibm.com>
Tue, 18 Aug 2009 13:43:13 +0000 (15:43 +0200)
committerJames Bottomley <James.Bottomley@suse.de>
Sat, 5 Sep 2009 13:49:16 +0000 (08:49 -0500)
There is no need for the QDIO layer to have knowledge or do things
wich are done better by the FSF layer and vice versa.  Straighten a
few things to improve vividness.

Signed-off-by: Swen Schillig <swen@vnet.ibm.com>
Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
drivers/s390/scsi/zfcp_ext.h
drivers/s390/scsi/zfcp_fsf.c
drivers/s390/scsi/zfcp_qdio.c

index 1a66695f11a254f982895ff4dd4cefad77fa3b62..6a3727bdb38647f6bd3024de9fe7f6e7591a509b 100644 (file)
@@ -133,11 +133,11 @@ extern int zfcp_fsf_send_ct(struct zfcp_send_ct *, mempool_t *,
 extern int zfcp_fsf_send_els(struct zfcp_send_els *);
 extern int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *,
                                          struct scsi_cmnd *);
-extern void zfcp_fsf_req_complete(struct zfcp_fsf_req *);
 extern void zfcp_fsf_req_free(struct zfcp_fsf_req *);
 extern struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *, u8);
 extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long,
                                                       struct zfcp_unit *);
+extern void zfcp_fsf_reqid_check(struct zfcp_adapter *, int);
 
 /* zfcp_qdio.c */
 extern int zfcp_qdio_allocate(struct zfcp_adapter *);
index c023db864dc58532f2e8fdb29aaf9c7802cc5921..7ca2995aaf6858c84a8a5e4c95e674d96082b426 100644 (file)
@@ -122,35 +122,6 @@ void zfcp_fsf_req_free(struct zfcp_fsf_req *req)
        }
 }
 
-/**
- * zfcp_fsf_req_dismiss_all - dismiss all fsf requests
- * @adapter: pointer to struct zfcp_adapter
- *
- * Never ever call this without shutting down the adapter first.
- * Otherwise the adapter would continue using and corrupting s390 storage.
- * Included BUG_ON() call to ensure this is done.
- * ERP is supposed to be the only user of this function.
- */
-void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
-{
-       struct zfcp_fsf_req *req, *tmp;
-       unsigned long flags;
-       LIST_HEAD(remove_queue);
-       unsigned int i;
-
-       BUG_ON(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP);
-       spin_lock_irqsave(&adapter->req_list_lock, flags);
-       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);
-
-       list_for_each_entry_safe(req, tmp, &remove_queue, list) {
-               list_del(&req->list);
-               req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
-               zfcp_fsf_req_complete(req);
-       }
-}
-
 static void zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *req)
 {
        struct fsf_status_read_buffer *sr_buf = req->data;
@@ -459,7 +430,7 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req)
  * is called to process the completion status and trigger further
  * events related to the FSF request.
  */
-void zfcp_fsf_req_complete(struct zfcp_fsf_req *req)
+static void zfcp_fsf_req_complete(struct zfcp_fsf_req *req)
 {
        if (unlikely(req->fsf_command == FSF_QTCB_UNSOLICITED_STATUS)) {
                zfcp_fsf_status_read_handler(req);
@@ -492,6 +463,35 @@ void zfcp_fsf_req_complete(struct zfcp_fsf_req *req)
                wake_up(&req->completion_wq);
 }
 
+/**
+ * zfcp_fsf_req_dismiss_all - dismiss all fsf requests
+ * @adapter: pointer to struct zfcp_adapter
+ *
+ * Never ever call this without shutting down the adapter first.
+ * Otherwise the adapter would continue using and corrupting s390 storage.
+ * Included BUG_ON() call to ensure this is done.
+ * ERP is supposed to be the only user of this function.
+ */
+void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
+{
+       struct zfcp_fsf_req *req, *tmp;
+       unsigned long flags;
+       LIST_HEAD(remove_queue);
+       unsigned int i;
+
+       BUG_ON(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP);
+       spin_lock_irqsave(&adapter->req_list_lock, flags);
+       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);
+
+       list_for_each_entry_safe(req, tmp, &remove_queue, list) {
+               list_del(&req->list);
+               req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
+               zfcp_fsf_req_complete(req);
+       }
+}
+
 static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req)
 {
        struct fsf_qtcb_bottom_config *bottom;
@@ -2578,3 +2578,43 @@ out:
        }
        return ERR_PTR(retval);
 }
+
+/**
+ * zfcp_fsf_reqid_check - validate req_id contained in SBAL returned by QDIO
+ * @adapter: pointer to struct zfcp_adapter
+ * @sbal_idx: response queue index of SBAL to be processed
+ */
+void zfcp_fsf_reqid_check(struct zfcp_adapter *adapter, int sbal_idx)
+{
+       struct qdio_buffer *sbal = adapter->resp_q.sbal[sbal_idx];
+       struct qdio_buffer_element *sbale;
+       struct zfcp_fsf_req *fsf_req;
+       unsigned long flags, req_id;
+       int idx;
+
+       for (idx = 0; idx < QDIO_MAX_ELEMENTS_PER_BUFFER; idx++) {
+
+               sbale = &sbal->element[idx];
+               req_id = (unsigned long) sbale->addr;
+               spin_lock_irqsave(&adapter->req_list_lock, flags);
+               fsf_req = zfcp_reqlist_find(adapter, req_id);
+
+               if (!fsf_req)
+                       /*
+                        * Unknown request means that we have potentially memory
+                        * corruption and must stop the machine immediately.
+                        */
+                       panic("error: unknown req_id (%lx) on adapter %s.\n",
+                             req_id, dev_name(&adapter->ccw_device->dev));
+
+               list_del(&fsf_req->list);
+               spin_unlock_irqrestore(&adapter->req_list_lock, flags);
+
+               fsf_req->sbal_response = sbal_idx;
+               fsf_req->qdio_inb_usage = atomic_read(&adapter->resp_q.count);
+               zfcp_fsf_req_complete(fsf_req);
+
+               if (likely(sbale->flags & SBAL_FLAGS_LAST_ENTRY))
+                       break;
+       }
+}
index e0a215309df064799efe0638d0dff04e8c37de4b..2e9b3a9cebd99966500c807de66057f2d542e3c3 100644 (file)
@@ -112,31 +112,6 @@ static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err,
        wake_up(&adapter->request_wq);
 }
 
-static void zfcp_qdio_reqid_check(struct zfcp_adapter *adapter,
-                                 unsigned long req_id, int sbal_idx)
-{
-       struct zfcp_fsf_req *fsf_req;
-       unsigned long flags;
-
-       spin_lock_irqsave(&adapter->req_list_lock, flags);
-       fsf_req = zfcp_reqlist_find(adapter, req_id);
-
-       if (!fsf_req)
-               /*
-                * Unknown request means that we have potentially memory
-                * corruption and must stop the machine immediatly.
-                */
-               panic("error: unknown request id (%lx) on adapter %s.\n",
-                     req_id, dev_name(&adapter->ccw_device->dev));
-
-       zfcp_reqlist_remove(adapter, fsf_req);
-       spin_unlock_irqrestore(&adapter->req_list_lock, flags);
-
-       fsf_req->sbal_response = sbal_idx;
-       fsf_req->qdio_inb_usage = atomic_read(&adapter->resp_q.count);
-       zfcp_fsf_req_complete(fsf_req);
-}
-
 static void zfcp_qdio_resp_put_back(struct zfcp_adapter *adapter, int processed)
 {
        struct zfcp_qdio_queue *queue = &adapter->resp_q;
@@ -163,9 +138,7 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
                               unsigned long parm)
 {
        struct zfcp_adapter *adapter = (struct zfcp_adapter *) parm;
-       struct zfcp_qdio_queue *queue = &adapter->resp_q;
-       struct qdio_buffer_element *sbale;
-       int sbal_idx, sbale_idx, sbal_no;
+       int sbal_idx, sbal_no;
 
        if (unlikely(qdio_err)) {
                zfcp_hba_dbf_event_qdio(adapter, qdio_err, first, count);
@@ -179,22 +152,8 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
         */
        for (sbal_no = 0; sbal_no < count; sbal_no++) {
                sbal_idx = (first + sbal_no) % QDIO_MAX_BUFFERS_PER_Q;
-
                /* go through all SBALEs of SBAL */
-               for (sbale_idx = 0; sbale_idx < QDIO_MAX_ELEMENTS_PER_BUFFER;
-                    sbale_idx++) {
-                       sbale = zfcp_qdio_sbale(queue, sbal_idx, sbale_idx);
-                       zfcp_qdio_reqid_check(adapter,
-                                             (unsigned long) sbale->addr,
-                                             sbal_idx);
-                       if (likely(sbale->flags & SBAL_FLAGS_LAST_ENTRY))
-                               break;
-               };
-
-               if (unlikely(!(sbale->flags & SBAL_FLAGS_LAST_ENTRY)))
-                       dev_warn(&adapter->ccw_device->dev,
-                                "A QDIO protocol error occurred, "
-                                "operations continue\n");
+               zfcp_fsf_reqid_check(adapter, sbal_idx);
        }
 
        /*