aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/s390/cio/qdio.c37
-rw-r--r--drivers/s390/cio/qdio.h4
-rw-r--r--drivers/s390/net/qeth_main.c14
-rw-r--r--include/asm-s390/qdio.h1
4 files changed, 39 insertions, 17 deletions
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index cba64e4cfcd4..f770018fe1d5 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -996,18 +996,25 @@ __qdio_outbound_processing(struct qdio_q *q)
996 if (qdio_has_outbound_q_moved(q)) 996 if (qdio_has_outbound_q_moved(q))
997 qdio_kick_outbound_handler(q); 997 qdio_kick_outbound_handler(q);
998 998
999 if (q->is_iqdio_q) { 999 if (q->queue_type == QDIO_ZFCP_QFMT) {
1000 if ((!q->hydra_gives_outbound_pcis) &&
1001 (!qdio_is_outbound_q_done(q)))
1002 qdio_mark_q(q);
1003 }
1004 else if (((!q->is_iqdio_q) && (!q->is_pci_out)) ||
1005 (q->queue_type == QDIO_IQDIO_QFMT_ASYNCH)) {
1000 /* 1006 /*
1001 * for asynchronous queues, we better check, if the sent 1007 * make sure buffer switch from PRIMED to EMPTY is noticed
1002 * buffer is already switched from PRIMED to EMPTY. 1008 * and outbound_handler is called
1003 */ 1009 */
1004 if ((q->queue_type == QDIO_IQDIO_QFMT_ASYNCH) && 1010 if (qdio_is_outbound_q_done(q)) {
1005 !qdio_is_outbound_q_done(q)) 1011 del_timer(&q->timer);
1006 qdio_mark_q(q); 1012 } else {
1007 1013 if (!timer_pending(&q->timer))
1008 } else if (!q->hydra_gives_outbound_pcis) 1014 mod_timer(&q->timer, jiffies +
1009 if (!qdio_is_outbound_q_done(q)) 1015 QDIO_FORCE_CHECK_TIMEOUT);
1010 qdio_mark_q(q); 1016 }
1017 }
1011 1018
1012 qdio_release_q(q); 1019 qdio_release_q(q);
1013} 1020}
@@ -1826,6 +1833,7 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev,
1826 q->queue_type = QDIO_IQDIO_QFMT_ASYNCH; 1833 q->queue_type = QDIO_IQDIO_QFMT_ASYNCH;
1827 q->int_parm=int_parm; 1834 q->int_parm=int_parm;
1828 q->is_input_q=0; 1835 q->is_input_q=0;
1836 q->is_pci_out = 0;
1829 q->schid = irq_ptr->schid; 1837 q->schid = irq_ptr->schid;
1830 q->cdev = cdev; 1838 q->cdev = cdev;
1831 q->irq_ptr = irq_ptr; 1839 q->irq_ptr = irq_ptr;
@@ -1838,6 +1846,10 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev,
1838 q->tasklet.data=(unsigned long)q; 1846 q->tasklet.data=(unsigned long)q;
1839 q->tasklet.func=(void(*)(unsigned long)) 1847 q->tasklet.func=(void(*)(unsigned long))
1840 &qdio_outbound_processing; 1848 &qdio_outbound_processing;
1849 q->timer.function=(void(*)(unsigned long))
1850 &qdio_outbound_processing;
1851 q->timer.data = (long)q;
1852 init_timer(&q->timer);
1841 1853
1842 atomic_set(&q->busy_siga_counter,0); 1854 atomic_set(&q->busy_siga_counter,0);
1843 q->timing.busy_start=0; 1855 q->timing.busy_start=0;
@@ -2635,6 +2647,7 @@ qdio_shutdown(struct ccw_device *cdev, int how)
2635 2647
2636 for (i=0;i<irq_ptr->no_output_qs;i++) { 2648 for (i=0;i<irq_ptr->no_output_qs;i++) {
2637 tasklet_kill(&irq_ptr->output_qs[i]->tasklet); 2649 tasklet_kill(&irq_ptr->output_qs[i]->tasklet);
2650 del_timer(&irq_ptr->output_qs[i]->timer);
2638 wait_event_interruptible_timeout(cdev->private->wait_q, 2651 wait_event_interruptible_timeout(cdev->private->wait_q,
2639 !atomic_read(&irq_ptr-> 2652 !atomic_read(&irq_ptr->
2640 output_qs[i]-> 2653 output_qs[i]->
@@ -3458,6 +3471,10 @@ do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags,
3458 qdio_perf_stat_inc(&perf_stats.outbound_cnt); 3471 qdio_perf_stat_inc(&perf_stats.outbound_cnt);
3459 return; 3472 return;
3460 } 3473 }
3474 if (callflags & QDIO_FLAG_PCI_OUT)
3475 q->is_pci_out = 1;
3476 else
3477 q->is_pci_out = 0;
3461 if (q->is_iqdio_q) { 3478 if (q->is_iqdio_q) {
3462 /* one siga for every sbal */ 3479 /* one siga for every sbal */
3463 while (count--) 3480 while (count--)
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index 2895392eaae4..6d7aad18f6f0 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -60,6 +60,7 @@
60#define QDIO_ACTIVATE_TIMEOUT ((5*HZ)>>10) 60#define QDIO_ACTIVATE_TIMEOUT ((5*HZ)>>10)
61#define QDIO_CLEANUP_CLEAR_TIMEOUT (20*HZ) 61#define QDIO_CLEANUP_CLEAR_TIMEOUT (20*HZ)
62#define QDIO_CLEANUP_HALT_TIMEOUT (10*HZ) 62#define QDIO_CLEANUP_HALT_TIMEOUT (10*HZ)
63#define QDIO_FORCE_CHECK_TIMEOUT (10*HZ)
63 64
64enum qdio_irq_states { 65enum qdio_irq_states {
65 QDIO_IRQ_STATE_INACTIVE, 66 QDIO_IRQ_STATE_INACTIVE,
@@ -511,8 +512,8 @@ struct qdio_q {
511 512
512 void *irq_ptr; 513 void *irq_ptr;
513 514
514#ifdef QDIO_USE_TIMERS_FOR_POLLING
515 struct timer_list timer; 515 struct timer_list timer;
516#ifdef QDIO_USE_TIMERS_FOR_POLLING
516 atomic_t timer_already_set; 517 atomic_t timer_already_set;
517 spinlock_t timer_lock; 518 spinlock_t timer_lock;
518#else /* QDIO_USE_TIMERS_FOR_POLLING */ 519#else /* QDIO_USE_TIMERS_FOR_POLLING */
@@ -558,6 +559,7 @@ struct qdio_q {
558 } timing; 559 } timing;
559 atomic_t busy_siga_counter; 560 atomic_t busy_siga_counter;
560 unsigned int queue_type; 561 unsigned int queue_type;
562 unsigned int is_pci_out;
561 563
562 /* leave this member at the end. won't be cleared in qdio_fill_qs */ 564 /* leave this member at the end. won't be cleared in qdio_fill_qs */
563 struct slib *slib; /* a page is allocated under this pointer, 565 struct slib *slib; /* a page is allocated under this pointer,
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 032483513027..134f08c200d2 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -2816,6 +2816,7 @@ qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int,
2816 struct qeth_qdio_out_buffer *buf; 2816 struct qeth_qdio_out_buffer *buf;
2817 int rc; 2817 int rc;
2818 int i; 2818 int i;
2819 unsigned int qdio_flags;
2819 2820
2820 QETH_DBF_TEXT(trace, 6, "flushbuf"); 2821 QETH_DBF_TEXT(trace, 6, "flushbuf");
2821 2822
@@ -2859,13 +2860,13 @@ qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int,
2859 queue->card->perf_stats.outbound_do_qdio_start_time = 2860 queue->card->perf_stats.outbound_do_qdio_start_time =
2860 qeth_get_micros(); 2861 qeth_get_micros();
2861 } 2862 }
2863 qdio_flags = QDIO_FLAG_SYNC_OUTPUT;
2862 if (under_int) 2864 if (under_int)
2863 rc = do_QDIO(CARD_DDEV(queue->card), 2865 qdio_flags |= QDIO_FLAG_UNDER_INTERRUPT;
2864 QDIO_FLAG_SYNC_OUTPUT | QDIO_FLAG_UNDER_INTERRUPT, 2866 if (atomic_read(&queue->set_pci_flags_count))
2865 queue->queue_no, index, count, NULL); 2867 qdio_flags |= QDIO_FLAG_PCI_OUT;
2866 else 2868 rc = do_QDIO(CARD_DDEV(queue->card), qdio_flags,
2867 rc = do_QDIO(CARD_DDEV(queue->card), QDIO_FLAG_SYNC_OUTPUT, 2869 queue->queue_no, index, count, NULL);
2868 queue->queue_no, index, count, NULL);
2869 if (queue->card->options.performance_stats) 2870 if (queue->card->options.performance_stats)
2870 queue->card->perf_stats.outbound_do_qdio_time += 2871 queue->card->perf_stats.outbound_do_qdio_time +=
2871 qeth_get_micros() - 2872 qeth_get_micros() -
@@ -8498,6 +8499,7 @@ __qeth_reboot_event_card(struct device *dev, void *data)
8498 card = (struct qeth_card *) dev->driver_data; 8499 card = (struct qeth_card *) dev->driver_data;
8499 qeth_clear_ip_list(card, 0, 0); 8500 qeth_clear_ip_list(card, 0, 0);
8500 qeth_qdio_clear_card(card, 0); 8501 qeth_qdio_clear_card(card, 0);
8502 qeth_clear_qdio_buffers(card);
8501 return 0; 8503 return 0;
8502} 8504}
8503 8505
diff --git a/include/asm-s390/qdio.h b/include/asm-s390/qdio.h
index 127f72e77419..74db1dc10a7d 100644
--- a/include/asm-s390/qdio.h
+++ b/include/asm-s390/qdio.h
@@ -120,6 +120,7 @@ extern unsigned long qdio_get_status(int irq);
120#define QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT 0x08 /* no effect on 120#define QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT 0x08 /* no effect on
121 adapter interrupts */ 121 adapter interrupts */
122#define QDIO_FLAG_DONT_SIGA 0x10 122#define QDIO_FLAG_DONT_SIGA 0x10
123#define QDIO_FLAG_PCI_OUT 0x20
123 124
124extern int do_QDIO(struct ccw_device*, unsigned int flags, 125extern int do_QDIO(struct ccw_device*, unsigned int flags,
125 unsigned int queue_number, 126 unsigned int queue_number,