diff options
Diffstat (limited to 'drivers/s390/cio/qdio.h')
-rw-r--r-- | drivers/s390/cio/qdio.h | 56 |
1 files changed, 46 insertions, 10 deletions
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index f0037eefd44e..7bc643f3f5ab 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h | |||
@@ -91,6 +91,12 @@ enum qdio_irq_states { | |||
91 | #define AC1_SC_QEBSM_AVAILABLE 0x02 /* available for subchannel */ | 91 | #define AC1_SC_QEBSM_AVAILABLE 0x02 /* available for subchannel */ |
92 | #define AC1_SC_QEBSM_ENABLED 0x01 /* enabled for subchannel */ | 92 | #define AC1_SC_QEBSM_ENABLED 0x01 /* enabled for subchannel */ |
93 | 93 | ||
94 | /* SIGA flags */ | ||
95 | #define QDIO_SIGA_WRITE 0x00 | ||
96 | #define QDIO_SIGA_READ 0x01 | ||
97 | #define QDIO_SIGA_SYNC 0x02 | ||
98 | #define QDIO_SIGA_QEBSM_FLAG 0x80 | ||
99 | |||
94 | #ifdef CONFIG_64BIT | 100 | #ifdef CONFIG_64BIT |
95 | static inline int do_sqbs(u64 token, unsigned char state, int queue, | 101 | static inline int do_sqbs(u64 token, unsigned char state, int queue, |
96 | int *start, int *count) | 102 | int *start, int *count) |
@@ -142,10 +148,9 @@ struct siga_flag { | |||
142 | u8 input:1; | 148 | u8 input:1; |
143 | u8 output:1; | 149 | u8 output:1; |
144 | u8 sync:1; | 150 | u8 sync:1; |
145 | u8 no_sync_ti:1; | 151 | u8 sync_after_ai:1; |
146 | u8 no_sync_out_ti:1; | 152 | u8 sync_out_after_pci:1; |
147 | u8 no_sync_out_pci:1; | 153 | u8:3; |
148 | u8:2; | ||
149 | } __attribute__ ((packed)); | 154 | } __attribute__ ((packed)); |
150 | 155 | ||
151 | struct chsc_ssqd_area { | 156 | struct chsc_ssqd_area { |
@@ -202,12 +207,14 @@ struct qdio_dev_perf_stat { | |||
202 | unsigned int inbound_queue_full; | 207 | unsigned int inbound_queue_full; |
203 | unsigned int outbound_call; | 208 | unsigned int outbound_call; |
204 | unsigned int outbound_handler; | 209 | unsigned int outbound_handler; |
210 | unsigned int outbound_queue_full; | ||
205 | unsigned int fast_requeue; | 211 | unsigned int fast_requeue; |
206 | unsigned int target_full; | 212 | unsigned int target_full; |
207 | unsigned int eqbs; | 213 | unsigned int eqbs; |
208 | unsigned int eqbs_partial; | 214 | unsigned int eqbs_partial; |
209 | unsigned int sqbs; | 215 | unsigned int sqbs; |
210 | unsigned int sqbs_partial; | 216 | unsigned int sqbs_partial; |
217 | unsigned int int_discarded; | ||
211 | } ____cacheline_aligned; | 218 | } ____cacheline_aligned; |
212 | 219 | ||
213 | struct qdio_queue_perf_stat { | 220 | struct qdio_queue_perf_stat { |
@@ -222,6 +229,10 @@ struct qdio_queue_perf_stat { | |||
222 | unsigned int nr_sbal_total; | 229 | unsigned int nr_sbal_total; |
223 | }; | 230 | }; |
224 | 231 | ||
232 | enum qdio_queue_irq_states { | ||
233 | QDIO_QUEUE_IRQS_DISABLED, | ||
234 | }; | ||
235 | |||
225 | struct qdio_input_q { | 236 | struct qdio_input_q { |
226 | /* input buffer acknowledgement flag */ | 237 | /* input buffer acknowledgement flag */ |
227 | int polling; | 238 | int polling; |
@@ -231,15 +242,19 @@ struct qdio_input_q { | |||
231 | int ack_count; | 242 | int ack_count; |
232 | /* last time of noticing incoming data */ | 243 | /* last time of noticing incoming data */ |
233 | u64 timestamp; | 244 | u64 timestamp; |
245 | /* upper-layer polling flag */ | ||
246 | unsigned long queue_irq_state; | ||
247 | /* callback to start upper-layer polling */ | ||
248 | void (*queue_start_poll) (struct ccw_device *, int, unsigned long); | ||
234 | }; | 249 | }; |
235 | 250 | ||
236 | struct qdio_output_q { | 251 | struct qdio_output_q { |
237 | /* PCIs are enabled for the queue */ | 252 | /* PCIs are enabled for the queue */ |
238 | int pci_out_enabled; | 253 | int pci_out_enabled; |
239 | /* IQDIO: output multiple buffers (enhanced SIGA) */ | ||
240 | int use_enh_siga; | ||
241 | /* timer to check for more outbound work */ | 254 | /* timer to check for more outbound work */ |
242 | struct timer_list timer; | 255 | struct timer_list timer; |
256 | /* used SBALs before tasklet schedule */ | ||
257 | int scan_threshold; | ||
243 | }; | 258 | }; |
244 | 259 | ||
245 | /* | 260 | /* |
@@ -374,12 +389,13 @@ static inline int multicast_outbound(struct qdio_q *q) | |||
374 | (q->irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED) | 389 | (q->irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED) |
375 | #define is_qebsm(q) (q->irq_ptr->sch_token != 0) | 390 | #define is_qebsm(q) (q->irq_ptr->sch_token != 0) |
376 | 391 | ||
377 | #define need_siga_sync_thinint(q) (!q->irq_ptr->siga_flag.no_sync_ti) | ||
378 | #define need_siga_sync_out_thinint(q) (!q->irq_ptr->siga_flag.no_sync_out_ti) | ||
379 | #define need_siga_in(q) (q->irq_ptr->siga_flag.input) | 392 | #define need_siga_in(q) (q->irq_ptr->siga_flag.input) |
380 | #define need_siga_out(q) (q->irq_ptr->siga_flag.output) | 393 | #define need_siga_out(q) (q->irq_ptr->siga_flag.output) |
381 | #define need_siga_sync(q) (q->irq_ptr->siga_flag.sync) | 394 | #define need_siga_sync(q) (unlikely(q->irq_ptr->siga_flag.sync)) |
382 | #define siga_syncs_out_pci(q) (q->irq_ptr->siga_flag.no_sync_out_pci) | 395 | #define need_siga_sync_after_ai(q) \ |
396 | (unlikely(q->irq_ptr->siga_flag.sync_after_ai)) | ||
397 | #define need_siga_sync_out_after_pci(q) \ | ||
398 | (unlikely(q->irq_ptr->siga_flag.sync_out_after_pci)) | ||
383 | 399 | ||
384 | #define for_each_input_queue(irq_ptr, q, i) \ | 400 | #define for_each_input_queue(irq_ptr, q, i) \ |
385 | for (i = 0, q = irq_ptr->input_qs[0]; \ | 401 | for (i = 0, q = irq_ptr->input_qs[0]; \ |
@@ -399,6 +415,26 @@ static inline int multicast_outbound(struct qdio_q *q) | |||
399 | #define sub_buf(bufnr, dec) \ | 415 | #define sub_buf(bufnr, dec) \ |
400 | ((bufnr - dec) & QDIO_MAX_BUFFERS_MASK) | 416 | ((bufnr - dec) & QDIO_MAX_BUFFERS_MASK) |
401 | 417 | ||
418 | #define queue_irqs_enabled(q) \ | ||
419 | (test_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state) == 0) | ||
420 | #define queue_irqs_disabled(q) \ | ||
421 | (test_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state) != 0) | ||
422 | |||
423 | #define TIQDIO_SHARED_IND 63 | ||
424 | |||
425 | /* device state change indicators */ | ||
426 | struct indicator_t { | ||
427 | u32 ind; /* u32 because of compare-and-swap performance */ | ||
428 | atomic_t count; /* use count, 0 or 1 for non-shared indicators */ | ||
429 | }; | ||
430 | |||
431 | extern struct indicator_t *q_indicators; | ||
432 | |||
433 | static inline int shared_ind(u32 *dsci) | ||
434 | { | ||
435 | return dsci == &q_indicators[TIQDIO_SHARED_IND].ind; | ||
436 | } | ||
437 | |||
402 | /* prototypes for thin interrupt */ | 438 | /* prototypes for thin interrupt */ |
403 | void qdio_setup_thinint(struct qdio_irq *irq_ptr); | 439 | void qdio_setup_thinint(struct qdio_irq *irq_ptr); |
404 | int qdio_establish_thinint(struct qdio_irq *irq_ptr); | 440 | int qdio_establish_thinint(struct qdio_irq *irq_ptr); |