aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-07 11:41:00 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-07 11:41:00 -0400
commitebb067d2f4e2db59b076f9c9cba0375a8ad1e07c (patch)
tree8d4fc065ab0fd45fca9483acfff93d4a6c74e981 /drivers/s390/scsi
parent33caee39925b887a99a2400dc5c980097c3573f9 (diff)
parent36e7fdaa1a04fcf65b864232e1af56a51c7814d6 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Martin Schwidefsky: "Mostly cleanups and bug-fixes, with two exceptions. The first is lazy flushing of I/O-TLBs for PCI to improve performance, the second is software dirty bits in the pmd for the madvise-free implementation" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (24 commits) s390/locking: Reenable optimistic spinning s390/mm: implement dirty bits for large segment table entries KVM: s390/mm: Fix page table locking vs. split pmd lock s390/dasd: fix camel case s390/3215: fix hanging console issue s390/irq: improve displayed interrupt order in /proc/interrupts s390/seccomp: fix error return for filtered system calls s390/pci: introduce lazy IOTLB flushing for DMA unmap dasd: fix error recovery for alias devices during format dasd: fix list_del corruption during format dasd: fix unresponsive device during format dasd: use aliases for formatted devices during format s390/pci: fix kmsg component s390/kdump: Return NOTIFY_OK for all actions other than MEM_GOING_OFFLINE s390/watchdog: Fix module name in Kconfig help text s390/dasd: replace seq_printf by seq_puts s390/dasd: replace pr_warning by pr_warn s390/dasd: Move EXPORT_SYMBOL after function/variable s390/dasd: remove unnecessary null test before debugfs_remove s390/zfcp: use qdio buffer helpers ...
Diffstat (limited to 'drivers/s390/scsi')
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c49
1 files changed, 21 insertions, 28 deletions
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index 06025cdaa4ad..495e1cb3afa6 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -14,27 +14,10 @@
14#include "zfcp_ext.h" 14#include "zfcp_ext.h"
15#include "zfcp_qdio.h" 15#include "zfcp_qdio.h"
16 16
17#define QBUFF_PER_PAGE (PAGE_SIZE / sizeof(struct qdio_buffer))
18
19static bool enable_multibuffer = 1; 17static bool enable_multibuffer = 1;
20module_param_named(datarouter, enable_multibuffer, bool, 0400); 18module_param_named(datarouter, enable_multibuffer, bool, 0400);
21MODULE_PARM_DESC(datarouter, "Enable hardware data router support (default on)"); 19MODULE_PARM_DESC(datarouter, "Enable hardware data router support (default on)");
22 20
23static int zfcp_qdio_buffers_enqueue(struct qdio_buffer **sbal)
24{
25 int pos;
26
27 for (pos = 0; pos < QDIO_MAX_BUFFERS_PER_Q; pos += QBUFF_PER_PAGE) {
28 sbal[pos] = (struct qdio_buffer *) get_zeroed_page(GFP_KERNEL);
29 if (!sbal[pos])
30 return -ENOMEM;
31 }
32 for (pos = 0; pos < QDIO_MAX_BUFFERS_PER_Q; pos++)
33 if (pos % QBUFF_PER_PAGE)
34 sbal[pos] = sbal[pos - 1] + 1;
35 return 0;
36}
37
38static void zfcp_qdio_handler_error(struct zfcp_qdio *qdio, char *id, 21static void zfcp_qdio_handler_error(struct zfcp_qdio *qdio, char *id,
39 unsigned int qdio_err) 22 unsigned int qdio_err)
40{ 23{
@@ -326,15 +309,30 @@ static void zfcp_qdio_setup_init_data(struct qdio_initialize *id,
326static int zfcp_qdio_allocate(struct zfcp_qdio *qdio) 309static int zfcp_qdio_allocate(struct zfcp_qdio *qdio)
327{ 310{
328 struct qdio_initialize init_data; 311 struct qdio_initialize init_data;
312 int ret;
329 313
330 if (zfcp_qdio_buffers_enqueue(qdio->req_q) || 314 ret = qdio_alloc_buffers(qdio->req_q, QDIO_MAX_BUFFERS_PER_Q);
331 zfcp_qdio_buffers_enqueue(qdio->res_q)) 315 if (ret)
332 return -ENOMEM; 316 return -ENOMEM;
333 317
318 ret = qdio_alloc_buffers(qdio->res_q, QDIO_MAX_BUFFERS_PER_Q);
319 if (ret)
320 goto free_req_q;
321
334 zfcp_qdio_setup_init_data(&init_data, qdio); 322 zfcp_qdio_setup_init_data(&init_data, qdio);
335 init_waitqueue_head(&qdio->req_q_wq); 323 init_waitqueue_head(&qdio->req_q_wq);
336 324
337 return qdio_allocate(&init_data); 325 ret = qdio_allocate(&init_data);
326 if (ret)
327 goto free_res_q;
328
329 return 0;
330
331free_res_q:
332 qdio_free_buffers(qdio->res_q, QDIO_MAX_BUFFERS_PER_Q);
333free_req_q:
334 qdio_free_buffers(qdio->req_q, QDIO_MAX_BUFFERS_PER_Q);
335 return ret;
338} 336}
339 337
340/** 338/**
@@ -448,19 +446,14 @@ failed_establish:
448 446
449void zfcp_qdio_destroy(struct zfcp_qdio *qdio) 447void zfcp_qdio_destroy(struct zfcp_qdio *qdio)
450{ 448{
451 int p;
452
453 if (!qdio) 449 if (!qdio)
454 return; 450 return;
455 451
456 if (qdio->adapter->ccw_device) 452 if (qdio->adapter->ccw_device)
457 qdio_free(qdio->adapter->ccw_device); 453 qdio_free(qdio->adapter->ccw_device);
458 454
459 for (p = 0; p < QDIO_MAX_BUFFERS_PER_Q; p += QBUFF_PER_PAGE) { 455 qdio_free_buffers(qdio->req_q, QDIO_MAX_BUFFERS_PER_Q);
460 free_page((unsigned long) qdio->req_q[p]); 456 qdio_free_buffers(qdio->res_q, QDIO_MAX_BUFFERS_PER_Q);
461 free_page((unsigned long) qdio->res_q[p]);
462 }
463
464 kfree(qdio); 457 kfree(qdio);
465} 458}
466 459
@@ -475,7 +468,7 @@ int zfcp_qdio_setup(struct zfcp_adapter *adapter)
475 qdio->adapter = adapter; 468 qdio->adapter = adapter;
476 469
477 if (zfcp_qdio_allocate(qdio)) { 470 if (zfcp_qdio_allocate(qdio)) {
478 zfcp_qdio_destroy(qdio); 471 kfree(qdio);
479 return -ENOMEM; 472 return -ENOMEM;
480 } 473 }
481 474