aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/net
diff options
context:
space:
mode:
authorfrank.blaschka@de.ibm.com <frank.blaschka@de.ibm.com>2011-08-07 21:33:55 -0400
committerDavid S. Miller <davem@davemloft.net>2011-08-13 04:10:16 -0400
commit104ea556ee7f40039c9c635d0c267b1fde084a81 (patch)
tree5b4af497551a3f2e2cb2f24030d028392aae07e0 /drivers/s390/net
parent3881ac441f642d56503818123446f7298442236b (diff)
qdio: support asynchronous delivery of storage blocks
This patch introduces support for asynchronous delivery of storage blocks for Hipersockets. Upper layers may exploit this functionality to reuse SBALs for which the delivery status is still pending. Signed-off-by: Einar Lueck <elelueck@de.ibm.com> Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com> Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/s390/net')
-rw-r--r--drivers/s390/net/qeth_core_main.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 2b0fb056a51f..8d804be9f043 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -3939,6 +3939,7 @@ static int qeth_qdio_establish(struct qeth_card *card)
3939 struct qdio_initialize init_data; 3939 struct qdio_initialize init_data;
3940 char *qib_param_field; 3940 char *qib_param_field;
3941 struct qdio_buffer **in_sbal_ptrs; 3941 struct qdio_buffer **in_sbal_ptrs;
3942 void (**queue_start_poll) (struct ccw_device *, int, unsigned long);
3942 struct qdio_buffer **out_sbal_ptrs; 3943 struct qdio_buffer **out_sbal_ptrs;
3943 int i, j, k; 3944 int i, j, k;
3944 int rc = 0; 3945 int rc = 0;
@@ -3947,8 +3948,10 @@ static int qeth_qdio_establish(struct qeth_card *card)
3947 3948
3948 qib_param_field = kzalloc(QDIO_MAX_BUFFERS_PER_Q * sizeof(char), 3949 qib_param_field = kzalloc(QDIO_MAX_BUFFERS_PER_Q * sizeof(char),
3949 GFP_KERNEL); 3950 GFP_KERNEL);
3950 if (!qib_param_field) 3951 if (!qib_param_field) {
3951 return -ENOMEM; 3952 rc = -ENOMEM;
3953 goto out_free_nothing;
3954 }
3952 3955
3953 qeth_create_qib_param_field(card, qib_param_field); 3956 qeth_create_qib_param_field(card, qib_param_field);
3954 qeth_create_qib_param_field_blkt(card, qib_param_field); 3957 qeth_create_qib_param_field_blkt(card, qib_param_field);
@@ -3956,20 +3959,26 @@ static int qeth_qdio_establish(struct qeth_card *card)
3956 in_sbal_ptrs = kmalloc(QDIO_MAX_BUFFERS_PER_Q * sizeof(void *), 3959 in_sbal_ptrs = kmalloc(QDIO_MAX_BUFFERS_PER_Q * sizeof(void *),
3957 GFP_KERNEL); 3960 GFP_KERNEL);
3958 if (!in_sbal_ptrs) { 3961 if (!in_sbal_ptrs) {
3959 kfree(qib_param_field); 3962 rc = -ENOMEM;
3960 return -ENOMEM; 3963 goto out_free_qib_param;
3961 } 3964 }
3962 for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i) 3965 for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i)
3963 in_sbal_ptrs[i] = (struct qdio_buffer *) 3966 in_sbal_ptrs[i] = (struct qdio_buffer *)
3964 virt_to_phys(card->qdio.in_q->bufs[i].buffer); 3967 virt_to_phys(card->qdio.in_q->bufs[i].buffer);
3965 3968
3969 queue_start_poll = kmalloc(sizeof(void *) * 1, GFP_KERNEL);
3970 if (!queue_start_poll) {
3971 rc = -ENOMEM;
3972 goto out_free_in_sbals;
3973 }
3974 queue_start_poll[0] = card->discipline.start_poll;
3975
3966 out_sbal_ptrs = 3976 out_sbal_ptrs =
3967 kmalloc(card->qdio.no_out_queues * QDIO_MAX_BUFFERS_PER_Q * 3977 kmalloc(card->qdio.no_out_queues * QDIO_MAX_BUFFERS_PER_Q *
3968 sizeof(void *), GFP_KERNEL); 3978 sizeof(void *), GFP_KERNEL);
3969 if (!out_sbal_ptrs) { 3979 if (!out_sbal_ptrs) {
3970 kfree(in_sbal_ptrs); 3980 rc = -ENOMEM;
3971 kfree(qib_param_field); 3981 goto out_free_queue_start_poll;
3972 return -ENOMEM;
3973 } 3982 }
3974 for (i = 0, k = 0; i < card->qdio.no_out_queues; ++i) 3983 for (i = 0, k = 0; i < card->qdio.no_out_queues; ++i)
3975 for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j, ++k) { 3984 for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j, ++k) {
@@ -3986,7 +3995,7 @@ static int qeth_qdio_establish(struct qeth_card *card)
3986 init_data.no_output_qs = card->qdio.no_out_queues; 3995 init_data.no_output_qs = card->qdio.no_out_queues;
3987 init_data.input_handler = card->discipline.input_handler; 3996 init_data.input_handler = card->discipline.input_handler;
3988 init_data.output_handler = card->discipline.output_handler; 3997 init_data.output_handler = card->discipline.output_handler;
3989 init_data.queue_start_poll = card->discipline.start_poll; 3998 init_data.queue_start_poll = queue_start_poll;
3990 init_data.int_parm = (unsigned long) card; 3999 init_data.int_parm = (unsigned long) card;
3991 init_data.input_sbal_addr_array = (void **) in_sbal_ptrs; 4000 init_data.input_sbal_addr_array = (void **) in_sbal_ptrs;
3992 init_data.output_sbal_addr_array = (void **) out_sbal_ptrs; 4001 init_data.output_sbal_addr_array = (void **) out_sbal_ptrs;
@@ -4008,8 +4017,13 @@ static int qeth_qdio_establish(struct qeth_card *card)
4008 } 4017 }
4009out: 4018out:
4010 kfree(out_sbal_ptrs); 4019 kfree(out_sbal_ptrs);
4020out_free_queue_start_poll:
4021 kfree(queue_start_poll);
4022out_free_in_sbals:
4011 kfree(in_sbal_ptrs); 4023 kfree(in_sbal_ptrs);
4024out_free_qib_param:
4012 kfree(qib_param_field); 4025 kfree(qib_param_field);
4026out_free_nothing:
4013 return rc; 4027 return rc;
4014} 4028}
4015 4029