aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_qdio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/scsi/zfcp_qdio.c')
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c47
1 files changed, 25 insertions, 22 deletions
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index 33e0a206a0a4..e0a215309df0 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -11,9 +11,6 @@
11 11
12#include "zfcp_ext.h" 12#include "zfcp_ext.h"
13 13
14/* FIXME(tune): free space should be one max. SBAL chain plus what? */
15#define ZFCP_QDIO_PCI_INTERVAL (QDIO_MAX_BUFFERS_PER_Q \
16 - (FSF_MAX_SBALS_PER_REQ + 4))
17#define QBUFF_PER_PAGE (PAGE_SIZE / sizeof(struct qdio_buffer)) 14#define QBUFF_PER_PAGE (PAGE_SIZE / sizeof(struct qdio_buffer))
18 15
19static int zfcp_qdio_buffers_enqueue(struct qdio_buffer **sbal) 16static int zfcp_qdio_buffers_enqueue(struct qdio_buffer **sbal)
@@ -58,7 +55,7 @@ void zfcp_qdio_free(struct zfcp_adapter *adapter)
58 } 55 }
59} 56}
60 57
61static void zfcp_qdio_handler_error(struct zfcp_adapter *adapter, u8 id) 58static void zfcp_qdio_handler_error(struct zfcp_adapter *adapter, char *id)
62{ 59{
63 dev_warn(&adapter->ccw_device->dev, "A QDIO problem occurred\n"); 60 dev_warn(&adapter->ccw_device->dev, "A QDIO problem occurred\n");
64 61
@@ -77,6 +74,23 @@ static void zfcp_qdio_zero_sbals(struct qdio_buffer *sbal[], int first, int cnt)
77 } 74 }
78} 75}
79 76
77/* this needs to be called prior to updating the queue fill level */
78static void zfcp_qdio_account(struct zfcp_adapter *adapter)
79{
80 ktime_t now;
81 s64 span;
82 int free, used;
83
84 spin_lock(&adapter->qdio_stat_lock);
85 now = ktime_get();
86 span = ktime_us_delta(now, adapter->req_q_time);
87 free = max(0, atomic_read(&adapter->req_q.count));
88 used = QDIO_MAX_BUFFERS_PER_Q - free;
89 adapter->req_q_util += used * span;
90 adapter->req_q_time = now;
91 spin_unlock(&adapter->qdio_stat_lock);
92}
93
80static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err, 94static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err,
81 int queue_no, int first, int count, 95 int queue_no, int first, int count,
82 unsigned long parm) 96 unsigned long parm)
@@ -86,13 +100,14 @@ static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err,
86 100
87 if (unlikely(qdio_err)) { 101 if (unlikely(qdio_err)) {
88 zfcp_hba_dbf_event_qdio(adapter, qdio_err, first, count); 102 zfcp_hba_dbf_event_qdio(adapter, qdio_err, first, count);
89 zfcp_qdio_handler_error(adapter, 140); 103 zfcp_qdio_handler_error(adapter, "qdireq1");
90 return; 104 return;
91 } 105 }
92 106
93 /* cleanup all SBALs being program-owned now */ 107 /* cleanup all SBALs being program-owned now */
94 zfcp_qdio_zero_sbals(queue->sbal, first, count); 108 zfcp_qdio_zero_sbals(queue->sbal, first, count);
95 109
110 zfcp_qdio_account(adapter);
96 atomic_add(count, &queue->count); 111 atomic_add(count, &queue->count);
97 wake_up(&adapter->request_wq); 112 wake_up(&adapter->request_wq);
98} 113}
@@ -154,7 +169,7 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
154 169
155 if (unlikely(qdio_err)) { 170 if (unlikely(qdio_err)) {
156 zfcp_hba_dbf_event_qdio(adapter, qdio_err, first, count); 171 zfcp_hba_dbf_event_qdio(adapter, qdio_err, first, count);
157 zfcp_qdio_handler_error(adapter, 147); 172 zfcp_qdio_handler_error(adapter, "qdires1");
158 return; 173 return;
159 } 174 }
160 175
@@ -346,21 +361,12 @@ int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req)
346 struct zfcp_qdio_queue *req_q = &adapter->req_q; 361 struct zfcp_qdio_queue *req_q = &adapter->req_q;
347 int first = fsf_req->sbal_first; 362 int first = fsf_req->sbal_first;
348 int count = fsf_req->sbal_number; 363 int count = fsf_req->sbal_number;
349 int retval, pci, pci_batch; 364 int retval;
350 struct qdio_buffer_element *sbale; 365 unsigned int qdio_flags = QDIO_FLAG_SYNC_OUTPUT;
351 366
352 /* acknowledgements for transferred buffers */ 367 zfcp_qdio_account(adapter);
353 pci_batch = adapter->req_q_pci_batch + count;
354 if (unlikely(pci_batch >= ZFCP_QDIO_PCI_INTERVAL)) {
355 pci_batch %= ZFCP_QDIO_PCI_INTERVAL;
356 pci = first + count - (pci_batch + 1);
357 pci %= QDIO_MAX_BUFFERS_PER_Q;
358 sbale = zfcp_qdio_sbale(req_q, pci, 0);
359 sbale->flags |= SBAL_FLAGS0_PCI;
360 }
361 368
362 retval = do_QDIO(adapter->ccw_device, QDIO_FLAG_SYNC_OUTPUT, 0, first, 369 retval = do_QDIO(adapter->ccw_device, qdio_flags, 0, first, count);
363 count);
364 if (unlikely(retval)) { 370 if (unlikely(retval)) {
365 zfcp_qdio_zero_sbals(req_q->sbal, first, count); 371 zfcp_qdio_zero_sbals(req_q->sbal, first, count);
366 return retval; 372 return retval;
@@ -370,7 +376,6 @@ int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req)
370 atomic_sub(count, &req_q->count); 376 atomic_sub(count, &req_q->count);
371 req_q->first += count; 377 req_q->first += count;
372 req_q->first %= QDIO_MAX_BUFFERS_PER_Q; 378 req_q->first %= QDIO_MAX_BUFFERS_PER_Q;
373 adapter->req_q_pci_batch = pci_batch;
374 return 0; 379 return 0;
375} 380}
376 381
@@ -441,7 +446,6 @@ void zfcp_qdio_close(struct zfcp_adapter *adapter)
441 } 446 }
442 req_q->first = 0; 447 req_q->first = 0;
443 atomic_set(&req_q->count, 0); 448 atomic_set(&req_q->count, 0);
444 adapter->req_q_pci_batch = 0;
445 adapter->resp_q.first = 0; 449 adapter->resp_q.first = 0;
446 atomic_set(&adapter->resp_q.count, 0); 450 atomic_set(&adapter->resp_q.count, 0);
447} 451}
@@ -479,7 +483,6 @@ int zfcp_qdio_open(struct zfcp_adapter *adapter)
479 /* set index of first avalable SBALS / number of available SBALS */ 483 /* set index of first avalable SBALS / number of available SBALS */
480 adapter->req_q.first = 0; 484 adapter->req_q.first = 0;
481 atomic_set(&adapter->req_q.count, QDIO_MAX_BUFFERS_PER_Q); 485 atomic_set(&adapter->req_q.count, QDIO_MAX_BUFFERS_PER_Q);
482 adapter->req_q_pci_batch = 0;
483 486
484 return 0; 487 return 0;
485 488