aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/qdio.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/cio/qdio.h')
-rw-r--r--drivers/s390/cio/qdio.h104
1 files changed, 70 insertions, 34 deletions
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index 328e31cc6854..b5d303e79a24 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -3,14 +3,13 @@
3 3
4#include <asm/page.h> 4#include <asm/page.h>
5 5
6#define VERSION_CIO_QDIO_H "$Revision: 1.33 $" 6#define VERSION_CIO_QDIO_H "$Revision: 1.37 $"
7 7
8#ifdef CONFIG_QDIO_DEBUG 8#ifdef CONFIG_QDIO_DEBUG
9#define QDIO_VERBOSE_LEVEL 9 9#define QDIO_VERBOSE_LEVEL 9
10#else /* CONFIG_QDIO_DEBUG */ 10#else /* CONFIG_QDIO_DEBUG */
11#define QDIO_VERBOSE_LEVEL 5 11#define QDIO_VERBOSE_LEVEL 5
12#endif /* CONFIG_QDIO_DEBUG */ 12#endif /* CONFIG_QDIO_DEBUG */
13
14#define QDIO_USE_PROCESSING_STATE 13#define QDIO_USE_PROCESSING_STATE
15 14
16#ifdef CONFIG_QDIO_PERF_STATS 15#ifdef CONFIG_QDIO_PERF_STATS
@@ -265,6 +264,58 @@ QDIO_PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \
265/* 264/*
266 * Some instructions as assembly 265 * Some instructions as assembly
267 */ 266 */
267
268static inline int
269do_sqbs(unsigned long sch, unsigned char state, int queue,
270 unsigned int *start, unsigned int *count)
271{
272#ifdef CONFIG_ARCH_S390X
273 register unsigned long _ccq asm ("0") = *count;
274 register unsigned long _sch asm ("1") = sch;
275 unsigned long _queuestart = ((unsigned long)queue << 32) | *start;
276
277 asm volatile (
278 " .insn rsy,0xeb000000008A,%1,0,0(%2)\n\t"
279 : "+d" (_ccq), "+d" (_queuestart)
280 : "d" ((unsigned long)state), "d" (_sch)
281 : "memory", "cc"
282 );
283 *count = _ccq & 0xff;
284 *start = _queuestart & 0xff;
285
286 return (_ccq >> 32) & 0xff;
287#else
288 return 0;
289#endif
290}
291
292static inline int
293do_eqbs(unsigned long sch, unsigned char *state, int queue,
294 unsigned int *start, unsigned int *count)
295{
296#ifdef CONFIG_ARCH_S390X
297 register unsigned long _ccq asm ("0") = *count;
298 register unsigned long _sch asm ("1") = sch;
299 unsigned long _queuestart = ((unsigned long)queue << 32) | *start;
300 unsigned long _state = 0;
301
302 asm volatile (
303 " .insn rrf,0xB99c0000,%1,%2,0,0 \n\t"
304 : "+d" (_ccq), "+d" (_queuestart), "+d" (_state)
305 : "d" (_sch)
306 : "memory", "cc"
307 );
308 *count = _ccq & 0xff;
309 *start = _queuestart & 0xff;
310 *state = _state & 0xff;
311
312 return (_ccq >> 32) & 0xff;
313#else
314 return 0;
315#endif
316}
317
318
268static inline int 319static inline int
269do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2) 320do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2)
270{ 321{
@@ -280,7 +331,7 @@ do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2)
280 "ipm %0 \n\t" 331 "ipm %0 \n\t"
281 "srl %0,28 \n\t" 332 "srl %0,28 \n\t"
282 : "=d" (cc) 333 : "=d" (cc)
283 : "d" (0x10000|irq), "d" (mask1), "d" (mask2) 334 : "d" (irq), "d" (mask1), "d" (mask2)
284 : "cc", "0", "1", "2", "3" 335 : "cc", "0", "1", "2", "3"
285 ); 336 );
286#else /* CONFIG_ARCH_S390X */ 337#else /* CONFIG_ARCH_S390X */
@@ -293,7 +344,7 @@ do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2)
293 "ipm %0 \n\t" 344 "ipm %0 \n\t"
294 "srl %0,28 \n\t" 345 "srl %0,28 \n\t"
295 : "=d" (cc) 346 : "=d" (cc)
296 : "d" (0x10000|irq), "d" (mask1), "d" (mask2) 347 : "d" (irq), "d" (mask1), "d" (mask2)
297 : "cc", "0", "1", "2", "3" 348 : "cc", "0", "1", "2", "3"
298 ); 349 );
299#endif /* CONFIG_ARCH_S390X */ 350#endif /* CONFIG_ARCH_S390X */
@@ -314,7 +365,7 @@ do_siga_input(unsigned int irq, unsigned int mask)
314 "ipm %0 \n\t" 365 "ipm %0 \n\t"
315 "srl %0,28 \n\t" 366 "srl %0,28 \n\t"
316 : "=d" (cc) 367 : "=d" (cc)
317 : "d" (0x10000|irq), "d" (mask) 368 : "d" (irq), "d" (mask)
318 : "cc", "0", "1", "2", "memory" 369 : "cc", "0", "1", "2", "memory"
319 ); 370 );
320#else /* CONFIG_ARCH_S390X */ 371#else /* CONFIG_ARCH_S390X */
@@ -326,7 +377,7 @@ do_siga_input(unsigned int irq, unsigned int mask)
326 "ipm %0 \n\t" 377 "ipm %0 \n\t"
327 "srl %0,28 \n\t" 378 "srl %0,28 \n\t"
328 : "=d" (cc) 379 : "=d" (cc)
329 : "d" (0x10000|irq), "d" (mask) 380 : "d" (irq), "d" (mask)
330 : "cc", "0", "1", "2", "memory" 381 : "cc", "0", "1", "2", "memory"
331 ); 382 );
332#endif /* CONFIG_ARCH_S390X */ 383#endif /* CONFIG_ARCH_S390X */
@@ -335,7 +386,8 @@ do_siga_input(unsigned int irq, unsigned int mask)
335} 386}
336 387
337static inline int 388static inline int
338do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb) 389do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb,
390 unsigned int fc)
339{ 391{
340 int cc; 392 int cc;
341 __u32 busy_bit; 393 __u32 busy_bit;
@@ -366,14 +418,14 @@ do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb)
366 ".long 0b,2b \n\t" 418 ".long 0b,2b \n\t"
367 ".previous \n\t" 419 ".previous \n\t"
368 : "=d" (cc), "=d" (busy_bit) 420 : "=d" (cc), "=d" (busy_bit)
369 : "d" (0x10000|irq), "d" (mask), 421 : "d" (irq), "d" (mask),
370 "i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION) 422 "i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION)
371 : "cc", "0", "1", "2", "memory" 423 : "cc", "0", "1", "2", "memory"
372 ); 424 );
373#else /* CONFIG_ARCH_S390X */ 425#else /* CONFIG_ARCH_S390X */
374 asm volatile ( 426 asm volatile (
375 "lghi 0,0 \n\t" 427 "llgfr 0,%5 \n\t"
376 "llgfr 1,%2 \n\t" 428 "lgr 1,%2 \n\t"
377 "llgfr 2,%3 \n\t" 429 "llgfr 2,%3 \n\t"
378 "siga 0 \n\t" 430 "siga 0 \n\t"
379 "0:" 431 "0:"
@@ -391,8 +443,8 @@ do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb)
391 ".quad 0b,1b \n\t" 443 ".quad 0b,1b \n\t"
392 ".previous \n\t" 444 ".previous \n\t"
393 : "=d" (cc), "=d" (busy_bit) 445 : "=d" (cc), "=d" (busy_bit)
394 : "d" (0x10000|irq), "d" (mask), 446 : "d" (irq), "d" (mask),
395 "i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION) 447 "i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION), "d" (fc)
396 : "cc", "0", "1", "2", "memory" 448 : "cc", "0", "1", "2", "memory"
397 ); 449 );
398#endif /* CONFIG_ARCH_S390X */ 450#endif /* CONFIG_ARCH_S390X */
@@ -494,33 +546,12 @@ struct qdio_perf_stats {
494#define QDIO_GET_ADDR(x) ((__u32)(long)x) 546#define QDIO_GET_ADDR(x) ((__u32)(long)x)
495#endif /* CONFIG_ARCH_S390X */ 547#endif /* CONFIG_ARCH_S390X */
496 548
497#ifdef CONFIG_QDIO_DEBUG
498#define set_slsb(x,y) \
499 if(q->queue_type==QDIO_TRACE_QTYPE) { \
500 if(q->is_input_q) { \
501 QDIO_DBF_HEX2(0,slsb_in,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \
502 } else { \
503 QDIO_DBF_HEX2(0,slsb_out,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \
504 } \
505 } \
506 qdio_set_slsb(x,y); \
507 if(q->queue_type==QDIO_TRACE_QTYPE) { \
508 if(q->is_input_q) { \
509 QDIO_DBF_HEX2(0,slsb_in,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \
510 } else { \
511 QDIO_DBF_HEX2(0,slsb_out,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \
512 } \
513 }
514#else /* CONFIG_QDIO_DEBUG */
515#define set_slsb(x,y) qdio_set_slsb(x,y)
516#endif /* CONFIG_QDIO_DEBUG */
517
518struct qdio_q { 549struct qdio_q {
519 volatile struct slsb slsb; 550 volatile struct slsb slsb;
520 551
521 char unused[QDIO_MAX_BUFFERS_PER_Q]; 552 char unused[QDIO_MAX_BUFFERS_PER_Q];
522 553
523 __u32 * volatile dev_st_chg_ind; 554 __u32 * dev_st_chg_ind;
524 555
525 int is_input_q; 556 int is_input_q;
526 int irq; 557 int irq;
@@ -568,6 +599,7 @@ struct qdio_q {
568 struct tasklet_struct tasklet; 599 struct tasklet_struct tasklet;
569#endif /* QDIO_USE_TIMERS_FOR_POLLING */ 600#endif /* QDIO_USE_TIMERS_FOR_POLLING */
570 601
602
571 enum qdio_irq_states state; 603 enum qdio_irq_states state;
572 604
573 /* used to store the error condition during a data transfer */ 605 /* used to store the error condition during a data transfer */
@@ -624,6 +656,10 @@ struct qdio_irq {
624 unsigned int hydra_gives_outbound_pcis; 656 unsigned int hydra_gives_outbound_pcis;
625 unsigned int sync_done_on_outb_pcis; 657 unsigned int sync_done_on_outb_pcis;
626 658
659 /* QEBSM facility */
660 unsigned int is_qebsm;
661 unsigned long sch_token;
662
627 enum qdio_irq_states state; 663 enum qdio_irq_states state;
628 664
629 unsigned int no_input_qs; 665 unsigned int no_input_qs;