]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/s390/scsi/zfcp_qdio.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
[linux-2.6-omap-h63xx.git] / drivers / s390 / scsi / zfcp_qdio.c
index 33e0a206a0a44019ffc33a44f7a166960f873741..e0a215309df064799efe0638d0dff04e8c37de4b 100644 (file)
@@ -11,9 +11,6 @@
 
 #include "zfcp_ext.h"
 
-/* FIXME(tune): free space should be one max. SBAL chain plus what? */
-#define ZFCP_QDIO_PCI_INTERVAL (QDIO_MAX_BUFFERS_PER_Q \
-                               - (FSF_MAX_SBALS_PER_REQ + 4))
 #define QBUFF_PER_PAGE         (PAGE_SIZE / sizeof(struct qdio_buffer))
 
 static int zfcp_qdio_buffers_enqueue(struct qdio_buffer **sbal)
@@ -58,7 +55,7 @@ void zfcp_qdio_free(struct zfcp_adapter *adapter)
        }
 }
 
-static void zfcp_qdio_handler_error(struct zfcp_adapter *adapter, u8 id)
+static void zfcp_qdio_handler_error(struct zfcp_adapter *adapter, char *id)
 {
        dev_warn(&adapter->ccw_device->dev, "A QDIO problem occurred\n");
 
@@ -77,6 +74,23 @@ static void zfcp_qdio_zero_sbals(struct qdio_buffer *sbal[], int first, int cnt)
        }
 }
 
+/* this needs to be called prior to updating the queue fill level */
+static void zfcp_qdio_account(struct zfcp_adapter *adapter)
+{
+       ktime_t now;
+       s64 span;
+       int free, used;
+
+       spin_lock(&adapter->qdio_stat_lock);
+       now = ktime_get();
+       span = ktime_us_delta(now, adapter->req_q_time);
+       free = max(0, atomic_read(&adapter->req_q.count));
+       used = QDIO_MAX_BUFFERS_PER_Q - free;
+       adapter->req_q_util += used * span;
+       adapter->req_q_time = now;
+       spin_unlock(&adapter->qdio_stat_lock);
+}
+
 static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err,
                              int queue_no, int first, int count,
                              unsigned long parm)
@@ -86,13 +100,14 @@ static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err,
 
        if (unlikely(qdio_err)) {
                zfcp_hba_dbf_event_qdio(adapter, qdio_err, first, count);
-               zfcp_qdio_handler_error(adapter, 140);
+               zfcp_qdio_handler_error(adapter, "qdireq1");
                return;
        }
 
        /* cleanup all SBALs being program-owned now */
        zfcp_qdio_zero_sbals(queue->sbal, first, count);
 
+       zfcp_qdio_account(adapter);
        atomic_add(count, &queue->count);
        wake_up(&adapter->request_wq);
 }
@@ -154,7 +169,7 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
 
        if (unlikely(qdio_err)) {
                zfcp_hba_dbf_event_qdio(adapter, qdio_err, first, count);
-               zfcp_qdio_handler_error(adapter, 147);
+               zfcp_qdio_handler_error(adapter, "qdires1");
                return;
        }
 
@@ -346,21 +361,12 @@ int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req)
        struct zfcp_qdio_queue *req_q = &adapter->req_q;
        int first = fsf_req->sbal_first;
        int count = fsf_req->sbal_number;
-       int retval, pci, pci_batch;
-       struct qdio_buffer_element *sbale;
+       int retval;
+       unsigned int qdio_flags = QDIO_FLAG_SYNC_OUTPUT;
 
-       /* acknowledgements for transferred buffers */
-       pci_batch = adapter->req_q_pci_batch + count;
-       if (unlikely(pci_batch >= ZFCP_QDIO_PCI_INTERVAL)) {
-               pci_batch %= ZFCP_QDIO_PCI_INTERVAL;
-               pci = first + count - (pci_batch + 1);
-               pci %= QDIO_MAX_BUFFERS_PER_Q;
-               sbale = zfcp_qdio_sbale(req_q, pci, 0);
-               sbale->flags |= SBAL_FLAGS0_PCI;
-       }
+       zfcp_qdio_account(adapter);
 
-       retval = do_QDIO(adapter->ccw_device, QDIO_FLAG_SYNC_OUTPUT, 0, first,
-                        count);
+       retval = do_QDIO(adapter->ccw_device, qdio_flags, 0, first, count);
        if (unlikely(retval)) {
                zfcp_qdio_zero_sbals(req_q->sbal, first, count);
                return retval;
@@ -370,7 +376,6 @@ int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req)
        atomic_sub(count, &req_q->count);
        req_q->first += count;
        req_q->first %= QDIO_MAX_BUFFERS_PER_Q;
-       adapter->req_q_pci_batch = pci_batch;
        return 0;
 }
 
@@ -441,7 +446,6 @@ void zfcp_qdio_close(struct zfcp_adapter *adapter)
        }
        req_q->first = 0;
        atomic_set(&req_q->count, 0);
-       adapter->req_q_pci_batch = 0;
        adapter->resp_q.first = 0;
        atomic_set(&adapter->resp_q.count, 0);
 }
@@ -479,7 +483,6 @@ int zfcp_qdio_open(struct zfcp_adapter *adapter)
        /* set index of first avalable SBALS / number of available SBALS */
        adapter->req_q.first = 0;
        atomic_set(&adapter->req_q.count, QDIO_MAX_BUFFERS_PER_Q);
-       adapter->req_q_pci_batch = 0;
 
        return 0;