diff options
Diffstat (limited to 'drivers/s390/cio')
-rw-r--r-- | drivers/s390/cio/qdio.c | 37 | ||||
-rw-r--r-- | drivers/s390/cio/qdio.h | 4 |
2 files changed, 30 insertions, 11 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, |