diff options
Diffstat (limited to 'drivers/s390/cio/qdio_thinint.c')
-rw-r--r-- | drivers/s390/cio/qdio_thinint.c | 48 |
1 files changed, 46 insertions, 2 deletions
diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c index 9d1e7efb5bb..011eadea3ee 100644 --- a/drivers/s390/cio/qdio_thinint.c +++ b/drivers/s390/cio/qdio_thinint.c | |||
@@ -26,6 +26,13 @@ | |||
26 | */ | 26 | */ |
27 | #define TIQDIO_NR_NONSHARED_IND 63 | 27 | #define TIQDIO_NR_NONSHARED_IND 63 |
28 | #define TIQDIO_NR_INDICATORS (TIQDIO_NR_NONSHARED_IND + 1) | 28 | #define TIQDIO_NR_INDICATORS (TIQDIO_NR_NONSHARED_IND + 1) |
29 | #define TIQDIO_SHARED_IND 63 | ||
30 | |||
31 | /* device state change indicators */ | ||
32 | struct indicator_t { | ||
33 | u32 ind; /* u32 because of compare-and-swap performance */ | ||
34 | atomic_t count; /* use count, 0 or 1 for non-shared indicators */ | ||
35 | }; | ||
29 | 36 | ||
30 | /* list of thin interrupt input queues */ | 37 | /* list of thin interrupt input queues */ |
31 | static LIST_HEAD(tiq_list); | 38 | static LIST_HEAD(tiq_list); |
@@ -34,7 +41,7 @@ static DEFINE_MUTEX(tiq_list_lock); | |||
34 | /* adapter local summary indicator */ | 41 | /* adapter local summary indicator */ |
35 | static u8 *tiqdio_alsi; | 42 | static u8 *tiqdio_alsi; |
36 | 43 | ||
37 | struct indicator_t *q_indicators; | 44 | static struct indicator_t *q_indicators; |
38 | 45 | ||
39 | u64 last_ai_time; | 46 | u64 last_ai_time; |
40 | 47 | ||
@@ -90,6 +97,43 @@ void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr) | |||
90 | synchronize_rcu(); | 97 | synchronize_rcu(); |
91 | } | 98 | } |
92 | 99 | ||
100 | static inline int has_multiple_inq_on_dsci(struct qdio_irq *irq_ptr) | ||
101 | { | ||
102 | return irq_ptr->nr_input_qs > 1; | ||
103 | } | ||
104 | |||
105 | static inline int references_shared_dsci(struct qdio_irq *irq_ptr) | ||
106 | { | ||
107 | return irq_ptr->dsci == &q_indicators[TIQDIO_SHARED_IND].ind; | ||
108 | } | ||
109 | |||
110 | static inline int shared_ind(struct qdio_irq *irq_ptr) | ||
111 | { | ||
112 | return references_shared_dsci(irq_ptr) || | ||
113 | has_multiple_inq_on_dsci(irq_ptr); | ||
114 | } | ||
115 | |||
116 | void clear_nonshared_ind(struct qdio_irq *irq_ptr) | ||
117 | { | ||
118 | if (!is_thinint_irq(irq_ptr)) | ||
119 | return; | ||
120 | if (shared_ind(irq_ptr)) | ||
121 | return; | ||
122 | xchg(irq_ptr->dsci, 0); | ||
123 | } | ||
124 | |||
125 | int test_nonshared_ind(struct qdio_irq *irq_ptr) | ||
126 | { | ||
127 | if (!is_thinint_irq(irq_ptr)) | ||
128 | return 0; | ||
129 | if (shared_ind(irq_ptr)) | ||
130 | return 0; | ||
131 | if (*irq_ptr->dsci) | ||
132 | return 1; | ||
133 | else | ||
134 | return 0; | ||
135 | } | ||
136 | |||
93 | static inline u32 clear_shared_ind(void) | 137 | static inline u32 clear_shared_ind(void) |
94 | { | 138 | { |
95 | if (!atomic_read(&q_indicators[TIQDIO_SHARED_IND].count)) | 139 | if (!atomic_read(&q_indicators[TIQDIO_SHARED_IND].count)) |
@@ -119,7 +163,7 @@ static inline void tiqdio_call_inq_handlers(struct qdio_irq *irq) | |||
119 | q->u.in.queue_start_poll(q->irq_ptr->cdev, q->nr, | 163 | q->u.in.queue_start_poll(q->irq_ptr->cdev, q->nr, |
120 | q->irq_ptr->int_parm); | 164 | q->irq_ptr->int_parm); |
121 | } else { | 165 | } else { |
122 | if (!shared_ind(q)) | 166 | if (!shared_ind(q->irq_ptr)) |
123 | xchg(q->irq_ptr->dsci, 0); | 167 | xchg(q->irq_ptr->dsci, 0); |
124 | 168 | ||
125 | /* | 169 | /* |