aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--arch/s390/Kconfig7
-rw-r--r--drivers/s390/cio/chsc.h4
-rw-r--r--drivers/s390/cio/qdio.c589
-rw-r--r--drivers/s390/cio/qdio.h104
-rw-r--r--include/asm-s390/qdio.h8
5 files changed, 556 insertions, 156 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 477ac2758bd5..1846fbfd6bf2 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -240,8 +240,8 @@ config MACHCHK_WARNING
240config QDIO 240config QDIO
241 tristate "QDIO support" 241 tristate "QDIO support"
242 ---help--- 242 ---help---
243 This driver provides the Queued Direct I/O base support for the 243 This driver provides the Queued Direct I/O base support for
244 IBM S/390 (G5 and G6) and eServer zSeries (z800, z890, z900 and z990). 244 IBM mainframes.
245 245
246 For details please refer to the documentation provided by IBM at 246 For details please refer to the documentation provided by IBM at
247 <http://www10.software.ibm.com/developerworks/opensource/linux390> 247 <http://www10.software.ibm.com/developerworks/opensource/linux390>
@@ -263,7 +263,8 @@ config QDIO_DEBUG
263 bool "Extended debugging information" 263 bool "Extended debugging information"
264 depends on QDIO 264 depends on QDIO
265 help 265 help
266 Say Y here to get extended debugging output in /proc/s390dbf/qdio... 266 Say Y here to get extended debugging output in
267 /sys/kernel/debug/s390dbf/qdio...
267 Warning: this option reduces the performance of the QDIO module. 268 Warning: this option reduces the performance of the QDIO module.
268 269
269 If unsure, say N. 270 If unsure, say N.
diff --git a/drivers/s390/cio/chsc.h b/drivers/s390/cio/chsc.h
index be20da49d147..69450134bec7 100644
--- a/drivers/s390/cio/chsc.h
+++ b/drivers/s390/cio/chsc.h
@@ -43,7 +43,9 @@ struct css_general_char {
43 u32 ext_mb : 1; /* bit 48 */ 43 u32 ext_mb : 1; /* bit 48 */
44 u32 : 7; 44 u32 : 7;
45 u32 aif_tdd : 1; /* bit 56 */ 45 u32 aif_tdd : 1; /* bit 56 */
46 u32 : 10; 46 u32 : 1;
47 u32 qebsm : 1; /* bit 58 */
48 u32 : 8;
47 u32 aif_osa : 1; /* bit 67 */ 49 u32 aif_osa : 1; /* bit 67 */
48 u32 : 28; 50 u32 : 28;
49}__attribute__((packed)); 51}__attribute__((packed));
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index eb39218b925e..e8bdfcd1d02a 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -56,7 +56,7 @@
56#include "ioasm.h" 56#include "ioasm.h"
57#include "chsc.h" 57#include "chsc.h"
58 58
59#define VERSION_QDIO_C "$Revision: 1.108 $" 59#define VERSION_QDIO_C "$Revision: 1.113 $"
60 60
61/****************** MODULE PARAMETER VARIABLES ********************/ 61/****************** MODULE PARAMETER VARIABLES ********************/
62MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>"); 62MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
@@ -76,6 +76,7 @@ static struct qdio_perf_stats perf_stats;
76#endif /* QDIO_PERFORMANCE_STATS */ 76#endif /* QDIO_PERFORMANCE_STATS */
77 77
78static int hydra_thinints; 78static int hydra_thinints;
79static int is_passthrough = 0;
79static int omit_svs; 80static int omit_svs;
80 81
81static int indicator_used[INDICATORS_PER_CACHELINE]; 82static int indicator_used[INDICATORS_PER_CACHELINE];
@@ -136,12 +137,126 @@ qdio_release_q(struct qdio_q *q)
136 atomic_dec(&q->use_count); 137 atomic_dec(&q->use_count);
137} 138}
138 139
139static volatile inline void 140/*check ccq */
140qdio_set_slsb(volatile char *slsb, unsigned char value) 141static inline int
142qdio_check_ccq(struct qdio_q *q, unsigned int ccq)
141{ 143{
142 xchg((char*)slsb,value); 144 char dbf_text[15];
145
146 if (ccq == 0 || ccq == 32 || ccq == 96)
147 return 0;
148 if (ccq == 97)
149 return 1;
150 /*notify devices immediately*/
151 sprintf(dbf_text,"%d", ccq);
152 QDIO_DBF_TEXT2(1,trace,dbf_text);
153 return -EIO;
143} 154}
155/* EQBS: extract buffer states */
156static inline int
157qdio_do_eqbs(struct qdio_q *q, unsigned char *state,
158 unsigned int *start, unsigned int *cnt)
159{
160 struct qdio_irq *irq;
161 unsigned int tmp_cnt, q_no, ccq;
162 int rc ;
163 char dbf_text[15];
144 164
165 ccq = 0;
166 tmp_cnt = *cnt;
167 irq = (struct qdio_irq*)q->irq_ptr;
168 q_no = q->q_no;
169 if(!q->is_input_q)
170 q_no += irq->no_input_qs;
171 ccq = do_eqbs(irq->sch_token, state, q_no, start, cnt);
172 rc = qdio_check_ccq(q, ccq);
173 if (rc < 0) {
174 QDIO_DBF_TEXT2(1,trace,"eqberr");
175 sprintf(dbf_text,"%2x,%2x,%d,%d",tmp_cnt, *cnt, ccq, q_no);
176 QDIO_DBF_TEXT2(1,trace,dbf_text);
177 q->handler(q->cdev,QDIO_STATUS_ACTIVATE_CHECK_CONDITION|
178 QDIO_STATUS_LOOK_FOR_ERROR,
179 0, 0, 0, -1, -1, q->int_parm);
180 return 0;
181 }
182 return (tmp_cnt - *cnt);
183}
184
185/* SQBS: set buffer states */
186static inline int
187qdio_do_sqbs(struct qdio_q *q, unsigned char state,
188 unsigned int *start, unsigned int *cnt)
189{
190 struct qdio_irq *irq;
191 unsigned int tmp_cnt, q_no, ccq;
192 int rc;
193 char dbf_text[15];
194
195 ccq = 0;
196 tmp_cnt = *cnt;
197 irq = (struct qdio_irq*)q->irq_ptr;
198 q_no = q->q_no;
199 if(!q->is_input_q)
200 q_no += irq->no_input_qs;
201 ccq = do_sqbs(irq->sch_token, state, q_no, start, cnt);
202 rc = qdio_check_ccq(q, ccq);
203 if (rc < 0) {
204 QDIO_DBF_TEXT3(1,trace,"sqberr");
205 sprintf(dbf_text,"%2x,%2x,%d,%d",tmp_cnt,*cnt,ccq,q_no);
206 QDIO_DBF_TEXT3(1,trace,dbf_text);
207 q->handler(q->cdev,QDIO_STATUS_ACTIVATE_CHECK_CONDITION|
208 QDIO_STATUS_LOOK_FOR_ERROR,
209 0, 0, 0, -1, -1, q->int_parm);
210 return 0;
211 }
212 return (tmp_cnt - *cnt);
213}
214
215static inline int
216qdio_set_slsb(struct qdio_q *q, unsigned int *bufno,
217 unsigned char state, unsigned int *count)
218{
219 volatile char *slsb;
220 struct qdio_irq *irq;
221
222 irq = (struct qdio_irq*)q->irq_ptr;
223 if (!irq->is_qebsm) {
224 slsb = (char *)&q->slsb.acc.val[(*bufno)];
225 xchg(slsb, state);
226 return 1;
227 }
228 return qdio_do_sqbs(q, state, bufno, count);
229}
230
231#ifdef CONFIG_QDIO_DEBUG
232static inline void
233qdio_trace_slsb(struct qdio_q *q)
234{
235 if (q->queue_type==QDIO_TRACE_QTYPE) {
236 if (q->is_input_q)
237 QDIO_DBF_HEX2(0,slsb_in,&q->slsb,
238 QDIO_MAX_BUFFERS_PER_Q);
239 else
240 QDIO_DBF_HEX2(0,slsb_out,&q->slsb,
241 QDIO_MAX_BUFFERS_PER_Q);
242 }
243}
244#endif
245
246static inline int
247set_slsb(struct qdio_q *q, unsigned int *bufno,
248 unsigned char state, unsigned int *count)
249{
250 int rc;
251#ifdef CONFIG_QDIO_DEBUG
252 qdio_trace_slsb(q);
253#endif
254 rc = qdio_set_slsb(q, bufno, state, count);
255#ifdef CONFIG_QDIO_DEBUG
256 qdio_trace_slsb(q);
257#endif
258 return rc;
259}
145static inline int 260static inline int
146qdio_siga_sync(struct qdio_q *q, unsigned int gpr2, 261qdio_siga_sync(struct qdio_q *q, unsigned int gpr2,
147 unsigned int gpr3) 262 unsigned int gpr3)
@@ -155,7 +270,7 @@ qdio_siga_sync(struct qdio_q *q, unsigned int gpr2,
155 perf_stats.siga_syncs++; 270 perf_stats.siga_syncs++;
156#endif /* QDIO_PERFORMANCE_STATS */ 271#endif /* QDIO_PERFORMANCE_STATS */
157 272
158 cc = do_siga_sync(q->irq, gpr2, gpr3); 273 cc = do_siga_sync(0x10000|q->irq, gpr2, gpr3);
159 if (cc) 274 if (cc)
160 QDIO_DBF_HEX3(0,trace,&cc,sizeof(int*)); 275 QDIO_DBF_HEX3(0,trace,&cc,sizeof(int*));
161 276
@@ -170,6 +285,19 @@ qdio_siga_sync_q(struct qdio_q *q)
170 return qdio_siga_sync(q, q->mask, 0); 285 return qdio_siga_sync(q, q->mask, 0);
171} 286}
172 287
288static int
289__do_siga_output(struct qdio_q *q, unsigned int *busy_bit)
290{
291 struct qdio_irq *irq;
292 unsigned int fc = 0;
293
294 irq = (struct qdio_irq *) q->irq_ptr;
295 if (!irq->is_qebsm)
296 return do_siga_output(0x10000|q->irq, q->mask, busy_bit, fc);
297 fc |= 0x80;
298 return do_siga_output(irq->sch_token, q->mask, busy_bit, fc);
299}
300
173/* 301/*
174 * returns QDIO_SIGA_ERROR_ACCESS_EXCEPTION as cc, when SIGA returns 302 * returns QDIO_SIGA_ERROR_ACCESS_EXCEPTION as cc, when SIGA returns
175 * an access exception 303 * an access exception
@@ -189,7 +317,7 @@ qdio_siga_output(struct qdio_q *q)
189 QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); 317 QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
190 318
191 for (;;) { 319 for (;;) {
192 cc = do_siga_output(q->irq, q->mask, &busy_bit); 320 cc = __do_siga_output(q, &busy_bit);
193//QDIO_PRINT_ERR("cc=%x, busy=%x\n",cc,busy_bit); 321//QDIO_PRINT_ERR("cc=%x, busy=%x\n",cc,busy_bit);
194 if ((cc==2) && (busy_bit) && (q->is_iqdio_q)) { 322 if ((cc==2) && (busy_bit) && (q->is_iqdio_q)) {
195 if (!start_time) 323 if (!start_time)
@@ -221,7 +349,7 @@ qdio_siga_input(struct qdio_q *q)
221 perf_stats.siga_ins++; 349 perf_stats.siga_ins++;
222#endif /* QDIO_PERFORMANCE_STATS */ 350#endif /* QDIO_PERFORMANCE_STATS */
223 351
224 cc = do_siga_input(q->irq, q->mask); 352 cc = do_siga_input(0x10000|q->irq, q->mask);
225 353
226 if (cc) 354 if (cc)
227 QDIO_DBF_HEX3(0,trace,&cc,sizeof(int*)); 355 QDIO_DBF_HEX3(0,trace,&cc,sizeof(int*));
@@ -230,7 +358,7 @@ qdio_siga_input(struct qdio_q *q)
230} 358}
231 359
232/* locked by the locks in qdio_activate and qdio_cleanup */ 360/* locked by the locks in qdio_activate and qdio_cleanup */
233static __u32 volatile * 361static __u32 *
234qdio_get_indicator(void) 362qdio_get_indicator(void)
235{ 363{
236 int i; 364 int i;
@@ -258,7 +386,7 @@ qdio_put_indicator(__u32 *addr)
258 atomic_dec(&spare_indicator_usecount); 386 atomic_dec(&spare_indicator_usecount);
259} 387}
260 388
261static inline volatile void 389static inline void
262tiqdio_clear_summary_bit(__u32 *location) 390tiqdio_clear_summary_bit(__u32 *location)
263{ 391{
264 QDIO_DBF_TEXT5(0,trace,"clrsummb"); 392 QDIO_DBF_TEXT5(0,trace,"clrsummb");
@@ -267,7 +395,7 @@ tiqdio_clear_summary_bit(__u32 *location)
267 xchg(location,0); 395 xchg(location,0);
268} 396}
269 397
270static inline volatile void 398static inline void
271tiqdio_set_summary_bit(__u32 *location) 399tiqdio_set_summary_bit(__u32 *location)
272{ 400{
273 QDIO_DBF_TEXT5(0,trace,"setsummb"); 401 QDIO_DBF_TEXT5(0,trace,"setsummb");
@@ -336,7 +464,9 @@ static inline int
336qdio_stop_polling(struct qdio_q *q) 464qdio_stop_polling(struct qdio_q *q)
337{ 465{
338#ifdef QDIO_USE_PROCESSING_STATE 466#ifdef QDIO_USE_PROCESSING_STATE
339 int gsf; 467 unsigned int tmp, gsf, count = 1;
468 unsigned char state = 0;
469 struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr;
340 470
341 if (!atomic_swap(&q->polling,0)) 471 if (!atomic_swap(&q->polling,0))
342 return 1; 472 return 1;
@@ -348,17 +478,22 @@ qdio_stop_polling(struct qdio_q *q)
348 if (!q->is_input_q) 478 if (!q->is_input_q)
349 return 1; 479 return 1;
350 480
351 gsf=GET_SAVED_FRONTIER(q); 481 tmp = gsf = GET_SAVED_FRONTIER(q);
352 set_slsb(&q->slsb.acc.val[(gsf+QDIO_MAX_BUFFERS_PER_Q-1)& 482 tmp = ((tmp + QDIO_MAX_BUFFERS_PER_Q-1) & (QDIO_MAX_BUFFERS_PER_Q-1) );
353 (QDIO_MAX_BUFFERS_PER_Q-1)], 483 set_slsb(q, &tmp, SLSB_P_INPUT_NOT_INIT, &count);
354 SLSB_P_INPUT_NOT_INIT); 484
355 /* 485 /*
356 * we don't issue this SYNC_MEMORY, as we trust Rick T and 486 * we don't issue this SYNC_MEMORY, as we trust Rick T and
357 * moreover will not use the PROCESSING state under VM, so 487 * moreover will not use the PROCESSING state under VM, so
358 * q->polling was 0 anyway 488 * q->polling was 0 anyway
359 */ 489 */
360 /*SYNC_MEMORY;*/ 490 /*SYNC_MEMORY;*/
361 if (q->slsb.acc.val[gsf]!=SLSB_P_INPUT_PRIMED) 491 if (irq->is_qebsm) {
492 count = 1;
493 qdio_do_eqbs(q, &state, &gsf, &count);
494 } else
495 state = q->slsb.acc.val[gsf];
496 if (state != SLSB_P_INPUT_PRIMED)
362 return 1; 497 return 1;
363 /* 498 /*
364 * set our summary bit again, as otherwise there is a 499 * set our summary bit again, as otherwise there is a
@@ -431,18 +566,136 @@ tiqdio_clear_global_summary(void)
431 566
432 567
433/************************* OUTBOUND ROUTINES *******************************/ 568/************************* OUTBOUND ROUTINES *******************************/
569static int
570qdio_qebsm_get_outbound_buffer_frontier(struct qdio_q *q)
571{
572 struct qdio_irq *irq;
573 unsigned char state;
574 unsigned int cnt, count, ftc;
575
576 irq = (struct qdio_irq *) q->irq_ptr;
577 if ((!q->is_iqdio_q) && (!q->hydra_gives_outbound_pcis))
578 SYNC_MEMORY;
579
580 ftc = q->first_to_check;
581 count = qdio_min(atomic_read(&q->number_of_buffers_used),
582 (QDIO_MAX_BUFFERS_PER_Q-1));
583 if (count == 0)
584 return q->first_to_check;
585 cnt = qdio_do_eqbs(q, &state, &ftc, &count);
586 if (cnt == 0)
587 return q->first_to_check;
588 switch (state) {
589 case SLSB_P_OUTPUT_ERROR:
590 QDIO_DBF_TEXT3(0,trace,"outperr");
591 atomic_sub(cnt , &q->number_of_buffers_used);
592 if (q->qdio_error)
593 q->error_status_flags |=
594 QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR;
595 q->qdio_error = SLSB_P_OUTPUT_ERROR;
596 q->error_status_flags |= QDIO_STATUS_LOOK_FOR_ERROR;
597 q->first_to_check = ftc;
598 break;
599 case SLSB_P_OUTPUT_EMPTY:
600 QDIO_DBF_TEXT5(0,trace,"outpempt");
601 atomic_sub(cnt, &q->number_of_buffers_used);
602 q->first_to_check = ftc;
603 break;
604 case SLSB_CU_OUTPUT_PRIMED:
605 /* all buffers primed */
606 QDIO_DBF_TEXT5(0,trace,"outpprim");
607 break;
608 default:
609 break;
610 }
611 QDIO_DBF_HEX4(0,trace,&q->first_to_check,sizeof(int));
612 return q->first_to_check;
613}
614
615static int
616qdio_qebsm_get_inbound_buffer_frontier(struct qdio_q *q)
617{
618 struct qdio_irq *irq;
619 unsigned char state;
620 int tmp, ftc, count, cnt;
621 char dbf_text[15];
622
623
624 irq = (struct qdio_irq *) q->irq_ptr;
625 ftc = q->first_to_check;
626 count = qdio_min(atomic_read(&q->number_of_buffers_used),
627 (QDIO_MAX_BUFFERS_PER_Q-1));
628 if (count == 0)
629 return q->first_to_check;
630 cnt = qdio_do_eqbs(q, &state, &ftc, &count);
631 if (cnt == 0)
632 return q->first_to_check;
633 switch (state) {
634 case SLSB_P_INPUT_ERROR :
635#ifdef CONFIG_QDIO_DEBUG
636 QDIO_DBF_TEXT3(1,trace,"inperr");
637 sprintf(dbf_text,"%2x,%2x",ftc,count);
638 QDIO_DBF_TEXT3(1,trace,dbf_text);
639#endif /* CONFIG_QDIO_DEBUG */
640 if (q->qdio_error)
641 q->error_status_flags |=
642 QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR;
643 q->qdio_error = SLSB_P_INPUT_ERROR;
644 q->error_status_flags |= QDIO_STATUS_LOOK_FOR_ERROR;
645 atomic_sub(cnt, &q->number_of_buffers_used);
646 q->first_to_check = ftc;
647 break;
648 case SLSB_P_INPUT_PRIMED :
649 QDIO_DBF_TEXT3(0,trace,"inptprim");
650 sprintf(dbf_text,"%2x,%2x",ftc,count);
651 QDIO_DBF_TEXT3(1,trace,dbf_text);
652 tmp = 0;
653 ftc = q->first_to_check;
654#ifdef QDIO_USE_PROCESSING_STATE
655 if (cnt > 1) {
656 cnt -= 1;
657 tmp = set_slsb(q, &ftc, SLSB_P_INPUT_NOT_INIT, &cnt);
658 if (!tmp)
659 break;
660 }
661 cnt = 1;
662 tmp += set_slsb(q, &ftc,
663 SLSB_P_INPUT_PROCESSING, &cnt);
664 atomic_set(&q->polling, 1);
665#else
666 tmp = set_slsb(q, &ftc, SLSB_P_INPUT_NOT_INIT, &cnt);
667#endif
668 atomic_sub(tmp, &q->number_of_buffers_used);
669 q->first_to_check = ftc;
670 break;
671 case SLSB_CU_INPUT_EMPTY:
672 case SLSB_P_INPUT_NOT_INIT:
673 case SLSB_P_INPUT_PROCESSING:
674 QDIO_DBF_TEXT5(0,trace,"inpnipro");
675 break;
676 default:
677 break;
678 }
679 QDIO_DBF_HEX4(0,trace,&q->first_to_check,sizeof(int));
680 return q->first_to_check;
681}
434 682
435static inline int 683static inline int
436qdio_get_outbound_buffer_frontier(struct qdio_q *q) 684qdio_get_outbound_buffer_frontier(struct qdio_q *q)
437{ 685{
438 int f,f_mod_no; 686 struct qdio_irq *irq;
439 volatile char *slsb; 687 volatile char *slsb;
440 int first_not_to_check; 688 unsigned int count = 1;
689 int first_not_to_check, f, f_mod_no;
441 char dbf_text[15]; 690 char dbf_text[15];
442 691
443 QDIO_DBF_TEXT4(0,trace,"getobfro"); 692 QDIO_DBF_TEXT4(0,trace,"getobfro");
444 QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); 693 QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
445 694
695 irq = (struct qdio_irq *) q->irq_ptr;
696 if (irq->is_qebsm)
697 return qdio_qebsm_get_outbound_buffer_frontier(q);
698
446 slsb=&q->slsb.acc.val[0]; 699 slsb=&q->slsb.acc.val[0];
447 f_mod_no=f=q->first_to_check; 700 f_mod_no=f=q->first_to_check;
448 /* 701 /*
@@ -484,7 +737,7 @@ check_next:
484 QDIO_DBF_HEX2(1,sbal,q->sbal[f_mod_no],256); 737 QDIO_DBF_HEX2(1,sbal,q->sbal[f_mod_no],256);
485 738
486 /* kind of process the buffer */ 739 /* kind of process the buffer */
487 set_slsb(&q->slsb.acc.val[f_mod_no], SLSB_P_OUTPUT_NOT_INIT); 740 set_slsb(q, &f_mod_no, SLSB_P_OUTPUT_NOT_INIT, &count);
488 741
489 /* 742 /*
490 * we increment the frontier, as this buffer 743 * we increment the frontier, as this buffer
@@ -597,48 +850,48 @@ qdio_kick_outbound_q(struct qdio_q *q)
597 850
598 result=qdio_siga_output(q); 851 result=qdio_siga_output(q);
599 852
600 switch (result) { 853 switch (result) {
601 case 0: 854 case 0:
602 /* went smooth this time, reset timestamp */ 855 /* went smooth this time, reset timestamp */
603#ifdef CONFIG_QDIO_DEBUG 856#ifdef CONFIG_QDIO_DEBUG
604 QDIO_DBF_TEXT3(0,trace,"cc2reslv"); 857 QDIO_DBF_TEXT3(0,trace,"cc2reslv");
605 sprintf(dbf_text,"%4x%2x%2x",q->irq,q->q_no, 858 sprintf(dbf_text,"%4x%2x%2x",q->irq,q->q_no,
606 atomic_read(&q->busy_siga_counter)); 859 atomic_read(&q->busy_siga_counter));
607 QDIO_DBF_TEXT3(0,trace,dbf_text); 860 QDIO_DBF_TEXT3(0,trace,dbf_text);
608#endif /* CONFIG_QDIO_DEBUG */ 861#endif /* CONFIG_QDIO_DEBUG */
609 q->timing.busy_start=0; 862 q->timing.busy_start=0;
863 break;
864 case (2|QDIO_SIGA_ERROR_B_BIT_SET):
865 /* cc=2 and busy bit: */
866 atomic_inc(&q->busy_siga_counter);
867
868 /* if the last siga was successful, save
869 * timestamp here */
870 if (!q->timing.busy_start)
871 q->timing.busy_start=NOW;
872
873 /* if we're in time, don't touch error_status_flags
874 * and siga_error */
875 if (NOW-q->timing.busy_start<QDIO_BUSY_BIT_GIVE_UP) {
876 qdio_mark_q(q);
610 break; 877 break;
611 case (2|QDIO_SIGA_ERROR_B_BIT_SET): 878 }
612 /* cc=2 and busy bit: */ 879 QDIO_DBF_TEXT2(0,trace,"cc2REPRT");
613 atomic_inc(&q->busy_siga_counter);
614
615 /* if the last siga was successful, save
616 * timestamp here */
617 if (!q->timing.busy_start)
618 q->timing.busy_start=NOW;
619
620 /* if we're in time, don't touch error_status_flags
621 * and siga_error */
622 if (NOW-q->timing.busy_start<QDIO_BUSY_BIT_GIVE_UP) {
623 qdio_mark_q(q);
624 break;
625 }
626 QDIO_DBF_TEXT2(0,trace,"cc2REPRT");
627#ifdef CONFIG_QDIO_DEBUG 880#ifdef CONFIG_QDIO_DEBUG
628 sprintf(dbf_text,"%4x%2x%2x",q->irq,q->q_no, 881 sprintf(dbf_text,"%4x%2x%2x",q->irq,q->q_no,
629 atomic_read(&q->busy_siga_counter)); 882 atomic_read(&q->busy_siga_counter));
630 QDIO_DBF_TEXT3(0,trace,dbf_text); 883 QDIO_DBF_TEXT3(0,trace,dbf_text);
631#endif /* CONFIG_QDIO_DEBUG */ 884#endif /* CONFIG_QDIO_DEBUG */
632 /* else fallthrough and report error */ 885 /* else fallthrough and report error */
633 default: 886 default:
634 /* for plain cc=1, 2 or 3: */ 887 /* for plain cc=1, 2 or 3: */
635 if (q->siga_error) 888 if (q->siga_error)
636 q->error_status_flags|=
637 QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR;
638 q->error_status_flags|= 889 q->error_status_flags|=
639 QDIO_STATUS_LOOK_FOR_ERROR; 890 QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR;
640 q->siga_error=result; 891 q->error_status_flags|=
641 } 892 QDIO_STATUS_LOOK_FOR_ERROR;
893 q->siga_error=result;
894 }
642} 895}
643 896
644static inline void 897static inline void
@@ -743,8 +996,10 @@ qdio_outbound_processing(struct qdio_q *q)
743static inline int 996static inline int
744qdio_get_inbound_buffer_frontier(struct qdio_q *q) 997qdio_get_inbound_buffer_frontier(struct qdio_q *q)
745{ 998{
999 struct qdio_irq *irq;
746 int f,f_mod_no; 1000 int f,f_mod_no;
747 volatile char *slsb; 1001 volatile char *slsb;
1002 unsigned int count = 1;
748 int first_not_to_check; 1003 int first_not_to_check;
749#ifdef CONFIG_QDIO_DEBUG 1004#ifdef CONFIG_QDIO_DEBUG
750 char dbf_text[15]; 1005 char dbf_text[15];
@@ -756,6 +1011,10 @@ qdio_get_inbound_buffer_frontier(struct qdio_q *q)
756 QDIO_DBF_TEXT4(0,trace,"getibfro"); 1011 QDIO_DBF_TEXT4(0,trace,"getibfro");
757 QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); 1012 QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
758 1013
1014 irq = (struct qdio_irq *) q->irq_ptr;
1015 if (irq->is_qebsm)
1016 return qdio_qebsm_get_inbound_buffer_frontier(q);
1017
759 slsb=&q->slsb.acc.val[0]; 1018 slsb=&q->slsb.acc.val[0];
760 f_mod_no=f=q->first_to_check; 1019 f_mod_no=f=q->first_to_check;
761 /* 1020 /*
@@ -792,19 +1051,19 @@ check_next:
792 * kill VM in terms of CP overhead 1051 * kill VM in terms of CP overhead
793 */ 1052 */
794 if (q->siga_sync) { 1053 if (q->siga_sync) {
795 set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_NOT_INIT); 1054 set_slsb(q, &f_mod_no, SLSB_P_INPUT_NOT_INIT, &count);
796 } else { 1055 } else {
797 /* set the previous buffer to NOT_INIT. The current 1056 /* set the previous buffer to NOT_INIT. The current
798 * buffer will be set to PROCESSING at the end of 1057 * buffer will be set to PROCESSING at the end of
799 * this function to avoid further interrupts. */ 1058 * this function to avoid further interrupts. */
800 if (last_position>=0) 1059 if (last_position>=0)
801 set_slsb(&slsb[last_position], 1060 set_slsb(q, &last_position,
802 SLSB_P_INPUT_NOT_INIT); 1061 SLSB_P_INPUT_NOT_INIT, &count);
803 atomic_set(&q->polling,1); 1062 atomic_set(&q->polling,1);
804 last_position=f_mod_no; 1063 last_position=f_mod_no;
805 } 1064 }
806#else /* QDIO_USE_PROCESSING_STATE */ 1065#else /* QDIO_USE_PROCESSING_STATE */
807 set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_NOT_INIT); 1066 set_slsb(q, &f_mod_no, SLSB_P_INPUT_NOT_INIT, &count);
808#endif /* QDIO_USE_PROCESSING_STATE */ 1067#endif /* QDIO_USE_PROCESSING_STATE */
809 /* 1068 /*
810 * not needed, as the inbound queue will be synced on the next 1069 * not needed, as the inbound queue will be synced on the next
@@ -829,7 +1088,7 @@ check_next:
829 QDIO_DBF_HEX2(1,sbal,q->sbal[f_mod_no],256); 1088 QDIO_DBF_HEX2(1,sbal,q->sbal[f_mod_no],256);
830 1089
831 /* kind of process the buffer */ 1090 /* kind of process the buffer */
832 set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_NOT_INIT); 1091 set_slsb(q, &f_mod_no, SLSB_P_INPUT_NOT_INIT, &count);
833 1092
834 if (q->qdio_error) 1093 if (q->qdio_error)
835 q->error_status_flags|= 1094 q->error_status_flags|=
@@ -857,7 +1116,7 @@ out:
857 1116
858#ifdef QDIO_USE_PROCESSING_STATE 1117#ifdef QDIO_USE_PROCESSING_STATE
859 if (last_position>=0) 1118 if (last_position>=0)
860 set_slsb(&slsb[last_position],SLSB_P_INPUT_PROCESSING); 1119 set_slsb(q, &last_position, SLSB_P_INPUT_NOT_INIT, &count);
861#endif /* QDIO_USE_PROCESSING_STATE */ 1120#endif /* QDIO_USE_PROCESSING_STATE */
862 1121
863 QDIO_DBF_HEX4(0,trace,&q->first_to_check,sizeof(int)); 1122 QDIO_DBF_HEX4(0,trace,&q->first_to_check,sizeof(int));
@@ -902,6 +1161,10 @@ static inline int
902tiqdio_is_inbound_q_done(struct qdio_q *q) 1161tiqdio_is_inbound_q_done(struct qdio_q *q)
903{ 1162{
904 int no_used; 1163 int no_used;
1164 unsigned int start_buf, count;
1165 unsigned char state = 0;
1166 struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr;
1167
905#ifdef CONFIG_QDIO_DEBUG 1168#ifdef CONFIG_QDIO_DEBUG
906 char dbf_text[15]; 1169 char dbf_text[15];
907#endif 1170#endif
@@ -927,8 +1190,13 @@ tiqdio_is_inbound_q_done(struct qdio_q *q)
927 if (!q->siga_sync) 1190 if (!q->siga_sync)
928 /* we'll check for more primed buffers in qeth_stop_polling */ 1191 /* we'll check for more primed buffers in qeth_stop_polling */
929 return 0; 1192 return 0;
930 1193 if (irq->is_qebsm) {
931 if (q->slsb.acc.val[q->first_to_check]!=SLSB_P_INPUT_PRIMED) 1194 count = 1;
1195 start_buf = q->first_to_check;
1196 qdio_do_eqbs(q, &state, &start_buf, &count);
1197 } else
1198 state = q->slsb.acc.val[q->first_to_check];
1199 if (state != SLSB_P_INPUT_PRIMED)
932 /* 1200 /*
933 * nothing more to do, if next buffer is not PRIMED. 1201 * nothing more to do, if next buffer is not PRIMED.
934 * note that we did a SYNC_MEMORY before, that there 1202 * note that we did a SYNC_MEMORY before, that there
@@ -955,6 +1223,10 @@ static inline int
955qdio_is_inbound_q_done(struct qdio_q *q) 1223qdio_is_inbound_q_done(struct qdio_q *q)
956{ 1224{
957 int no_used; 1225 int no_used;
1226 unsigned int start_buf, count;
1227 unsigned char state = 0;
1228 struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr;
1229
958#ifdef CONFIG_QDIO_DEBUG 1230#ifdef CONFIG_QDIO_DEBUG
959 char dbf_text[15]; 1231 char dbf_text[15];
960#endif 1232#endif
@@ -973,8 +1245,13 @@ qdio_is_inbound_q_done(struct qdio_q *q)
973 QDIO_DBF_TEXT4(0,trace,dbf_text); 1245 QDIO_DBF_TEXT4(0,trace,dbf_text);
974 return 1; 1246 return 1;
975 } 1247 }
976 1248 if (irq->is_qebsm) {
977 if (q->slsb.acc.val[q->first_to_check]==SLSB_P_INPUT_PRIMED) { 1249 count = 1;
1250 start_buf = q->first_to_check;
1251 qdio_do_eqbs(q, &state, &start_buf, &count);
1252 } else
1253 state = q->slsb.acc.val[q->first_to_check];
1254 if (state == SLSB_P_INPUT_PRIMED) {
978 /* we got something to do */ 1255 /* we got something to do */
979 QDIO_DBF_TEXT4(0,trace,"inqisntA"); 1256 QDIO_DBF_TEXT4(0,trace,"inqisntA");
980 QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); 1257 QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
@@ -1523,11 +1800,11 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev,
1523 QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*)); 1800 QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*));
1524 1801
1525 /* fill in slsb */ 1802 /* fill in slsb */
1526 for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) { 1803 if (!irq_ptr->is_qebsm) {
1527 set_slsb(&q->slsb.acc.val[j], 1804 unsigned int count = 1;
1528 SLSB_P_INPUT_NOT_INIT); 1805 for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++)
1529/* q->sbal[j]->element[1].sbalf.i1.key=QDIO_STORAGE_KEY;*/ 1806 set_slsb(q, &j, SLSB_P_INPUT_NOT_INIT, &count);
1530 } 1807 }
1531 } 1808 }
1532 1809
1533 for (i=0;i<no_output_qs;i++) { 1810 for (i=0;i<no_output_qs;i++) {
@@ -1584,11 +1861,11 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev,
1584 QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*)); 1861 QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*));
1585 1862
1586 /* fill in slsb */ 1863 /* fill in slsb */
1587 for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) { 1864 if (!irq_ptr->is_qebsm) {
1588 set_slsb(&q->slsb.acc.val[j], 1865 unsigned int count = 1;
1589 SLSB_P_OUTPUT_NOT_INIT); 1866 for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++)
1590/* q->sbal[j]->element[1].sbalf.i1.key=QDIO_STORAGE_KEY;*/ 1867 set_slsb(q, &j, SLSB_P_OUTPUT_NOT_INIT, &count);
1591 } 1868 }
1592 } 1869 }
1593} 1870}
1594 1871
@@ -1905,7 +2182,7 @@ int
1905qdio_synchronize(struct ccw_device *cdev, unsigned int flags, 2182qdio_synchronize(struct ccw_device *cdev, unsigned int flags,
1906 unsigned int queue_number) 2183 unsigned int queue_number)
1907{ 2184{
1908 int cc; 2185 int cc = 0;
1909 struct qdio_q *q; 2186 struct qdio_q *q;
1910 struct qdio_irq *irq_ptr; 2187 struct qdio_irq *irq_ptr;
1911 void *ptr; 2188 void *ptr;
@@ -1929,12 +2206,14 @@ qdio_synchronize(struct ccw_device *cdev, unsigned int flags,
1929 q=irq_ptr->input_qs[queue_number]; 2206 q=irq_ptr->input_qs[queue_number];
1930 if (!q) 2207 if (!q)
1931 return -EINVAL; 2208 return -EINVAL;
1932 cc = do_siga_sync(q->irq, 0, q->mask); 2209 if (!(irq_ptr->is_qebsm))
2210 cc = do_siga_sync(0x10000|q->irq, 0, q->mask);
1933 } else if (flags&QDIO_FLAG_SYNC_OUTPUT) { 2211 } else if (flags&QDIO_FLAG_SYNC_OUTPUT) {
1934 q=irq_ptr->output_qs[queue_number]; 2212 q=irq_ptr->output_qs[queue_number];
1935 if (!q) 2213 if (!q)
1936 return -EINVAL; 2214 return -EINVAL;
1937 cc = do_siga_sync(q->irq, q->mask, 0); 2215 if (!(irq_ptr->is_qebsm))
2216 cc = do_siga_sync(0x10000|q->irq, q->mask, 0);
1938 } else 2217 } else
1939 return -EINVAL; 2218 return -EINVAL;
1940 2219
@@ -1945,12 +2224,49 @@ qdio_synchronize(struct ccw_device *cdev, unsigned int flags,
1945 return cc; 2224 return cc;
1946} 2225}
1947 2226
1948static unsigned char 2227static inline void
1949qdio_check_siga_needs(int sch) 2228qdio_check_subchannel_qebsm(struct qdio_irq *irq_ptr, unsigned char qdioac,
2229 unsigned long token)
2230{
2231 struct qdio_q *q;
2232 int i;
2233 unsigned int count, start_buf;
2234 char dbf_text[15];
2235
2236 /*check if QEBSM is disabled */
2237 if (!(irq_ptr->is_qebsm) || !(qdioac & 0x01)) {
2238 irq_ptr->is_qebsm = 0;
2239 irq_ptr->sch_token = 0;
2240 irq_ptr->qib.rflags &= ~QIB_RFLAGS_ENABLE_QEBSM;
2241 QDIO_DBF_TEXT0(0,setup,"noV=V");
2242 return;
2243 }
2244 irq_ptr->sch_token = token;
2245 /*input queue*/
2246 for (i = 0; i < irq_ptr->no_input_qs;i++) {
2247 q = irq_ptr->input_qs[i];
2248 count = QDIO_MAX_BUFFERS_PER_Q;
2249 start_buf = 0;
2250 set_slsb(q, &start_buf, SLSB_P_INPUT_NOT_INIT, &count);
2251 }
2252 sprintf(dbf_text,"V=V:%2x",irq_ptr->is_qebsm);
2253 QDIO_DBF_TEXT0(0,setup,dbf_text);
2254 sprintf(dbf_text,"%8lx",irq_ptr->sch_token);
2255 QDIO_DBF_TEXT0(0,setup,dbf_text);
2256 /*output queue*/
2257 for (i = 0; i < irq_ptr->no_output_qs; i++) {
2258 q = irq_ptr->output_qs[i];
2259 count = QDIO_MAX_BUFFERS_PER_Q;
2260 start_buf = 0;
2261 set_slsb(q, &start_buf, SLSB_P_OUTPUT_NOT_INIT, &count);
2262 }
2263}
2264
2265static void
2266qdio_get_ssqd_information(struct qdio_irq *irq_ptr)
1950{ 2267{
1951 int result; 2268 int result;
1952 unsigned char qdioac; 2269 unsigned char qdioac;
1953
1954 struct { 2270 struct {
1955 struct chsc_header request; 2271 struct chsc_header request;
1956 u16 reserved1; 2272 u16 reserved1;
@@ -1964,67 +2280,80 @@ qdio_check_siga_needs(int sch)
1964 u8 reserved5; 2280 u8 reserved5;
1965 u16 sch; 2281 u16 sch;
1966 u8 qfmt; 2282 u8 qfmt;
1967 u8 reserved6; 2283 u8 parm;
1968 u8 qdioac; 2284 u8 qdioac1;
1969 u8 sch_class; 2285 u8 sch_class;
1970 u8 reserved7; 2286 u8 reserved7;
1971 u8 icnt; 2287 u8 icnt;
1972 u8 reserved8; 2288 u8 reserved8;
1973 u8 ocnt; 2289 u8 ocnt;
2290 u8 reserved9;
2291 u8 mbccnt;
2292 u16 qdioac2;
2293 u64 sch_token;
1974 } *ssqd_area; 2294 } *ssqd_area;
1975 2295
2296 QDIO_DBF_TEXT0(0,setup,"getssqd");
2297 qdioac = 0;
1976 ssqd_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 2298 ssqd_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
1977 if (!ssqd_area) { 2299 if (!ssqd_area) {
1978 QDIO_PRINT_WARN("Could not get memory for chsc. Using all " \ 2300 QDIO_PRINT_WARN("Could not get memory for chsc. Using all " \
1979 "SIGAs for sch x%x.\n", sch); 2301 "SIGAs for sch x%x.\n", irq_ptr->irq);
1980 return CHSC_FLAG_SIGA_INPUT_NECESSARY || 2302 irq_ptr->qdioac = CHSC_FLAG_SIGA_INPUT_NECESSARY ||
1981 CHSC_FLAG_SIGA_OUTPUT_NECESSARY || 2303 CHSC_FLAG_SIGA_OUTPUT_NECESSARY ||
1982 CHSC_FLAG_SIGA_SYNC_NECESSARY; /* all flags set */ 2304 CHSC_FLAG_SIGA_SYNC_NECESSARY; /* all flags set */
2305 irq_ptr->is_qebsm = 0;
2306 irq_ptr->sch_token = 0;
2307 irq_ptr->qib.rflags &= ~QIB_RFLAGS_ENABLE_QEBSM;
2308 return;
1983 } 2309 }
2310
1984 ssqd_area->request = (struct chsc_header) { 2311 ssqd_area->request = (struct chsc_header) {
1985 .length = 0x0010, 2312 .length = 0x0010,
1986 .code = 0x0024, 2313 .code = 0x0024,
1987 }; 2314 };
1988 2315 ssqd_area->first_sch = irq_ptr->irq;
1989 ssqd_area->first_sch = sch; 2316 ssqd_area->last_sch = irq_ptr->irq;
1990 ssqd_area->last_sch = sch; 2317 result = chsc(ssqd_area);
1991
1992 result=chsc(ssqd_area);
1993 2318
1994 if (result) { 2319 if (result) {
1995 QDIO_PRINT_WARN("CHSC returned cc %i. Using all " \ 2320 QDIO_PRINT_WARN("CHSC returned cc %i. Using all " \
1996 "SIGAs for sch x%x.\n", 2321 "SIGAs for sch x%x.\n",
1997 result,sch); 2322 result, irq_ptr->irq);
1998 qdioac = CHSC_FLAG_SIGA_INPUT_NECESSARY || 2323 qdioac = CHSC_FLAG_SIGA_INPUT_NECESSARY ||
1999 CHSC_FLAG_SIGA_OUTPUT_NECESSARY || 2324 CHSC_FLAG_SIGA_OUTPUT_NECESSARY ||
2000 CHSC_FLAG_SIGA_SYNC_NECESSARY; /* all flags set */ 2325 CHSC_FLAG_SIGA_SYNC_NECESSARY; /* all flags set */
2326 irq_ptr->is_qebsm = 0;
2001 goto out; 2327 goto out;
2002 } 2328 }
2003 2329
2004 if (ssqd_area->response.code != QDIO_CHSC_RESPONSE_CODE_OK) { 2330 if (ssqd_area->response.code != QDIO_CHSC_RESPONSE_CODE_OK) {
2005 QDIO_PRINT_WARN("response upon checking SIGA needs " \ 2331 QDIO_PRINT_WARN("response upon checking SIGA needs " \
2006 "is 0x%x. Using all SIGAs for sch x%x.\n", 2332 "is 0x%x. Using all SIGAs for sch x%x.\n",
2007 ssqd_area->response.code, sch); 2333 ssqd_area->response.code, irq_ptr->irq);
2008 qdioac = CHSC_FLAG_SIGA_INPUT_NECESSARY || 2334 qdioac = CHSC_FLAG_SIGA_INPUT_NECESSARY ||
2009 CHSC_FLAG_SIGA_OUTPUT_NECESSARY || 2335 CHSC_FLAG_SIGA_OUTPUT_NECESSARY ||
2010 CHSC_FLAG_SIGA_SYNC_NECESSARY; /* all flags set */ 2336 CHSC_FLAG_SIGA_SYNC_NECESSARY; /* all flags set */
2337 irq_ptr->is_qebsm = 0;
2011 goto out; 2338 goto out;
2012 } 2339 }
2013 if (!(ssqd_area->flags & CHSC_FLAG_QDIO_CAPABILITY) || 2340 if (!(ssqd_area->flags & CHSC_FLAG_QDIO_CAPABILITY) ||
2014 !(ssqd_area->flags & CHSC_FLAG_VALIDITY) || 2341 !(ssqd_area->flags & CHSC_FLAG_VALIDITY) ||
2015 (ssqd_area->sch != sch)) { 2342 (ssqd_area->sch != irq_ptr->irq)) {
2016 QDIO_PRINT_WARN("huh? problems checking out sch x%x... " \ 2343 QDIO_PRINT_WARN("huh? problems checking out sch x%x... " \
2017 "using all SIGAs.\n",sch); 2344 "using all SIGAs.\n",irq_ptr->irq);
2018 qdioac = CHSC_FLAG_SIGA_INPUT_NECESSARY | 2345 qdioac = CHSC_FLAG_SIGA_INPUT_NECESSARY |
2019 CHSC_FLAG_SIGA_OUTPUT_NECESSARY | 2346 CHSC_FLAG_SIGA_OUTPUT_NECESSARY |
2020 CHSC_FLAG_SIGA_SYNC_NECESSARY; /* worst case */ 2347 CHSC_FLAG_SIGA_SYNC_NECESSARY; /* worst case */
2348 irq_ptr->is_qebsm = 0;
2021 goto out; 2349 goto out;
2022 } 2350 }
2023 2351 qdioac = ssqd_area->qdioac1;
2024 qdioac = ssqd_area->qdioac;
2025out: 2352out:
2353 qdio_check_subchannel_qebsm(irq_ptr, qdioac,
2354 ssqd_area->sch_token);
2026 free_page ((unsigned long) ssqd_area); 2355 free_page ((unsigned long) ssqd_area);
2027 return qdioac; 2356 irq_ptr->qdioac = qdioac;
2028} 2357}
2029 2358
2030static unsigned int 2359static unsigned int
@@ -2055,6 +2384,13 @@ tiqdio_check_chsc_availability(void)
2055 sprintf(dbf_text,"hydrati%1x", hydra_thinints); 2384 sprintf(dbf_text,"hydrati%1x", hydra_thinints);
2056 QDIO_DBF_TEXT0(0,setup,dbf_text); 2385 QDIO_DBF_TEXT0(0,setup,dbf_text);
2057 2386
2387#ifdef CONFIG_ARCH_S390X
2388 /* Check for QEBSM support in general (bit 58). */
2389 is_passthrough = css_general_characteristics.qebsm;
2390#endif
2391 sprintf(dbf_text,"cssQBS:%1x", is_passthrough);
2392 QDIO_DBF_TEXT0(0,setup,dbf_text);
2393
2058 /* Check for aif time delay disablement fac (bit 56). If installed, 2394 /* Check for aif time delay disablement fac (bit 56). If installed,
2059 * omit svs even under lpar (good point by rick again) */ 2395 * omit svs even under lpar (good point by rick again) */
2060 omit_svs = css_general_characteristics.aif_tdd; 2396 omit_svs = css_general_characteristics.aif_tdd;
@@ -2698,7 +3034,7 @@ int qdio_fill_irq(struct qdio_initialize *init_data)
2698 QDIO_DBF_TEXT2(0,setup,dbf_text); 3034 QDIO_DBF_TEXT2(0,setup,dbf_text);
2699 3035
2700 if (irq_ptr->is_thinint_irq) { 3036 if (irq_ptr->is_thinint_irq) {
2701 irq_ptr->dev_st_chg_ind=qdio_get_indicator(); 3037 irq_ptr->dev_st_chg_ind = qdio_get_indicator();
2702 QDIO_DBF_HEX1(0,setup,&irq_ptr->dev_st_chg_ind,sizeof(void*)); 3038 QDIO_DBF_HEX1(0,setup,&irq_ptr->dev_st_chg_ind,sizeof(void*));
2703 if (!irq_ptr->dev_st_chg_ind) { 3039 if (!irq_ptr->dev_st_chg_ind) {
2704 QDIO_PRINT_WARN("no indicator location available " \ 3040 QDIO_PRINT_WARN("no indicator location available " \
@@ -2747,6 +3083,10 @@ int qdio_fill_irq(struct qdio_initialize *init_data)
2747 irq_ptr->qdr->qkey=QDIO_STORAGE_KEY; 3083 irq_ptr->qdr->qkey=QDIO_STORAGE_KEY;
2748 3084
2749 /* fill in qib */ 3085 /* fill in qib */
3086 irq_ptr->is_qebsm = is_passthrough;
3087 if (irq_ptr->is_qebsm)
3088 irq_ptr->qib.rflags |= QIB_RFLAGS_ENABLE_QEBSM;
3089
2750 irq_ptr->qib.qfmt=init_data->q_format; 3090 irq_ptr->qib.qfmt=init_data->q_format;
2751 if (init_data->no_input_qs) 3091 if (init_data->no_input_qs)
2752 irq_ptr->qib.isliba=(unsigned long)(irq_ptr->input_qs[0]->slib); 3092 irq_ptr->qib.isliba=(unsigned long)(irq_ptr->input_qs[0]->slib);
@@ -2884,7 +3224,7 @@ qdio_establish(struct qdio_initialize *init_data)
2884 return -EIO; 3224 return -EIO;
2885 } 3225 }
2886 3226
2887 irq_ptr->qdioac=qdio_check_siga_needs(irq_ptr->irq); 3227 qdio_get_ssqd_information(irq_ptr);
2888 /* if this gets set once, we're running under VM and can omit SVSes */ 3228 /* if this gets set once, we're running under VM and can omit SVSes */
2889 if (irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_NECESSARY) 3229 if (irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_NECESSARY)
2890 omit_svs=1; 3230 omit_svs=1;
@@ -3015,30 +3355,40 @@ static inline void
3015qdio_do_qdio_fill_input(struct qdio_q *q, unsigned int qidx, 3355qdio_do_qdio_fill_input(struct qdio_q *q, unsigned int qidx,
3016 unsigned int count, struct qdio_buffer *buffers) 3356 unsigned int count, struct qdio_buffer *buffers)
3017{ 3357{
3358 struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr;
3359 qidx &= (QDIO_MAX_BUFFERS_PER_Q - 1);
3360 if (irq->is_qebsm) {
3361 while (count)
3362 set_slsb(q, &qidx, SLSB_CU_INPUT_EMPTY, &count);
3363 return;
3364 }
3018 for (;;) { 3365 for (;;) {
3019 set_slsb(&q->slsb.acc.val[qidx],SLSB_CU_INPUT_EMPTY); 3366 set_slsb(q, &qidx, SLSB_CU_INPUT_EMPTY, &count);
3020 count--; 3367 count--;
3021 if (!count) break; 3368 if (!count) break;
3022 qidx=(qidx+1)&(QDIO_MAX_BUFFERS_PER_Q-1); 3369 qidx = (qidx + 1) & (QDIO_MAX_BUFFERS_PER_Q - 1);
3023 } 3370 }
3024
3025 /* not necessary, as the queues are synced during the SIGA read */
3026 /*SYNC_MEMORY;*/
3027} 3371}
3028 3372
3029static inline void 3373static inline void
3030qdio_do_qdio_fill_output(struct qdio_q *q, unsigned int qidx, 3374qdio_do_qdio_fill_output(struct qdio_q *q, unsigned int qidx,
3031 unsigned int count, struct qdio_buffer *buffers) 3375 unsigned int count, struct qdio_buffer *buffers)
3032{ 3376{
3377 struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr;
3378
3379 qidx &= (QDIO_MAX_BUFFERS_PER_Q - 1);
3380 if (irq->is_qebsm) {
3381 while (count)
3382 set_slsb(q, &qidx, SLSB_CU_OUTPUT_PRIMED, &count);
3383 return;
3384 }
3385
3033 for (;;) { 3386 for (;;) {
3034 set_slsb(&q->slsb.acc.val[qidx],SLSB_CU_OUTPUT_PRIMED); 3387 set_slsb(q, &qidx, SLSB_CU_OUTPUT_PRIMED, &count);
3035 count--; 3388 count--;
3036 if (!count) break; 3389 if (!count) break;
3037 qidx=(qidx+1)&(QDIO_MAX_BUFFERS_PER_Q-1); 3390 qidx = (qidx + 1) & (QDIO_MAX_BUFFERS_PER_Q - 1);
3038 } 3391 }
3039
3040 /* SIGA write will sync the queues */
3041 /*SYNC_MEMORY;*/
3042} 3392}
3043 3393
3044static inline void 3394static inline void
@@ -3083,6 +3433,9 @@ do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags,
3083 struct qdio_buffer *buffers) 3433 struct qdio_buffer *buffers)
3084{ 3434{
3085 int used_elements; 3435 int used_elements;
3436 unsigned int cnt, start_buf;
3437 unsigned char state = 0;
3438 struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr;
3086 3439
3087 /* This is the outbound handling of queues */ 3440 /* This is the outbound handling of queues */
3088#ifdef QDIO_PERFORMANCE_STATS 3441#ifdef QDIO_PERFORMANCE_STATS
@@ -3115,9 +3468,15 @@ do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags,
3115 * SYNC_MEMORY :-/ ), we try to 3468 * SYNC_MEMORY :-/ ), we try to
3116 * fast-requeue buffers 3469 * fast-requeue buffers
3117 */ 3470 */
3118 if (q->slsb.acc.val[(qidx+QDIO_MAX_BUFFERS_PER_Q-1) 3471 if (irq->is_qebsm) {
3119 &(QDIO_MAX_BUFFERS_PER_Q-1)]!= 3472 cnt = 1;
3120 SLSB_CU_OUTPUT_PRIMED) { 3473 start_buf = ((qidx+QDIO_MAX_BUFFERS_PER_Q-1) &
3474 (QDIO_MAX_BUFFERS_PER_Q-1));
3475 qdio_do_eqbs(q, &state, &start_buf, &cnt);
3476 } else
3477 state = q->slsb.acc.val[(qidx+QDIO_MAX_BUFFERS_PER_Q-1)
3478 &(QDIO_MAX_BUFFERS_PER_Q-1) ];
3479 if (state != SLSB_CU_OUTPUT_PRIMED) {
3121 qdio_kick_outbound_q(q); 3480 qdio_kick_outbound_q(q);
3122 } else { 3481 } else {
3123 QDIO_DBF_TEXT3(0,trace, "fast-req"); 3482 QDIO_DBF_TEXT3(0,trace, "fast-req");
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;
diff --git a/include/asm-s390/qdio.h b/include/asm-s390/qdio.h
index 0ddf0a8ef8de..7bc15f0231db 100644
--- a/include/asm-s390/qdio.h
+++ b/include/asm-s390/qdio.h
@@ -195,12 +195,14 @@ struct qdr {
195/* 195/*
196 * queue information block (QIB) 196 * queue information block (QIB)
197 */ 197 */
198#define QIB_AC_INBOUND_PCI_SUPPORTED 0x80 198#define QIB_AC_INBOUND_PCI_SUPPORTED 0x80
199#define QIB_AC_OUTBOUND_PCI_SUPPORTED 0x40 199#define QIB_AC_OUTBOUND_PCI_SUPPORTED 0x40
200#define QIB_RFLAGS_ENABLE_QEBSM 0x80
201
200struct qib { 202struct qib {
201 unsigned int qfmt : 8; /* queue format */ 203 unsigned int qfmt : 8; /* queue format */
202 unsigned int pfmt : 8; /* impl. dep. parameter format */ 204 unsigned int pfmt : 8; /* impl. dep. parameter format */
203 unsigned int res1 : 8; /* reserved */ 205 unsigned int rflags : 8; /* QEBSM */
204 unsigned int ac : 8; /* adapter characteristics */ 206 unsigned int ac : 8; /* adapter characteristics */
205 unsigned int res2; /* reserved */ 207 unsigned int res2; /* reserved */
206#ifdef QDIO_32_BIT 208#ifdef QDIO_32_BIT