aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/qdio.h
diff options
context:
space:
mode:
authorFrank Pavlic <pavlic@de.ibm.com>2006-01-06 03:19:20 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-06 11:33:51 -0500
commit8129ee164267dc030b8e1d541ee3643c0b9f2fa1 (patch)
treeca477e575a9098e637411332a8d354477143eff4 /drivers/s390/cio/qdio.h
parent05f29fcdb0c6c99484c8bea5e244fe2f4edc9337 (diff)
[PATCH] s390: qdio V=V pass-through
New feature V=V qdio pass-through. QDIO and HiperSockets processing in z/VM V=V guest environments (as well as V=R with z/VM running in LPAR mode) requires shadowing of all QDIO architecture queue elements. Especially the shadowing of SBALs and SLSBs structures in the hypervisor, and the need to issue SIGA SYNC operations to observe state changes, eventually causes significant CPU processing overhead in the hypervisor. The QDIO pass-through support for V=V guests avoids the shadowing of SBALs and SLSBs. This significantly reduces the hypervisor overhead for QDIO based I/O. Signed-off-by: Frank Pavlic <pavlic@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
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;