diff options
-rw-r--r-- | drivers/s390/cio/qdio.c | 37 | ||||
-rw-r--r-- | drivers/s390/cio/qdio.h | 4 | ||||
-rw-r--r-- | drivers/s390/net/qeth_main.c | 14 | ||||
-rw-r--r-- | include/asm-s390/qdio.h | 1 |
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 | ||
64 | enum qdio_irq_states { | 65 | enum 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 | ||
124 | extern int do_QDIO(struct ccw_device*, unsigned int flags, | 125 | extern int do_QDIO(struct ccw_device*, unsigned int flags, |
125 | unsigned int queue_number, | 126 | unsigned int queue_number, |