aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/qdio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/cio/qdio.c')
-rw-r--r--drivers/s390/cio/qdio.c97
1 files changed, 51 insertions, 46 deletions
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index ed026a1dc324..d8d479876ec7 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -81,6 +81,7 @@ static __u32 volatile spare_indicator;
81static atomic_t spare_indicator_usecount; 81static atomic_t spare_indicator_usecount;
82#define QDIO_MEMPOOL_SCSSC_ELEMENTS 2 82#define QDIO_MEMPOOL_SCSSC_ELEMENTS 2
83static mempool_t *qdio_mempool_scssc; 83static mempool_t *qdio_mempool_scssc;
84static struct kmem_cache *qdio_q_cache;
84 85
85static debug_info_t *qdio_dbf_setup; 86static debug_info_t *qdio_dbf_setup;
86static debug_info_t *qdio_dbf_sbal; 87static debug_info_t *qdio_dbf_sbal;
@@ -194,6 +195,8 @@ qdio_do_eqbs(struct qdio_q *q, unsigned char *state,
194again: 195again:
195 ccq = do_eqbs(irq->sch_token, state, q_no, start, cnt); 196 ccq = do_eqbs(irq->sch_token, state, q_no, start, cnt);
196 rc = qdio_check_ccq(q, ccq); 197 rc = qdio_check_ccq(q, ccq);
198 if ((ccq == 96) && (tmp_cnt != *cnt))
199 rc = 0;
197 if (rc == 1) { 200 if (rc == 1) {
198 QDIO_DBF_TEXT5(1,trace,"eqAGAIN"); 201 QDIO_DBF_TEXT5(1,trace,"eqAGAIN");
199 goto again; 202 goto again;
@@ -739,7 +742,8 @@ qdio_get_outbound_buffer_frontier(struct qdio_q *q)
739 first_not_to_check=f+qdio_min(atomic_read(&q->number_of_buffers_used), 742 first_not_to_check=f+qdio_min(atomic_read(&q->number_of_buffers_used),
740 (QDIO_MAX_BUFFERS_PER_Q-1)); 743 (QDIO_MAX_BUFFERS_PER_Q-1));
741 744
742 if ((!q->is_iqdio_q)&&(!q->hydra_gives_outbound_pcis)) 745 if (((!q->is_iqdio_q) && (!q->hydra_gives_outbound_pcis)) ||
746 (q->queue_type == QDIO_IQDIO_QFMT_ASYNCH))
743 SYNC_MEMORY; 747 SYNC_MEMORY;
744 748
745check_next: 749check_next:
@@ -1617,23 +1621,21 @@ static void
1617qdio_release_irq_memory(struct qdio_irq *irq_ptr) 1621qdio_release_irq_memory(struct qdio_irq *irq_ptr)
1618{ 1622{
1619 int i; 1623 int i;
1624 struct qdio_q *q;
1620 1625
1621 for (i=0;i<QDIO_MAX_QUEUES_PER_IRQ;i++) { 1626 for (i = 0; i < QDIO_MAX_QUEUES_PER_IRQ; i++) {
1622 if (!irq_ptr->input_qs[i]) 1627 q = irq_ptr->input_qs[i];
1623 goto next; 1628 if (q) {
1624 1629 free_page((unsigned long) q->slib);
1625 kfree(irq_ptr->input_qs[i]->slib); 1630 kmem_cache_free(qdio_q_cache, q);
1626 kfree(irq_ptr->input_qs[i]); 1631 }
1627 1632 q = irq_ptr->output_qs[i];
1628next: 1633 if (q) {
1629 if (!irq_ptr->output_qs[i]) 1634 free_page((unsigned long) q->slib);
1630 continue; 1635 kmem_cache_free(qdio_q_cache, q);
1631 1636 }
1632 kfree(irq_ptr->output_qs[i]->slib);
1633 kfree(irq_ptr->output_qs[i]);
1634
1635 } 1637 }
1636 kfree(irq_ptr->qdr); 1638 free_page((unsigned long) irq_ptr->qdr);
1637 free_page((unsigned long) irq_ptr); 1639 free_page((unsigned long) irq_ptr);
1638} 1640}
1639 1641
@@ -1680,44 +1682,35 @@ qdio_alloc_qs(struct qdio_irq *irq_ptr,
1680{ 1682{
1681 int i; 1683 int i;
1682 struct qdio_q *q; 1684 struct qdio_q *q;
1683 int result=-ENOMEM;
1684
1685 for (i=0;i<no_input_qs;i++) {
1686 q = kzalloc(sizeof(struct qdio_q), GFP_KERNEL);
1687 1685
1688 if (!q) { 1686 for (i = 0; i < no_input_qs; i++) {
1689 QDIO_PRINT_ERR("kmalloc of q failed!\n"); 1687 q = kmem_cache_alloc(qdio_q_cache, GFP_KERNEL);
1690 goto out; 1688 if (!q)
1691 } 1689 return -ENOMEM;
1690 memset(q, 0, sizeof(*q));
1692 1691
1693 q->slib = kmalloc(PAGE_SIZE, GFP_KERNEL); 1692 q->slib = (struct slib *) __get_free_page(GFP_KERNEL);
1694 if (!q->slib) { 1693 if (!q->slib) {
1695 QDIO_PRINT_ERR("kmalloc of slib failed!\n"); 1694 kmem_cache_free(qdio_q_cache, q);
1696 goto out; 1695 return -ENOMEM;
1697 } 1696 }
1698
1699 irq_ptr->input_qs[i]=q; 1697 irq_ptr->input_qs[i]=q;
1700 } 1698 }
1701 1699
1702 for (i=0;i<no_output_qs;i++) { 1700 for (i = 0; i < no_output_qs; i++) {
1703 q = kzalloc(sizeof(struct qdio_q), GFP_KERNEL); 1701 q = kmem_cache_alloc(qdio_q_cache, GFP_KERNEL);
1704 1702 if (!q)
1705 if (!q) { 1703 return -ENOMEM;
1706 goto out; 1704 memset(q, 0, sizeof(*q));
1707 }
1708 1705
1709 q->slib=kmalloc(PAGE_SIZE,GFP_KERNEL); 1706 q->slib = (struct slib *) __get_free_page(GFP_KERNEL);
1710 if (!q->slib) { 1707 if (!q->slib) {
1711 QDIO_PRINT_ERR("kmalloc of slib failed!\n"); 1708 kmem_cache_free(qdio_q_cache, q);
1712 goto out; 1709 return -ENOMEM;
1713 } 1710 }
1714
1715 irq_ptr->output_qs[i]=q; 1711 irq_ptr->output_qs[i]=q;
1716 } 1712 }
1717 1713 return 0;
1718 result=0;
1719out:
1720 return result;
1721} 1714}
1722 1715
1723static void 1716static void
@@ -2985,17 +2978,17 @@ qdio_allocate(struct qdio_initialize *init_data)
2985 QDIO_DBF_HEX0(0,setup,&irq_ptr,sizeof(void*)); 2978 QDIO_DBF_HEX0(0,setup,&irq_ptr,sizeof(void*));
2986 2979
2987 if (!irq_ptr) { 2980 if (!irq_ptr) {
2988 QDIO_PRINT_ERR("kmalloc of irq_ptr failed!\n"); 2981 QDIO_PRINT_ERR("allocation of irq_ptr failed!\n");
2989 return -ENOMEM; 2982 return -ENOMEM;
2990 } 2983 }
2991 2984
2992 init_MUTEX(&irq_ptr->setting_up_sema); 2985 init_MUTEX(&irq_ptr->setting_up_sema);
2993 2986
2994 /* QDR must be in DMA area since CCW data address is only 32 bit */ 2987 /* QDR must be in DMA area since CCW data address is only 32 bit */
2995 irq_ptr->qdr=kmalloc(sizeof(struct qdr), GFP_KERNEL | GFP_DMA); 2988 irq_ptr->qdr = (struct qdr *) __get_free_page(GFP_KERNEL | GFP_DMA);
2996 if (!(irq_ptr->qdr)) { 2989 if (!(irq_ptr->qdr)) {
2997 free_page((unsigned long) irq_ptr); 2990 free_page((unsigned long) irq_ptr);
2998 QDIO_PRINT_ERR("kmalloc of irq_ptr->qdr failed!\n"); 2991 QDIO_PRINT_ERR("allocation of irq_ptr->qdr failed!\n");
2999 return -ENOMEM; 2992 return -ENOMEM;
3000 } 2993 }
3001 QDIO_DBF_TEXT0(0,setup,"qdr:"); 2994 QDIO_DBF_TEXT0(0,setup,"qdr:");
@@ -3004,6 +2997,7 @@ qdio_allocate(struct qdio_initialize *init_data)
3004 if (qdio_alloc_qs(irq_ptr, 2997 if (qdio_alloc_qs(irq_ptr,
3005 init_data->no_input_qs, 2998 init_data->no_input_qs,
3006 init_data->no_output_qs)) { 2999 init_data->no_output_qs)) {
3000 QDIO_PRINT_ERR("queue allocation failed!\n");
3007 qdio_release_irq_memory(irq_ptr); 3001 qdio_release_irq_memory(irq_ptr);
3008 return -ENOMEM; 3002 return -ENOMEM;
3009 } 3003 }
@@ -3895,9 +3889,19 @@ init_QDIO(void)
3895 if (res) 3889 if (res)
3896 return res; 3890 return res;
3897 3891
3892 qdio_q_cache = kmem_cache_create("qdio_q", sizeof(struct qdio_q),
3893 256, 0, NULL);
3894 if (!qdio_q_cache) {
3895 qdio_release_qdio_memory();
3896 return -ENOMEM;
3897 }
3898
3898 res = qdio_register_dbf_views(); 3899 res = qdio_register_dbf_views();
3899 if (res) 3900 if (res) {
3901 kmem_cache_destroy(qdio_q_cache);
3902 qdio_release_qdio_memory();
3900 return res; 3903 return res;
3904 }
3901 3905
3902 QDIO_DBF_TEXT0(0,setup,"initQDIO"); 3906 QDIO_DBF_TEXT0(0,setup,"initQDIO");
3903 res = bus_create_file(&ccw_bus_type, &bus_attr_qdio_performance_stats); 3907 res = bus_create_file(&ccw_bus_type, &bus_attr_qdio_performance_stats);
@@ -3929,6 +3933,7 @@ cleanup_QDIO(void)
3929 qdio_release_qdio_memory(); 3933 qdio_release_qdio_memory();
3930 qdio_unregister_dbf_views(); 3934 qdio_unregister_dbf_views();
3931 mempool_destroy(qdio_mempool_scssc); 3935 mempool_destroy(qdio_mempool_scssc);
3936 kmem_cache_destroy(qdio_q_cache);
3932 bus_remove_file(&ccw_bus_type, &bus_attr_qdio_performance_stats); 3937 bus_remove_file(&ccw_bus_type, &bus_attr_qdio_performance_stats);
3933 printk("qdio: %s: module removed\n",version); 3938 printk("qdio: %s: module removed\n",version);
3934} 3939}