diff options
Diffstat (limited to 'drivers/s390/cio/qdio.c')
-rw-r--r-- | drivers/s390/cio/qdio.c | 713 |
1 files changed, 545 insertions, 168 deletions
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index eb39218b925e..30a836ffc31f 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.114 $" |
60 | 60 | ||
61 | /****************** MODULE PARAMETER VARIABLES ********************/ | 61 | /****************** MODULE PARAMETER VARIABLES ********************/ |
62 | MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>"); | 62 | MODULE_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 | ||
78 | static int hydra_thinints; | 78 | static int hydra_thinints; |
79 | static int is_passthrough = 0; | ||
79 | static int omit_svs; | 80 | static int omit_svs; |
80 | 81 | ||
81 | static int indicator_used[INDICATORS_PER_CACHELINE]; | 82 | static 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 | ||
139 | static volatile inline void | 140 | /*check ccq */ |
140 | qdio_set_slsb(volatile char *slsb, unsigned char value) | 141 | static inline int |
142 | qdio_check_ccq(struct qdio_q *q, unsigned int ccq) | ||
143 | { | ||
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; | ||
154 | } | ||
155 | /* EQBS: extract buffer states */ | ||
156 | static inline int | ||
157 | qdio_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]; | ||
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 */ | ||
186 | static inline int | ||
187 | qdio_do_sqbs(struct qdio_q *q, unsigned char state, | ||
188 | unsigned int *start, unsigned int *cnt) | ||
141 | { | 189 | { |
142 | xchg((char*)slsb,value); | 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); | ||
143 | } | 213 | } |
144 | 214 | ||
215 | static inline int | ||
216 | qdio_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 | ||
232 | static inline void | ||
233 | qdio_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 | |||
246 | static inline int | ||
247 | set_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 | } | ||
145 | static inline int | 260 | static inline int |
146 | qdio_siga_sync(struct qdio_q *q, unsigned int gpr2, | 261 | qdio_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(q->schid, 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,23 @@ 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 | ||
288 | static 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 | unsigned long schid; | ||
294 | |||
295 | irq = (struct qdio_irq *) q->irq_ptr; | ||
296 | if (!irq->is_qebsm) | ||
297 | schid = *((u32 *)&q->schid); | ||
298 | else { | ||
299 | schid = irq->sch_token; | ||
300 | fc |= 0x80; | ||
301 | } | ||
302 | return do_siga_output(schid, q->mask, busy_bit, fc); | ||
303 | } | ||
304 | |||
173 | /* | 305 | /* |
174 | * returns QDIO_SIGA_ERROR_ACCESS_EXCEPTION as cc, when SIGA returns | 306 | * returns QDIO_SIGA_ERROR_ACCESS_EXCEPTION as cc, when SIGA returns |
175 | * an access exception | 307 | * an access exception |
@@ -189,7 +321,7 @@ qdio_siga_output(struct qdio_q *q) | |||
189 | QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); | 321 | QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); |
190 | 322 | ||
191 | for (;;) { | 323 | for (;;) { |
192 | cc = do_siga_output(q->irq, q->mask, &busy_bit); | 324 | cc = __do_siga_output(q, &busy_bit); |
193 | //QDIO_PRINT_ERR("cc=%x, busy=%x\n",cc,busy_bit); | 325 | //QDIO_PRINT_ERR("cc=%x, busy=%x\n",cc,busy_bit); |
194 | if ((cc==2) && (busy_bit) && (q->is_iqdio_q)) { | 326 | if ((cc==2) && (busy_bit) && (q->is_iqdio_q)) { |
195 | if (!start_time) | 327 | if (!start_time) |
@@ -221,7 +353,7 @@ qdio_siga_input(struct qdio_q *q) | |||
221 | perf_stats.siga_ins++; | 353 | perf_stats.siga_ins++; |
222 | #endif /* QDIO_PERFORMANCE_STATS */ | 354 | #endif /* QDIO_PERFORMANCE_STATS */ |
223 | 355 | ||
224 | cc = do_siga_input(q->irq, q->mask); | 356 | cc = do_siga_input(q->schid, q->mask); |
225 | 357 | ||
226 | if (cc) | 358 | if (cc) |
227 | QDIO_DBF_HEX3(0,trace,&cc,sizeof(int*)); | 359 | QDIO_DBF_HEX3(0,trace,&cc,sizeof(int*)); |
@@ -230,7 +362,7 @@ qdio_siga_input(struct qdio_q *q) | |||
230 | } | 362 | } |
231 | 363 | ||
232 | /* locked by the locks in qdio_activate and qdio_cleanup */ | 364 | /* locked by the locks in qdio_activate and qdio_cleanup */ |
233 | static __u32 volatile * | 365 | static __u32 * |
234 | qdio_get_indicator(void) | 366 | qdio_get_indicator(void) |
235 | { | 367 | { |
236 | int i; | 368 | int i; |
@@ -258,7 +390,7 @@ qdio_put_indicator(__u32 *addr) | |||
258 | atomic_dec(&spare_indicator_usecount); | 390 | atomic_dec(&spare_indicator_usecount); |
259 | } | 391 | } |
260 | 392 | ||
261 | static inline volatile void | 393 | static inline void |
262 | tiqdio_clear_summary_bit(__u32 *location) | 394 | tiqdio_clear_summary_bit(__u32 *location) |
263 | { | 395 | { |
264 | QDIO_DBF_TEXT5(0,trace,"clrsummb"); | 396 | QDIO_DBF_TEXT5(0,trace,"clrsummb"); |
@@ -267,7 +399,7 @@ tiqdio_clear_summary_bit(__u32 *location) | |||
267 | xchg(location,0); | 399 | xchg(location,0); |
268 | } | 400 | } |
269 | 401 | ||
270 | static inline volatile void | 402 | static inline void |
271 | tiqdio_set_summary_bit(__u32 *location) | 403 | tiqdio_set_summary_bit(__u32 *location) |
272 | { | 404 | { |
273 | QDIO_DBF_TEXT5(0,trace,"setsummb"); | 405 | QDIO_DBF_TEXT5(0,trace,"setsummb"); |
@@ -336,7 +468,9 @@ static inline int | |||
336 | qdio_stop_polling(struct qdio_q *q) | 468 | qdio_stop_polling(struct qdio_q *q) |
337 | { | 469 | { |
338 | #ifdef QDIO_USE_PROCESSING_STATE | 470 | #ifdef QDIO_USE_PROCESSING_STATE |
339 | int gsf; | 471 | unsigned int tmp, gsf, count = 1; |
472 | unsigned char state = 0; | ||
473 | struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr; | ||
340 | 474 | ||
341 | if (!atomic_swap(&q->polling,0)) | 475 | if (!atomic_swap(&q->polling,0)) |
342 | return 1; | 476 | return 1; |
@@ -348,17 +482,22 @@ qdio_stop_polling(struct qdio_q *q) | |||
348 | if (!q->is_input_q) | 482 | if (!q->is_input_q) |
349 | return 1; | 483 | return 1; |
350 | 484 | ||
351 | gsf=GET_SAVED_FRONTIER(q); | 485 | tmp = gsf = GET_SAVED_FRONTIER(q); |
352 | set_slsb(&q->slsb.acc.val[(gsf+QDIO_MAX_BUFFERS_PER_Q-1)& | 486 | tmp = ((tmp + QDIO_MAX_BUFFERS_PER_Q-1) & (QDIO_MAX_BUFFERS_PER_Q-1) ); |
353 | (QDIO_MAX_BUFFERS_PER_Q-1)], | 487 | set_slsb(q, &tmp, SLSB_P_INPUT_NOT_INIT, &count); |
354 | SLSB_P_INPUT_NOT_INIT); | 488 | |
355 | /* | 489 | /* |
356 | * we don't issue this SYNC_MEMORY, as we trust Rick T and | 490 | * we don't issue this SYNC_MEMORY, as we trust Rick T and |
357 | * moreover will not use the PROCESSING state under VM, so | 491 | * moreover will not use the PROCESSING state under VM, so |
358 | * q->polling was 0 anyway | 492 | * q->polling was 0 anyway |
359 | */ | 493 | */ |
360 | /*SYNC_MEMORY;*/ | 494 | /*SYNC_MEMORY;*/ |
361 | if (q->slsb.acc.val[gsf]!=SLSB_P_INPUT_PRIMED) | 495 | if (irq->is_qebsm) { |
496 | count = 1; | ||
497 | qdio_do_eqbs(q, &state, &gsf, &count); | ||
498 | } else | ||
499 | state = q->slsb.acc.val[gsf]; | ||
500 | if (state != SLSB_P_INPUT_PRIMED) | ||
362 | return 1; | 501 | return 1; |
363 | /* | 502 | /* |
364 | * set our summary bit again, as otherwise there is a | 503 | * set our summary bit again, as otherwise there is a |
@@ -431,18 +570,136 @@ tiqdio_clear_global_summary(void) | |||
431 | 570 | ||
432 | 571 | ||
433 | /************************* OUTBOUND ROUTINES *******************************/ | 572 | /************************* OUTBOUND ROUTINES *******************************/ |
573 | static int | ||
574 | qdio_qebsm_get_outbound_buffer_frontier(struct qdio_q *q) | ||
575 | { | ||
576 | struct qdio_irq *irq; | ||
577 | unsigned char state; | ||
578 | unsigned int cnt, count, ftc; | ||
579 | |||
580 | irq = (struct qdio_irq *) q->irq_ptr; | ||
581 | if ((!q->is_iqdio_q) && (!q->hydra_gives_outbound_pcis)) | ||
582 | SYNC_MEMORY; | ||
583 | |||
584 | ftc = q->first_to_check; | ||
585 | count = qdio_min(atomic_read(&q->number_of_buffers_used), | ||
586 | (QDIO_MAX_BUFFERS_PER_Q-1)); | ||
587 | if (count == 0) | ||
588 | return q->first_to_check; | ||
589 | cnt = qdio_do_eqbs(q, &state, &ftc, &count); | ||
590 | if (cnt == 0) | ||
591 | return q->first_to_check; | ||
592 | switch (state) { | ||
593 | case SLSB_P_OUTPUT_ERROR: | ||
594 | QDIO_DBF_TEXT3(0,trace,"outperr"); | ||
595 | atomic_sub(cnt , &q->number_of_buffers_used); | ||
596 | if (q->qdio_error) | ||
597 | q->error_status_flags |= | ||
598 | QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR; | ||
599 | q->qdio_error = SLSB_P_OUTPUT_ERROR; | ||
600 | q->error_status_flags |= QDIO_STATUS_LOOK_FOR_ERROR; | ||
601 | q->first_to_check = ftc; | ||
602 | break; | ||
603 | case SLSB_P_OUTPUT_EMPTY: | ||
604 | QDIO_DBF_TEXT5(0,trace,"outpempt"); | ||
605 | atomic_sub(cnt, &q->number_of_buffers_used); | ||
606 | q->first_to_check = ftc; | ||
607 | break; | ||
608 | case SLSB_CU_OUTPUT_PRIMED: | ||
609 | /* all buffers primed */ | ||
610 | QDIO_DBF_TEXT5(0,trace,"outpprim"); | ||
611 | break; | ||
612 | default: | ||
613 | break; | ||
614 | } | ||
615 | QDIO_DBF_HEX4(0,trace,&q->first_to_check,sizeof(int)); | ||
616 | return q->first_to_check; | ||
617 | } | ||
618 | |||
619 | static int | ||
620 | qdio_qebsm_get_inbound_buffer_frontier(struct qdio_q *q) | ||
621 | { | ||
622 | struct qdio_irq *irq; | ||
623 | unsigned char state; | ||
624 | int tmp, ftc, count, cnt; | ||
625 | char dbf_text[15]; | ||
626 | |||
627 | |||
628 | irq = (struct qdio_irq *) q->irq_ptr; | ||
629 | ftc = q->first_to_check; | ||
630 | count = qdio_min(atomic_read(&q->number_of_buffers_used), | ||
631 | (QDIO_MAX_BUFFERS_PER_Q-1)); | ||
632 | if (count == 0) | ||
633 | return q->first_to_check; | ||
634 | cnt = qdio_do_eqbs(q, &state, &ftc, &count); | ||
635 | if (cnt == 0) | ||
636 | return q->first_to_check; | ||
637 | switch (state) { | ||
638 | case SLSB_P_INPUT_ERROR : | ||
639 | #ifdef CONFIG_QDIO_DEBUG | ||
640 | QDIO_DBF_TEXT3(1,trace,"inperr"); | ||
641 | sprintf(dbf_text,"%2x,%2x",ftc,count); | ||
642 | QDIO_DBF_TEXT3(1,trace,dbf_text); | ||
643 | #endif /* CONFIG_QDIO_DEBUG */ | ||
644 | if (q->qdio_error) | ||
645 | q->error_status_flags |= | ||
646 | QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR; | ||
647 | q->qdio_error = SLSB_P_INPUT_ERROR; | ||
648 | q->error_status_flags |= QDIO_STATUS_LOOK_FOR_ERROR; | ||
649 | atomic_sub(cnt, &q->number_of_buffers_used); | ||
650 | q->first_to_check = ftc; | ||
651 | break; | ||
652 | case SLSB_P_INPUT_PRIMED : | ||
653 | QDIO_DBF_TEXT3(0,trace,"inptprim"); | ||
654 | sprintf(dbf_text,"%2x,%2x",ftc,count); | ||
655 | QDIO_DBF_TEXT3(1,trace,dbf_text); | ||
656 | tmp = 0; | ||
657 | ftc = q->first_to_check; | ||
658 | #ifdef QDIO_USE_PROCESSING_STATE | ||
659 | if (cnt > 1) { | ||
660 | cnt -= 1; | ||
661 | tmp = set_slsb(q, &ftc, SLSB_P_INPUT_NOT_INIT, &cnt); | ||
662 | if (!tmp) | ||
663 | break; | ||
664 | } | ||
665 | cnt = 1; | ||
666 | tmp += set_slsb(q, &ftc, | ||
667 | SLSB_P_INPUT_PROCESSING, &cnt); | ||
668 | atomic_set(&q->polling, 1); | ||
669 | #else | ||
670 | tmp = set_slsb(q, &ftc, SLSB_P_INPUT_NOT_INIT, &cnt); | ||
671 | #endif | ||
672 | atomic_sub(tmp, &q->number_of_buffers_used); | ||
673 | q->first_to_check = ftc; | ||
674 | break; | ||
675 | case SLSB_CU_INPUT_EMPTY: | ||
676 | case SLSB_P_INPUT_NOT_INIT: | ||
677 | case SLSB_P_INPUT_PROCESSING: | ||
678 | QDIO_DBF_TEXT5(0,trace,"inpnipro"); | ||
679 | break; | ||
680 | default: | ||
681 | break; | ||
682 | } | ||
683 | QDIO_DBF_HEX4(0,trace,&q->first_to_check,sizeof(int)); | ||
684 | return q->first_to_check; | ||
685 | } | ||
434 | 686 | ||
435 | static inline int | 687 | static inline int |
436 | qdio_get_outbound_buffer_frontier(struct qdio_q *q) | 688 | qdio_get_outbound_buffer_frontier(struct qdio_q *q) |
437 | { | 689 | { |
438 | int f,f_mod_no; | 690 | struct qdio_irq *irq; |
439 | volatile char *slsb; | 691 | volatile char *slsb; |
440 | int first_not_to_check; | 692 | unsigned int count = 1; |
693 | int first_not_to_check, f, f_mod_no; | ||
441 | char dbf_text[15]; | 694 | char dbf_text[15]; |
442 | 695 | ||
443 | QDIO_DBF_TEXT4(0,trace,"getobfro"); | 696 | QDIO_DBF_TEXT4(0,trace,"getobfro"); |
444 | QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); | 697 | QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); |
445 | 698 | ||
699 | irq = (struct qdio_irq *) q->irq_ptr; | ||
700 | if (irq->is_qebsm) | ||
701 | return qdio_qebsm_get_outbound_buffer_frontier(q); | ||
702 | |||
446 | slsb=&q->slsb.acc.val[0]; | 703 | slsb=&q->slsb.acc.val[0]; |
447 | f_mod_no=f=q->first_to_check; | 704 | f_mod_no=f=q->first_to_check; |
448 | /* | 705 | /* |
@@ -484,7 +741,7 @@ check_next: | |||
484 | QDIO_DBF_HEX2(1,sbal,q->sbal[f_mod_no],256); | 741 | QDIO_DBF_HEX2(1,sbal,q->sbal[f_mod_no],256); |
485 | 742 | ||
486 | /* kind of process the buffer */ | 743 | /* kind of process the buffer */ |
487 | set_slsb(&q->slsb.acc.val[f_mod_no], SLSB_P_OUTPUT_NOT_INIT); | 744 | set_slsb(q, &f_mod_no, SLSB_P_OUTPUT_NOT_INIT, &count); |
488 | 745 | ||
489 | /* | 746 | /* |
490 | * we increment the frontier, as this buffer | 747 | * we increment the frontier, as this buffer |
@@ -597,48 +854,48 @@ qdio_kick_outbound_q(struct qdio_q *q) | |||
597 | 854 | ||
598 | result=qdio_siga_output(q); | 855 | result=qdio_siga_output(q); |
599 | 856 | ||
600 | switch (result) { | 857 | switch (result) { |
601 | case 0: | 858 | case 0: |
602 | /* went smooth this time, reset timestamp */ | 859 | /* went smooth this time, reset timestamp */ |
603 | #ifdef CONFIG_QDIO_DEBUG | 860 | #ifdef CONFIG_QDIO_DEBUG |
604 | QDIO_DBF_TEXT3(0,trace,"cc2reslv"); | 861 | QDIO_DBF_TEXT3(0,trace,"cc2reslv"); |
605 | sprintf(dbf_text,"%4x%2x%2x",q->irq,q->q_no, | 862 | sprintf(dbf_text,"%4x%2x%2x",q->schid.sch_no,q->q_no, |
606 | atomic_read(&q->busy_siga_counter)); | 863 | atomic_read(&q->busy_siga_counter)); |
607 | QDIO_DBF_TEXT3(0,trace,dbf_text); | 864 | QDIO_DBF_TEXT3(0,trace,dbf_text); |
608 | #endif /* CONFIG_QDIO_DEBUG */ | 865 | #endif /* CONFIG_QDIO_DEBUG */ |
609 | q->timing.busy_start=0; | 866 | q->timing.busy_start=0; |
867 | break; | ||
868 | case (2|QDIO_SIGA_ERROR_B_BIT_SET): | ||
869 | /* cc=2 and busy bit: */ | ||
870 | atomic_inc(&q->busy_siga_counter); | ||
871 | |||
872 | /* if the last siga was successful, save | ||
873 | * timestamp here */ | ||
874 | if (!q->timing.busy_start) | ||
875 | q->timing.busy_start=NOW; | ||
876 | |||
877 | /* if we're in time, don't touch error_status_flags | ||
878 | * and siga_error */ | ||
879 | if (NOW-q->timing.busy_start<QDIO_BUSY_BIT_GIVE_UP) { | ||
880 | qdio_mark_q(q); | ||
610 | break; | 881 | break; |
611 | case (2|QDIO_SIGA_ERROR_B_BIT_SET): | 882 | } |
612 | /* cc=2 and busy bit: */ | 883 | 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 | 884 | #ifdef CONFIG_QDIO_DEBUG |
628 | sprintf(dbf_text,"%4x%2x%2x",q->irq,q->q_no, | 885 | sprintf(dbf_text,"%4x%2x%2x",q->schid.sch_no,q->q_no, |
629 | atomic_read(&q->busy_siga_counter)); | 886 | atomic_read(&q->busy_siga_counter)); |
630 | QDIO_DBF_TEXT3(0,trace,dbf_text); | 887 | QDIO_DBF_TEXT3(0,trace,dbf_text); |
631 | #endif /* CONFIG_QDIO_DEBUG */ | 888 | #endif /* CONFIG_QDIO_DEBUG */ |
632 | /* else fallthrough and report error */ | 889 | /* else fallthrough and report error */ |
633 | default: | 890 | default: |
634 | /* for plain cc=1, 2 or 3: */ | 891 | /* for plain cc=1, 2 or 3: */ |
635 | if (q->siga_error) | 892 | if (q->siga_error) |
636 | q->error_status_flags|= | ||
637 | QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR; | ||
638 | q->error_status_flags|= | 893 | q->error_status_flags|= |
639 | QDIO_STATUS_LOOK_FOR_ERROR; | 894 | QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR; |
640 | q->siga_error=result; | 895 | q->error_status_flags|= |
641 | } | 896 | QDIO_STATUS_LOOK_FOR_ERROR; |
897 | q->siga_error=result; | ||
898 | } | ||
642 | } | 899 | } |
643 | 900 | ||
644 | static inline void | 901 | static inline void |
@@ -743,8 +1000,10 @@ qdio_outbound_processing(struct qdio_q *q) | |||
743 | static inline int | 1000 | static inline int |
744 | qdio_get_inbound_buffer_frontier(struct qdio_q *q) | 1001 | qdio_get_inbound_buffer_frontier(struct qdio_q *q) |
745 | { | 1002 | { |
1003 | struct qdio_irq *irq; | ||
746 | int f,f_mod_no; | 1004 | int f,f_mod_no; |
747 | volatile char *slsb; | 1005 | volatile char *slsb; |
1006 | unsigned int count = 1; | ||
748 | int first_not_to_check; | 1007 | int first_not_to_check; |
749 | #ifdef CONFIG_QDIO_DEBUG | 1008 | #ifdef CONFIG_QDIO_DEBUG |
750 | char dbf_text[15]; | 1009 | char dbf_text[15]; |
@@ -756,6 +1015,10 @@ qdio_get_inbound_buffer_frontier(struct qdio_q *q) | |||
756 | QDIO_DBF_TEXT4(0,trace,"getibfro"); | 1015 | QDIO_DBF_TEXT4(0,trace,"getibfro"); |
757 | QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); | 1016 | QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); |
758 | 1017 | ||
1018 | irq = (struct qdio_irq *) q->irq_ptr; | ||
1019 | if (irq->is_qebsm) | ||
1020 | return qdio_qebsm_get_inbound_buffer_frontier(q); | ||
1021 | |||
759 | slsb=&q->slsb.acc.val[0]; | 1022 | slsb=&q->slsb.acc.val[0]; |
760 | f_mod_no=f=q->first_to_check; | 1023 | f_mod_no=f=q->first_to_check; |
761 | /* | 1024 | /* |
@@ -792,19 +1055,19 @@ check_next: | |||
792 | * kill VM in terms of CP overhead | 1055 | * kill VM in terms of CP overhead |
793 | */ | 1056 | */ |
794 | if (q->siga_sync) { | 1057 | if (q->siga_sync) { |
795 | set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_NOT_INIT); | 1058 | set_slsb(q, &f_mod_no, SLSB_P_INPUT_NOT_INIT, &count); |
796 | } else { | 1059 | } else { |
797 | /* set the previous buffer to NOT_INIT. The current | 1060 | /* set the previous buffer to NOT_INIT. The current |
798 | * buffer will be set to PROCESSING at the end of | 1061 | * buffer will be set to PROCESSING at the end of |
799 | * this function to avoid further interrupts. */ | 1062 | * this function to avoid further interrupts. */ |
800 | if (last_position>=0) | 1063 | if (last_position>=0) |
801 | set_slsb(&slsb[last_position], | 1064 | set_slsb(q, &last_position, |
802 | SLSB_P_INPUT_NOT_INIT); | 1065 | SLSB_P_INPUT_NOT_INIT, &count); |
803 | atomic_set(&q->polling,1); | 1066 | atomic_set(&q->polling,1); |
804 | last_position=f_mod_no; | 1067 | last_position=f_mod_no; |
805 | } | 1068 | } |
806 | #else /* QDIO_USE_PROCESSING_STATE */ | 1069 | #else /* QDIO_USE_PROCESSING_STATE */ |
807 | set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_NOT_INIT); | 1070 | set_slsb(q, &f_mod_no, SLSB_P_INPUT_NOT_INIT, &count); |
808 | #endif /* QDIO_USE_PROCESSING_STATE */ | 1071 | #endif /* QDIO_USE_PROCESSING_STATE */ |
809 | /* | 1072 | /* |
810 | * not needed, as the inbound queue will be synced on the next | 1073 | * not needed, as the inbound queue will be synced on the next |
@@ -829,7 +1092,7 @@ check_next: | |||
829 | QDIO_DBF_HEX2(1,sbal,q->sbal[f_mod_no],256); | 1092 | QDIO_DBF_HEX2(1,sbal,q->sbal[f_mod_no],256); |
830 | 1093 | ||
831 | /* kind of process the buffer */ | 1094 | /* kind of process the buffer */ |
832 | set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_NOT_INIT); | 1095 | set_slsb(q, &f_mod_no, SLSB_P_INPUT_NOT_INIT, &count); |
833 | 1096 | ||
834 | if (q->qdio_error) | 1097 | if (q->qdio_error) |
835 | q->error_status_flags|= | 1098 | q->error_status_flags|= |
@@ -857,7 +1120,7 @@ out: | |||
857 | 1120 | ||
858 | #ifdef QDIO_USE_PROCESSING_STATE | 1121 | #ifdef QDIO_USE_PROCESSING_STATE |
859 | if (last_position>=0) | 1122 | if (last_position>=0) |
860 | set_slsb(&slsb[last_position],SLSB_P_INPUT_PROCESSING); | 1123 | set_slsb(q, &last_position, SLSB_P_INPUT_NOT_INIT, &count); |
861 | #endif /* QDIO_USE_PROCESSING_STATE */ | 1124 | #endif /* QDIO_USE_PROCESSING_STATE */ |
862 | 1125 | ||
863 | QDIO_DBF_HEX4(0,trace,&q->first_to_check,sizeof(int)); | 1126 | QDIO_DBF_HEX4(0,trace,&q->first_to_check,sizeof(int)); |
@@ -902,6 +1165,10 @@ static inline int | |||
902 | tiqdio_is_inbound_q_done(struct qdio_q *q) | 1165 | tiqdio_is_inbound_q_done(struct qdio_q *q) |
903 | { | 1166 | { |
904 | int no_used; | 1167 | int no_used; |
1168 | unsigned int start_buf, count; | ||
1169 | unsigned char state = 0; | ||
1170 | struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr; | ||
1171 | |||
905 | #ifdef CONFIG_QDIO_DEBUG | 1172 | #ifdef CONFIG_QDIO_DEBUG |
906 | char dbf_text[15]; | 1173 | char dbf_text[15]; |
907 | #endif | 1174 | #endif |
@@ -927,8 +1194,13 @@ tiqdio_is_inbound_q_done(struct qdio_q *q) | |||
927 | if (!q->siga_sync) | 1194 | if (!q->siga_sync) |
928 | /* we'll check for more primed buffers in qeth_stop_polling */ | 1195 | /* we'll check for more primed buffers in qeth_stop_polling */ |
929 | return 0; | 1196 | return 0; |
930 | 1197 | if (irq->is_qebsm) { | |
931 | if (q->slsb.acc.val[q->first_to_check]!=SLSB_P_INPUT_PRIMED) | 1198 | count = 1; |
1199 | start_buf = q->first_to_check; | ||
1200 | qdio_do_eqbs(q, &state, &start_buf, &count); | ||
1201 | } else | ||
1202 | state = q->slsb.acc.val[q->first_to_check]; | ||
1203 | if (state != SLSB_P_INPUT_PRIMED) | ||
932 | /* | 1204 | /* |
933 | * nothing more to do, if next buffer is not PRIMED. | 1205 | * nothing more to do, if next buffer is not PRIMED. |
934 | * note that we did a SYNC_MEMORY before, that there | 1206 | * note that we did a SYNC_MEMORY before, that there |
@@ -955,6 +1227,10 @@ static inline int | |||
955 | qdio_is_inbound_q_done(struct qdio_q *q) | 1227 | qdio_is_inbound_q_done(struct qdio_q *q) |
956 | { | 1228 | { |
957 | int no_used; | 1229 | int no_used; |
1230 | unsigned int start_buf, count; | ||
1231 | unsigned char state = 0; | ||
1232 | struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr; | ||
1233 | |||
958 | #ifdef CONFIG_QDIO_DEBUG | 1234 | #ifdef CONFIG_QDIO_DEBUG |
959 | char dbf_text[15]; | 1235 | char dbf_text[15]; |
960 | #endif | 1236 | #endif |
@@ -973,8 +1249,13 @@ qdio_is_inbound_q_done(struct qdio_q *q) | |||
973 | QDIO_DBF_TEXT4(0,trace,dbf_text); | 1249 | QDIO_DBF_TEXT4(0,trace,dbf_text); |
974 | return 1; | 1250 | return 1; |
975 | } | 1251 | } |
976 | 1252 | if (irq->is_qebsm) { | |
977 | if (q->slsb.acc.val[q->first_to_check]==SLSB_P_INPUT_PRIMED) { | 1253 | count = 1; |
1254 | start_buf = q->first_to_check; | ||
1255 | qdio_do_eqbs(q, &state, &start_buf, &count); | ||
1256 | } else | ||
1257 | state = q->slsb.acc.val[q->first_to_check]; | ||
1258 | if (state == SLSB_P_INPUT_PRIMED) { | ||
978 | /* we got something to do */ | 1259 | /* we got something to do */ |
979 | QDIO_DBF_TEXT4(0,trace,"inqisntA"); | 1260 | QDIO_DBF_TEXT4(0,trace,"inqisntA"); |
980 | QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); | 1261 | QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); |
@@ -1456,7 +1737,7 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev, | |||
1456 | void *ptr; | 1737 | void *ptr; |
1457 | int available; | 1738 | int available; |
1458 | 1739 | ||
1459 | sprintf(dbf_text,"qfqs%4x",cdev->private->irq); | 1740 | sprintf(dbf_text,"qfqs%4x",cdev->private->sch_no); |
1460 | QDIO_DBF_TEXT0(0,setup,dbf_text); | 1741 | QDIO_DBF_TEXT0(0,setup,dbf_text); |
1461 | for (i=0;i<no_input_qs;i++) { | 1742 | for (i=0;i<no_input_qs;i++) { |
1462 | q=irq_ptr->input_qs[i]; | 1743 | q=irq_ptr->input_qs[i]; |
@@ -1476,7 +1757,7 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev, | |||
1476 | 1757 | ||
1477 | q->queue_type=q_format; | 1758 | q->queue_type=q_format; |
1478 | q->int_parm=int_parm; | 1759 | q->int_parm=int_parm; |
1479 | q->irq=irq_ptr->irq; | 1760 | q->schid = irq_ptr->schid; |
1480 | q->irq_ptr = irq_ptr; | 1761 | q->irq_ptr = irq_ptr; |
1481 | q->cdev = cdev; | 1762 | q->cdev = cdev; |
1482 | q->mask=1<<(31-i); | 1763 | q->mask=1<<(31-i); |
@@ -1523,11 +1804,11 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev, | |||
1523 | QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*)); | 1804 | QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*)); |
1524 | 1805 | ||
1525 | /* fill in slsb */ | 1806 | /* fill in slsb */ |
1526 | for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) { | 1807 | if (!irq_ptr->is_qebsm) { |
1527 | set_slsb(&q->slsb.acc.val[j], | 1808 | unsigned int count = 1; |
1528 | SLSB_P_INPUT_NOT_INIT); | 1809 | for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) |
1529 | /* q->sbal[j]->element[1].sbalf.i1.key=QDIO_STORAGE_KEY;*/ | 1810 | set_slsb(q, &j, SLSB_P_INPUT_NOT_INIT, &count); |
1530 | } | 1811 | } |
1531 | } | 1812 | } |
1532 | 1813 | ||
1533 | for (i=0;i<no_output_qs;i++) { | 1814 | for (i=0;i<no_output_qs;i++) { |
@@ -1549,7 +1830,7 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev, | |||
1549 | q->queue_type=q_format; | 1830 | q->queue_type=q_format; |
1550 | q->int_parm=int_parm; | 1831 | q->int_parm=int_parm; |
1551 | q->is_input_q=0; | 1832 | q->is_input_q=0; |
1552 | q->irq=irq_ptr->irq; | 1833 | q->schid = irq_ptr->schid; |
1553 | q->cdev = cdev; | 1834 | q->cdev = cdev; |
1554 | q->irq_ptr = irq_ptr; | 1835 | q->irq_ptr = irq_ptr; |
1555 | q->mask=1<<(31-i); | 1836 | q->mask=1<<(31-i); |
@@ -1584,11 +1865,11 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev, | |||
1584 | QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*)); | 1865 | QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*)); |
1585 | 1866 | ||
1586 | /* fill in slsb */ | 1867 | /* fill in slsb */ |
1587 | for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) { | 1868 | if (!irq_ptr->is_qebsm) { |
1588 | set_slsb(&q->slsb.acc.val[j], | 1869 | unsigned int count = 1; |
1589 | SLSB_P_OUTPUT_NOT_INIT); | 1870 | for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) |
1590 | /* q->sbal[j]->element[1].sbalf.i1.key=QDIO_STORAGE_KEY;*/ | 1871 | set_slsb(q, &j, SLSB_P_OUTPUT_NOT_INIT, &count); |
1591 | } | 1872 | } |
1592 | } | 1873 | } |
1593 | } | 1874 | } |
1594 | 1875 | ||
@@ -1656,7 +1937,7 @@ qdio_set_state(struct qdio_irq *irq_ptr, enum qdio_irq_states state) | |||
1656 | char dbf_text[15]; | 1937 | char dbf_text[15]; |
1657 | 1938 | ||
1658 | QDIO_DBF_TEXT5(0,trace,"newstate"); | 1939 | QDIO_DBF_TEXT5(0,trace,"newstate"); |
1659 | sprintf(dbf_text,"%4x%4x",irq_ptr->irq,state); | 1940 | sprintf(dbf_text,"%4x%4x",irq_ptr->schid.sch_no,state); |
1660 | QDIO_DBF_TEXT5(0,trace,dbf_text); | 1941 | QDIO_DBF_TEXT5(0,trace,dbf_text); |
1661 | #endif /* CONFIG_QDIO_DEBUG */ | 1942 | #endif /* CONFIG_QDIO_DEBUG */ |
1662 | 1943 | ||
@@ -1669,12 +1950,12 @@ qdio_set_state(struct qdio_irq *irq_ptr, enum qdio_irq_states state) | |||
1669 | } | 1950 | } |
1670 | 1951 | ||
1671 | static inline void | 1952 | static inline void |
1672 | qdio_irq_check_sense(int irq, struct irb *irb) | 1953 | qdio_irq_check_sense(struct subchannel_id schid, struct irb *irb) |
1673 | { | 1954 | { |
1674 | char dbf_text[15]; | 1955 | char dbf_text[15]; |
1675 | 1956 | ||
1676 | if (irb->esw.esw0.erw.cons) { | 1957 | if (irb->esw.esw0.erw.cons) { |
1677 | sprintf(dbf_text,"sens%4x",irq); | 1958 | sprintf(dbf_text,"sens%4x",schid.sch_no); |
1678 | QDIO_DBF_TEXT2(1,trace,dbf_text); | 1959 | QDIO_DBF_TEXT2(1,trace,dbf_text); |
1679 | QDIO_DBF_HEX0(0,sense,irb,QDIO_DBF_SENSE_LEN); | 1960 | QDIO_DBF_HEX0(0,sense,irb,QDIO_DBF_SENSE_LEN); |
1680 | 1961 | ||
@@ -1785,21 +2066,22 @@ qdio_timeout_handler(struct ccw_device *cdev) | |||
1785 | 2066 | ||
1786 | switch (irq_ptr->state) { | 2067 | switch (irq_ptr->state) { |
1787 | case QDIO_IRQ_STATE_INACTIVE: | 2068 | case QDIO_IRQ_STATE_INACTIVE: |
1788 | QDIO_PRINT_ERR("establish queues on irq %04x: timed out\n", | 2069 | QDIO_PRINT_ERR("establish queues on irq 0.%x.%04x: timed out\n", |
1789 | irq_ptr->irq); | 2070 | irq_ptr->schid.ssid, irq_ptr->schid.sch_no); |
1790 | QDIO_DBF_TEXT2(1,setup,"eq:timeo"); | 2071 | QDIO_DBF_TEXT2(1,setup,"eq:timeo"); |
1791 | qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR); | 2072 | qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR); |
1792 | break; | 2073 | break; |
1793 | case QDIO_IRQ_STATE_CLEANUP: | 2074 | case QDIO_IRQ_STATE_CLEANUP: |
1794 | QDIO_PRINT_INFO("Did not get interrupt on cleanup, irq=0x%x.\n", | 2075 | QDIO_PRINT_INFO("Did not get interrupt on cleanup, " |
1795 | irq_ptr->irq); | 2076 | "irq=0.%x.%x.\n", |
2077 | irq_ptr->schid.ssid, irq_ptr->schid.sch_no); | ||
1796 | qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR); | 2078 | qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR); |
1797 | break; | 2079 | break; |
1798 | case QDIO_IRQ_STATE_ESTABLISHED: | 2080 | case QDIO_IRQ_STATE_ESTABLISHED: |
1799 | case QDIO_IRQ_STATE_ACTIVE: | 2081 | case QDIO_IRQ_STATE_ACTIVE: |
1800 | /* I/O has been terminated by common I/O layer. */ | 2082 | /* I/O has been terminated by common I/O layer. */ |
1801 | QDIO_PRINT_INFO("Queues on irq %04x killed by cio.\n", | 2083 | QDIO_PRINT_INFO("Queues on irq 0.%x.%04x killed by cio.\n", |
1802 | irq_ptr->irq); | 2084 | irq_ptr->schid.ssid, irq_ptr->schid.sch_no); |
1803 | QDIO_DBF_TEXT2(1, trace, "cio:term"); | 2085 | QDIO_DBF_TEXT2(1, trace, "cio:term"); |
1804 | qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED); | 2086 | qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED); |
1805 | if (get_device(&cdev->dev)) { | 2087 | if (get_device(&cdev->dev)) { |
@@ -1862,7 +2144,7 @@ qdio_handler(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) | |||
1862 | } | 2144 | } |
1863 | } | 2145 | } |
1864 | 2146 | ||
1865 | qdio_irq_check_sense(irq_ptr->irq, irb); | 2147 | qdio_irq_check_sense(irq_ptr->schid, irb); |
1866 | 2148 | ||
1867 | #ifdef CONFIG_QDIO_DEBUG | 2149 | #ifdef CONFIG_QDIO_DEBUG |
1868 | sprintf(dbf_text, "state:%d", irq_ptr->state); | 2150 | sprintf(dbf_text, "state:%d", irq_ptr->state); |
@@ -1905,7 +2187,7 @@ int | |||
1905 | qdio_synchronize(struct ccw_device *cdev, unsigned int flags, | 2187 | qdio_synchronize(struct ccw_device *cdev, unsigned int flags, |
1906 | unsigned int queue_number) | 2188 | unsigned int queue_number) |
1907 | { | 2189 | { |
1908 | int cc; | 2190 | int cc = 0; |
1909 | struct qdio_q *q; | 2191 | struct qdio_q *q; |
1910 | struct qdio_irq *irq_ptr; | 2192 | struct qdio_irq *irq_ptr; |
1911 | void *ptr; | 2193 | void *ptr; |
@@ -1918,7 +2200,7 @@ qdio_synchronize(struct ccw_device *cdev, unsigned int flags, | |||
1918 | return -ENODEV; | 2200 | return -ENODEV; |
1919 | 2201 | ||
1920 | #ifdef CONFIG_QDIO_DEBUG | 2202 | #ifdef CONFIG_QDIO_DEBUG |
1921 | *((int*)(&dbf_text[4])) = irq_ptr->irq; | 2203 | *((int*)(&dbf_text[4])) = irq_ptr->schid.sch_no; |
1922 | QDIO_DBF_HEX4(0,trace,dbf_text,QDIO_DBF_TRACE_LEN); | 2204 | QDIO_DBF_HEX4(0,trace,dbf_text,QDIO_DBF_TRACE_LEN); |
1923 | *((int*)(&dbf_text[0]))=flags; | 2205 | *((int*)(&dbf_text[0]))=flags; |
1924 | *((int*)(&dbf_text[4]))=queue_number; | 2206 | *((int*)(&dbf_text[4]))=queue_number; |
@@ -1929,12 +2211,14 @@ qdio_synchronize(struct ccw_device *cdev, unsigned int flags, | |||
1929 | q=irq_ptr->input_qs[queue_number]; | 2211 | q=irq_ptr->input_qs[queue_number]; |
1930 | if (!q) | 2212 | if (!q) |
1931 | return -EINVAL; | 2213 | return -EINVAL; |
1932 | cc = do_siga_sync(q->irq, 0, q->mask); | 2214 | if (!(irq_ptr->is_qebsm)) |
2215 | cc = do_siga_sync(q->schid, 0, q->mask); | ||
1933 | } else if (flags&QDIO_FLAG_SYNC_OUTPUT) { | 2216 | } else if (flags&QDIO_FLAG_SYNC_OUTPUT) { |
1934 | q=irq_ptr->output_qs[queue_number]; | 2217 | q=irq_ptr->output_qs[queue_number]; |
1935 | if (!q) | 2218 | if (!q) |
1936 | return -EINVAL; | 2219 | return -EINVAL; |
1937 | cc = do_siga_sync(q->irq, q->mask, 0); | 2220 | if (!(irq_ptr->is_qebsm)) |
2221 | cc = do_siga_sync(q->schid, q->mask, 0); | ||
1938 | } else | 2222 | } else |
1939 | return -EINVAL; | 2223 | return -EINVAL; |
1940 | 2224 | ||
@@ -1945,15 +2229,54 @@ qdio_synchronize(struct ccw_device *cdev, unsigned int flags, | |||
1945 | return cc; | 2229 | return cc; |
1946 | } | 2230 | } |
1947 | 2231 | ||
1948 | static unsigned char | 2232 | static inline void |
1949 | qdio_check_siga_needs(int sch) | 2233 | qdio_check_subchannel_qebsm(struct qdio_irq *irq_ptr, unsigned char qdioac, |
2234 | unsigned long token) | ||
2235 | { | ||
2236 | struct qdio_q *q; | ||
2237 | int i; | ||
2238 | unsigned int count, start_buf; | ||
2239 | char dbf_text[15]; | ||
2240 | |||
2241 | /*check if QEBSM is disabled */ | ||
2242 | if (!(irq_ptr->is_qebsm) || !(qdioac & 0x01)) { | ||
2243 | irq_ptr->is_qebsm = 0; | ||
2244 | irq_ptr->sch_token = 0; | ||
2245 | irq_ptr->qib.rflags &= ~QIB_RFLAGS_ENABLE_QEBSM; | ||
2246 | QDIO_DBF_TEXT0(0,setup,"noV=V"); | ||
2247 | return; | ||
2248 | } | ||
2249 | irq_ptr->sch_token = token; | ||
2250 | /*input queue*/ | ||
2251 | for (i = 0; i < irq_ptr->no_input_qs;i++) { | ||
2252 | q = irq_ptr->input_qs[i]; | ||
2253 | count = QDIO_MAX_BUFFERS_PER_Q; | ||
2254 | start_buf = 0; | ||
2255 | set_slsb(q, &start_buf, SLSB_P_INPUT_NOT_INIT, &count); | ||
2256 | } | ||
2257 | sprintf(dbf_text,"V=V:%2x",irq_ptr->is_qebsm); | ||
2258 | QDIO_DBF_TEXT0(0,setup,dbf_text); | ||
2259 | sprintf(dbf_text,"%8lx",irq_ptr->sch_token); | ||
2260 | QDIO_DBF_TEXT0(0,setup,dbf_text); | ||
2261 | /*output queue*/ | ||
2262 | for (i = 0; i < irq_ptr->no_output_qs; i++) { | ||
2263 | q = irq_ptr->output_qs[i]; | ||
2264 | count = QDIO_MAX_BUFFERS_PER_Q; | ||
2265 | start_buf = 0; | ||
2266 | set_slsb(q, &start_buf, SLSB_P_OUTPUT_NOT_INIT, &count); | ||
2267 | } | ||
2268 | } | ||
2269 | |||
2270 | static void | ||
2271 | qdio_get_ssqd_information(struct qdio_irq *irq_ptr) | ||
1950 | { | 2272 | { |
1951 | int result; | 2273 | int result; |
1952 | unsigned char qdioac; | 2274 | unsigned char qdioac; |
1953 | |||
1954 | struct { | 2275 | struct { |
1955 | struct chsc_header request; | 2276 | struct chsc_header request; |
1956 | u16 reserved1; | 2277 | u16 reserved1:10; |
2278 | u16 ssid:2; | ||
2279 | u16 fmt:4; | ||
1957 | u16 first_sch; | 2280 | u16 first_sch; |
1958 | u16 reserved2; | 2281 | u16 reserved2; |
1959 | u16 last_sch; | 2282 | u16 last_sch; |
@@ -1964,67 +2287,83 @@ qdio_check_siga_needs(int sch) | |||
1964 | u8 reserved5; | 2287 | u8 reserved5; |
1965 | u16 sch; | 2288 | u16 sch; |
1966 | u8 qfmt; | 2289 | u8 qfmt; |
1967 | u8 reserved6; | 2290 | u8 parm; |
1968 | u8 qdioac; | 2291 | u8 qdioac1; |
1969 | u8 sch_class; | 2292 | u8 sch_class; |
1970 | u8 reserved7; | 2293 | u8 reserved7; |
1971 | u8 icnt; | 2294 | u8 icnt; |
1972 | u8 reserved8; | 2295 | u8 reserved8; |
1973 | u8 ocnt; | 2296 | u8 ocnt; |
2297 | u8 reserved9; | ||
2298 | u8 mbccnt; | ||
2299 | u16 qdioac2; | ||
2300 | u64 sch_token; | ||
1974 | } *ssqd_area; | 2301 | } *ssqd_area; |
1975 | 2302 | ||
2303 | QDIO_DBF_TEXT0(0,setup,"getssqd"); | ||
2304 | qdioac = 0; | ||
1976 | ssqd_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); | 2305 | ssqd_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); |
1977 | if (!ssqd_area) { | 2306 | if (!ssqd_area) { |
1978 | QDIO_PRINT_WARN("Could not get memory for chsc. Using all " \ | 2307 | QDIO_PRINT_WARN("Could not get memory for chsc. Using all " \ |
1979 | "SIGAs for sch x%x.\n", sch); | 2308 | "SIGAs for sch x%x.\n", irq_ptr->schid.sch_no); |
1980 | return CHSC_FLAG_SIGA_INPUT_NECESSARY || | 2309 | irq_ptr->qdioac = CHSC_FLAG_SIGA_INPUT_NECESSARY || |
1981 | CHSC_FLAG_SIGA_OUTPUT_NECESSARY || | 2310 | CHSC_FLAG_SIGA_OUTPUT_NECESSARY || |
1982 | CHSC_FLAG_SIGA_SYNC_NECESSARY; /* all flags set */ | 2311 | CHSC_FLAG_SIGA_SYNC_NECESSARY; /* all flags set */ |
2312 | irq_ptr->is_qebsm = 0; | ||
2313 | irq_ptr->sch_token = 0; | ||
2314 | irq_ptr->qib.rflags &= ~QIB_RFLAGS_ENABLE_QEBSM; | ||
2315 | return; | ||
1983 | } | 2316 | } |
2317 | |||
1984 | ssqd_area->request = (struct chsc_header) { | 2318 | ssqd_area->request = (struct chsc_header) { |
1985 | .length = 0x0010, | 2319 | .length = 0x0010, |
1986 | .code = 0x0024, | 2320 | .code = 0x0024, |
1987 | }; | 2321 | }; |
1988 | 2322 | ssqd_area->first_sch = irq_ptr->schid.sch_no; | |
1989 | ssqd_area->first_sch = sch; | 2323 | ssqd_area->last_sch = irq_ptr->schid.sch_no; |
1990 | ssqd_area->last_sch = sch; | 2324 | ssqd_area->ssid = irq_ptr->schid.ssid; |
1991 | 2325 | result = chsc(ssqd_area); | |
1992 | result=chsc(ssqd_area); | ||
1993 | 2326 | ||
1994 | if (result) { | 2327 | if (result) { |
1995 | QDIO_PRINT_WARN("CHSC returned cc %i. Using all " \ | 2328 | QDIO_PRINT_WARN("CHSC returned cc %i. Using all " \ |
1996 | "SIGAs for sch x%x.\n", | 2329 | "SIGAs for sch 0.%x.%x.\n", result, |
1997 | result,sch); | 2330 | irq_ptr->schid.ssid, irq_ptr->schid.sch_no); |
1998 | qdioac = CHSC_FLAG_SIGA_INPUT_NECESSARY || | 2331 | qdioac = CHSC_FLAG_SIGA_INPUT_NECESSARY || |
1999 | CHSC_FLAG_SIGA_OUTPUT_NECESSARY || | 2332 | CHSC_FLAG_SIGA_OUTPUT_NECESSARY || |
2000 | CHSC_FLAG_SIGA_SYNC_NECESSARY; /* all flags set */ | 2333 | CHSC_FLAG_SIGA_SYNC_NECESSARY; /* all flags set */ |
2334 | irq_ptr->is_qebsm = 0; | ||
2001 | goto out; | 2335 | goto out; |
2002 | } | 2336 | } |
2003 | 2337 | ||
2004 | if (ssqd_area->response.code != QDIO_CHSC_RESPONSE_CODE_OK) { | 2338 | if (ssqd_area->response.code != QDIO_CHSC_RESPONSE_CODE_OK) { |
2005 | QDIO_PRINT_WARN("response upon checking SIGA needs " \ | 2339 | QDIO_PRINT_WARN("response upon checking SIGA needs " \ |
2006 | "is 0x%x. Using all SIGAs for sch x%x.\n", | 2340 | "is 0x%x. Using all SIGAs for sch 0.%x.%x.\n", |
2007 | ssqd_area->response.code, sch); | 2341 | ssqd_area->response.code, |
2342 | irq_ptr->schid.ssid, irq_ptr->schid.sch_no); | ||
2008 | qdioac = CHSC_FLAG_SIGA_INPUT_NECESSARY || | 2343 | qdioac = CHSC_FLAG_SIGA_INPUT_NECESSARY || |
2009 | CHSC_FLAG_SIGA_OUTPUT_NECESSARY || | 2344 | CHSC_FLAG_SIGA_OUTPUT_NECESSARY || |
2010 | CHSC_FLAG_SIGA_SYNC_NECESSARY; /* all flags set */ | 2345 | CHSC_FLAG_SIGA_SYNC_NECESSARY; /* all flags set */ |
2346 | irq_ptr->is_qebsm = 0; | ||
2011 | goto out; | 2347 | goto out; |
2012 | } | 2348 | } |
2013 | if (!(ssqd_area->flags & CHSC_FLAG_QDIO_CAPABILITY) || | 2349 | if (!(ssqd_area->flags & CHSC_FLAG_QDIO_CAPABILITY) || |
2014 | !(ssqd_area->flags & CHSC_FLAG_VALIDITY) || | 2350 | !(ssqd_area->flags & CHSC_FLAG_VALIDITY) || |
2015 | (ssqd_area->sch != sch)) { | 2351 | (ssqd_area->sch != irq_ptr->schid.sch_no)) { |
2016 | QDIO_PRINT_WARN("huh? problems checking out sch x%x... " \ | 2352 | QDIO_PRINT_WARN("huh? problems checking out sch 0.%x.%x... " \ |
2017 | "using all SIGAs.\n",sch); | 2353 | "using all SIGAs.\n", |
2354 | irq_ptr->schid.ssid, irq_ptr->schid.sch_no); | ||
2018 | qdioac = CHSC_FLAG_SIGA_INPUT_NECESSARY | | 2355 | qdioac = CHSC_FLAG_SIGA_INPUT_NECESSARY | |
2019 | CHSC_FLAG_SIGA_OUTPUT_NECESSARY | | 2356 | CHSC_FLAG_SIGA_OUTPUT_NECESSARY | |
2020 | CHSC_FLAG_SIGA_SYNC_NECESSARY; /* worst case */ | 2357 | CHSC_FLAG_SIGA_SYNC_NECESSARY; /* worst case */ |
2358 | irq_ptr->is_qebsm = 0; | ||
2021 | goto out; | 2359 | goto out; |
2022 | } | 2360 | } |
2023 | 2361 | qdioac = ssqd_area->qdioac1; | |
2024 | qdioac = ssqd_area->qdioac; | ||
2025 | out: | 2362 | out: |
2363 | qdio_check_subchannel_qebsm(irq_ptr, qdioac, | ||
2364 | ssqd_area->sch_token); | ||
2026 | free_page ((unsigned long) ssqd_area); | 2365 | free_page ((unsigned long) ssqd_area); |
2027 | return qdioac; | 2366 | irq_ptr->qdioac = qdioac; |
2028 | } | 2367 | } |
2029 | 2368 | ||
2030 | static unsigned int | 2369 | static unsigned int |
@@ -2055,6 +2394,13 @@ tiqdio_check_chsc_availability(void) | |||
2055 | sprintf(dbf_text,"hydrati%1x", hydra_thinints); | 2394 | sprintf(dbf_text,"hydrati%1x", hydra_thinints); |
2056 | QDIO_DBF_TEXT0(0,setup,dbf_text); | 2395 | QDIO_DBF_TEXT0(0,setup,dbf_text); |
2057 | 2396 | ||
2397 | #ifdef CONFIG_64BIT | ||
2398 | /* Check for QEBSM support in general (bit 58). */ | ||
2399 | is_passthrough = css_general_characteristics.qebsm; | ||
2400 | #endif | ||
2401 | sprintf(dbf_text,"cssQBS:%1x", is_passthrough); | ||
2402 | QDIO_DBF_TEXT0(0,setup,dbf_text); | ||
2403 | |||
2058 | /* Check for aif time delay disablement fac (bit 56). If installed, | 2404 | /* Check for aif time delay disablement fac (bit 56). If installed, |
2059 | * omit svs even under lpar (good point by rick again) */ | 2405 | * omit svs even under lpar (good point by rick again) */ |
2060 | omit_svs = css_general_characteristics.aif_tdd; | 2406 | omit_svs = css_general_characteristics.aif_tdd; |
@@ -2091,7 +2437,7 @@ tiqdio_set_subchannel_ind(struct qdio_irq *irq_ptr, int reset_to_zero) | |||
2091 | /* set to 0x10000000 to enable | 2437 | /* set to 0x10000000 to enable |
2092 | * time delay disablement facility */ | 2438 | * time delay disablement facility */ |
2093 | u32 reserved5; | 2439 | u32 reserved5; |
2094 | u32 subsystem_id; | 2440 | struct subchannel_id schid; |
2095 | u32 reserved6[1004]; | 2441 | u32 reserved6[1004]; |
2096 | struct chsc_header response; | 2442 | struct chsc_header response; |
2097 | u32 reserved7; | 2443 | u32 reserved7; |
@@ -2113,7 +2459,8 @@ tiqdio_set_subchannel_ind(struct qdio_irq *irq_ptr, int reset_to_zero) | |||
2113 | scssc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); | 2459 | scssc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); |
2114 | if (!scssc_area) { | 2460 | if (!scssc_area) { |
2115 | QDIO_PRINT_WARN("No memory for setting indicators on " \ | 2461 | QDIO_PRINT_WARN("No memory for setting indicators on " \ |
2116 | "subchannel x%x.\n", irq_ptr->irq); | 2462 | "subchannel 0.%x.%x.\n", |
2463 | irq_ptr->schid.ssid, irq_ptr->schid.sch_no); | ||
2117 | return -ENOMEM; | 2464 | return -ENOMEM; |
2118 | } | 2465 | } |
2119 | scssc_area->request = (struct chsc_header) { | 2466 | scssc_area->request = (struct chsc_header) { |
@@ -2127,7 +2474,7 @@ tiqdio_set_subchannel_ind(struct qdio_irq *irq_ptr, int reset_to_zero) | |||
2127 | scssc_area->ks = QDIO_STORAGE_KEY; | 2474 | scssc_area->ks = QDIO_STORAGE_KEY; |
2128 | scssc_area->kc = QDIO_STORAGE_KEY; | 2475 | scssc_area->kc = QDIO_STORAGE_KEY; |
2129 | scssc_area->isc = TIQDIO_THININT_ISC; | 2476 | scssc_area->isc = TIQDIO_THININT_ISC; |
2130 | scssc_area->subsystem_id = (1<<16) + irq_ptr->irq; | 2477 | scssc_area->schid = irq_ptr->schid; |
2131 | /* enables the time delay disablement facility. Don't care | 2478 | /* enables the time delay disablement facility. Don't care |
2132 | * whether it is really there (i.e. we haven't checked for | 2479 | * whether it is really there (i.e. we haven't checked for |
2133 | * it) */ | 2480 | * it) */ |
@@ -2137,12 +2484,11 @@ tiqdio_set_subchannel_ind(struct qdio_irq *irq_ptr, int reset_to_zero) | |||
2137 | QDIO_PRINT_WARN("Time delay disablement facility " \ | 2484 | QDIO_PRINT_WARN("Time delay disablement facility " \ |
2138 | "not available\n"); | 2485 | "not available\n"); |
2139 | 2486 | ||
2140 | |||
2141 | |||
2142 | result = chsc(scssc_area); | 2487 | result = chsc(scssc_area); |
2143 | if (result) { | 2488 | if (result) { |
2144 | QDIO_PRINT_WARN("could not set indicators on irq x%x, " \ | 2489 | QDIO_PRINT_WARN("could not set indicators on irq 0.%x.%x, " \ |
2145 | "cc=%i.\n",irq_ptr->irq,result); | 2490 | "cc=%i.\n", |
2491 | irq_ptr->schid.ssid, irq_ptr->schid.sch_no,result); | ||
2146 | result = -EIO; | 2492 | result = -EIO; |
2147 | goto out; | 2493 | goto out; |
2148 | } | 2494 | } |
@@ -2198,7 +2544,8 @@ tiqdio_set_delay_target(struct qdio_irq *irq_ptr, unsigned long delay_target) | |||
2198 | scsscf_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); | 2544 | scsscf_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); |
2199 | if (!scsscf_area) { | 2545 | if (!scsscf_area) { |
2200 | QDIO_PRINT_WARN("No memory for setting delay target on " \ | 2546 | QDIO_PRINT_WARN("No memory for setting delay target on " \ |
2201 | "subchannel x%x.\n", irq_ptr->irq); | 2547 | "subchannel 0.%x.%x.\n", |
2548 | irq_ptr->schid.ssid, irq_ptr->schid.sch_no); | ||
2202 | return -ENOMEM; | 2549 | return -ENOMEM; |
2203 | } | 2550 | } |
2204 | scsscf_area->request = (struct chsc_header) { | 2551 | scsscf_area->request = (struct chsc_header) { |
@@ -2210,8 +2557,10 @@ tiqdio_set_delay_target(struct qdio_irq *irq_ptr, unsigned long delay_target) | |||
2210 | 2557 | ||
2211 | result=chsc(scsscf_area); | 2558 | result=chsc(scsscf_area); |
2212 | if (result) { | 2559 | if (result) { |
2213 | QDIO_PRINT_WARN("could not set delay target on irq x%x, " \ | 2560 | QDIO_PRINT_WARN("could not set delay target on irq 0.%x.%x, " \ |
2214 | "cc=%i. Continuing.\n",irq_ptr->irq,result); | 2561 | "cc=%i. Continuing.\n", |
2562 | irq_ptr->schid.ssid, irq_ptr->schid.sch_no, | ||
2563 | result); | ||
2215 | result = -EIO; | 2564 | result = -EIO; |
2216 | goto out; | 2565 | goto out; |
2217 | } | 2566 | } |
@@ -2245,7 +2594,7 @@ qdio_cleanup(struct ccw_device *cdev, int how) | |||
2245 | if (!irq_ptr) | 2594 | if (!irq_ptr) |
2246 | return -ENODEV; | 2595 | return -ENODEV; |
2247 | 2596 | ||
2248 | sprintf(dbf_text,"qcln%4x",irq_ptr->irq); | 2597 | sprintf(dbf_text,"qcln%4x",irq_ptr->schid.sch_no); |
2249 | QDIO_DBF_TEXT1(0,trace,dbf_text); | 2598 | QDIO_DBF_TEXT1(0,trace,dbf_text); |
2250 | QDIO_DBF_TEXT0(0,setup,dbf_text); | 2599 | QDIO_DBF_TEXT0(0,setup,dbf_text); |
2251 | 2600 | ||
@@ -2272,7 +2621,7 @@ qdio_shutdown(struct ccw_device *cdev, int how) | |||
2272 | 2621 | ||
2273 | down(&irq_ptr->setting_up_sema); | 2622 | down(&irq_ptr->setting_up_sema); |
2274 | 2623 | ||
2275 | sprintf(dbf_text,"qsqs%4x",irq_ptr->irq); | 2624 | sprintf(dbf_text,"qsqs%4x",irq_ptr->schid.sch_no); |
2276 | QDIO_DBF_TEXT1(0,trace,dbf_text); | 2625 | QDIO_DBF_TEXT1(0,trace,dbf_text); |
2277 | QDIO_DBF_TEXT0(0,setup,dbf_text); | 2626 | QDIO_DBF_TEXT0(0,setup,dbf_text); |
2278 | 2627 | ||
@@ -2378,7 +2727,7 @@ qdio_free(struct ccw_device *cdev) | |||
2378 | 2727 | ||
2379 | down(&irq_ptr->setting_up_sema); | 2728 | down(&irq_ptr->setting_up_sema); |
2380 | 2729 | ||
2381 | sprintf(dbf_text,"qfqs%4x",irq_ptr->irq); | 2730 | sprintf(dbf_text,"qfqs%4x",irq_ptr->schid.sch_no); |
2382 | QDIO_DBF_TEXT1(0,trace,dbf_text); | 2731 | QDIO_DBF_TEXT1(0,trace,dbf_text); |
2383 | QDIO_DBF_TEXT0(0,setup,dbf_text); | 2732 | QDIO_DBF_TEXT0(0,setup,dbf_text); |
2384 | 2733 | ||
@@ -2526,13 +2875,14 @@ qdio_establish_irq_check_for_errors(struct ccw_device *cdev, int cstat, | |||
2526 | irq_ptr = cdev->private->qdio_data; | 2875 | irq_ptr = cdev->private->qdio_data; |
2527 | 2876 | ||
2528 | if (cstat || (dstat & ~(DEV_STAT_CHN_END|DEV_STAT_DEV_END))) { | 2877 | if (cstat || (dstat & ~(DEV_STAT_CHN_END|DEV_STAT_DEV_END))) { |
2529 | sprintf(dbf_text,"ick1%4x",irq_ptr->irq); | 2878 | sprintf(dbf_text,"ick1%4x",irq_ptr->schid.sch_no); |
2530 | QDIO_DBF_TEXT2(1,trace,dbf_text); | 2879 | QDIO_DBF_TEXT2(1,trace,dbf_text); |
2531 | QDIO_DBF_HEX2(0,trace,&dstat,sizeof(int)); | 2880 | QDIO_DBF_HEX2(0,trace,&dstat,sizeof(int)); |
2532 | QDIO_DBF_HEX2(0,trace,&cstat,sizeof(int)); | 2881 | QDIO_DBF_HEX2(0,trace,&cstat,sizeof(int)); |
2533 | QDIO_PRINT_ERR("received check condition on establish " \ | 2882 | QDIO_PRINT_ERR("received check condition on establish " \ |
2534 | "queues on irq 0x%x (cs=x%x, ds=x%x).\n", | 2883 | "queues on irq 0.%x.%x (cs=x%x, ds=x%x).\n", |
2535 | irq_ptr->irq,cstat,dstat); | 2884 | irq_ptr->schid.ssid, irq_ptr->schid.sch_no, |
2885 | cstat,dstat); | ||
2536 | qdio_set_state(irq_ptr,QDIO_IRQ_STATE_ERR); | 2886 | qdio_set_state(irq_ptr,QDIO_IRQ_STATE_ERR); |
2537 | } | 2887 | } |
2538 | 2888 | ||
@@ -2540,9 +2890,10 @@ qdio_establish_irq_check_for_errors(struct ccw_device *cdev, int cstat, | |||
2540 | QDIO_DBF_TEXT2(1,setup,"eq:no de"); | 2890 | QDIO_DBF_TEXT2(1,setup,"eq:no de"); |
2541 | QDIO_DBF_HEX2(0,setup,&dstat, sizeof(dstat)); | 2891 | QDIO_DBF_HEX2(0,setup,&dstat, sizeof(dstat)); |
2542 | QDIO_DBF_HEX2(0,setup,&cstat, sizeof(cstat)); | 2892 | QDIO_DBF_HEX2(0,setup,&cstat, sizeof(cstat)); |
2543 | QDIO_PRINT_ERR("establish queues on irq %04x: didn't get " | 2893 | QDIO_PRINT_ERR("establish queues on irq 0.%x.%04x: didn't get " |
2544 | "device end: dstat=%02x, cstat=%02x\n", | 2894 | "device end: dstat=%02x, cstat=%02x\n", |
2545 | irq_ptr->irq, dstat, cstat); | 2895 | irq_ptr->schid.ssid, irq_ptr->schid.sch_no, |
2896 | dstat, cstat); | ||
2546 | qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR); | 2897 | qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR); |
2547 | return 1; | 2898 | return 1; |
2548 | } | 2899 | } |
@@ -2551,10 +2902,10 @@ qdio_establish_irq_check_for_errors(struct ccw_device *cdev, int cstat, | |||
2551 | QDIO_DBF_TEXT2(1,setup,"eq:badio"); | 2902 | QDIO_DBF_TEXT2(1,setup,"eq:badio"); |
2552 | QDIO_DBF_HEX2(0,setup,&dstat, sizeof(dstat)); | 2903 | QDIO_DBF_HEX2(0,setup,&dstat, sizeof(dstat)); |
2553 | QDIO_DBF_HEX2(0,setup,&cstat, sizeof(cstat)); | 2904 | QDIO_DBF_HEX2(0,setup,&cstat, sizeof(cstat)); |
2554 | QDIO_PRINT_ERR("establish queues on irq %04x: got " | 2905 | QDIO_PRINT_ERR("establish queues on irq 0.%x.%04x: got " |
2555 | "the following devstat: dstat=%02x, " | 2906 | "the following devstat: dstat=%02x, " |
2556 | "cstat=%02x\n", | 2907 | "cstat=%02x\n", irq_ptr->schid.ssid, |
2557 | irq_ptr->irq, dstat, cstat); | 2908 | irq_ptr->schid.sch_no, dstat, cstat); |
2558 | qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR); | 2909 | qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR); |
2559 | return 1; | 2910 | return 1; |
2560 | } | 2911 | } |
@@ -2569,7 +2920,7 @@ qdio_establish_handle_irq(struct ccw_device *cdev, int cstat, int dstat) | |||
2569 | 2920 | ||
2570 | irq_ptr = cdev->private->qdio_data; | 2921 | irq_ptr = cdev->private->qdio_data; |
2571 | 2922 | ||
2572 | sprintf(dbf_text,"qehi%4x",cdev->private->irq); | 2923 | sprintf(dbf_text,"qehi%4x",cdev->private->sch_no); |
2573 | QDIO_DBF_TEXT0(0,setup,dbf_text); | 2924 | QDIO_DBF_TEXT0(0,setup,dbf_text); |
2574 | QDIO_DBF_TEXT0(0,trace,dbf_text); | 2925 | QDIO_DBF_TEXT0(0,trace,dbf_text); |
2575 | 2926 | ||
@@ -2588,7 +2939,7 @@ qdio_initialize(struct qdio_initialize *init_data) | |||
2588 | int rc; | 2939 | int rc; |
2589 | char dbf_text[15]; | 2940 | char dbf_text[15]; |
2590 | 2941 | ||
2591 | sprintf(dbf_text,"qini%4x",init_data->cdev->private->irq); | 2942 | sprintf(dbf_text,"qini%4x",init_data->cdev->private->sch_no); |
2592 | QDIO_DBF_TEXT0(0,setup,dbf_text); | 2943 | QDIO_DBF_TEXT0(0,setup,dbf_text); |
2593 | QDIO_DBF_TEXT0(0,trace,dbf_text); | 2944 | QDIO_DBF_TEXT0(0,trace,dbf_text); |
2594 | 2945 | ||
@@ -2609,7 +2960,7 @@ qdio_allocate(struct qdio_initialize *init_data) | |||
2609 | struct qdio_irq *irq_ptr; | 2960 | struct qdio_irq *irq_ptr; |
2610 | char dbf_text[15]; | 2961 | char dbf_text[15]; |
2611 | 2962 | ||
2612 | sprintf(dbf_text,"qalc%4x",init_data->cdev->private->irq); | 2963 | sprintf(dbf_text,"qalc%4x",init_data->cdev->private->sch_no); |
2613 | QDIO_DBF_TEXT0(0,setup,dbf_text); | 2964 | QDIO_DBF_TEXT0(0,setup,dbf_text); |
2614 | QDIO_DBF_TEXT0(0,trace,dbf_text); | 2965 | QDIO_DBF_TEXT0(0,trace,dbf_text); |
2615 | if ( (init_data->no_input_qs>QDIO_MAX_QUEUES_PER_IRQ) || | 2966 | if ( (init_data->no_input_qs>QDIO_MAX_QUEUES_PER_IRQ) || |
@@ -2682,7 +3033,7 @@ int qdio_fill_irq(struct qdio_initialize *init_data) | |||
2682 | 3033 | ||
2683 | irq_ptr->int_parm=init_data->int_parm; | 3034 | irq_ptr->int_parm=init_data->int_parm; |
2684 | 3035 | ||
2685 | irq_ptr->irq = init_data->cdev->private->irq; | 3036 | irq_ptr->schid = ccw_device_get_subchannel_id(init_data->cdev); |
2686 | irq_ptr->no_input_qs=init_data->no_input_qs; | 3037 | irq_ptr->no_input_qs=init_data->no_input_qs; |
2687 | irq_ptr->no_output_qs=init_data->no_output_qs; | 3038 | irq_ptr->no_output_qs=init_data->no_output_qs; |
2688 | 3039 | ||
@@ -2698,11 +3049,12 @@ int qdio_fill_irq(struct qdio_initialize *init_data) | |||
2698 | QDIO_DBF_TEXT2(0,setup,dbf_text); | 3049 | QDIO_DBF_TEXT2(0,setup,dbf_text); |
2699 | 3050 | ||
2700 | if (irq_ptr->is_thinint_irq) { | 3051 | if (irq_ptr->is_thinint_irq) { |
2701 | irq_ptr->dev_st_chg_ind=qdio_get_indicator(); | 3052 | irq_ptr->dev_st_chg_ind = qdio_get_indicator(); |
2702 | QDIO_DBF_HEX1(0,setup,&irq_ptr->dev_st_chg_ind,sizeof(void*)); | 3053 | QDIO_DBF_HEX1(0,setup,&irq_ptr->dev_st_chg_ind,sizeof(void*)); |
2703 | if (!irq_ptr->dev_st_chg_ind) { | 3054 | if (!irq_ptr->dev_st_chg_ind) { |
2704 | QDIO_PRINT_WARN("no indicator location available " \ | 3055 | QDIO_PRINT_WARN("no indicator location available " \ |
2705 | "for irq 0x%x\n",irq_ptr->irq); | 3056 | "for irq 0.%x.%x\n", |
3057 | irq_ptr->schid.ssid, irq_ptr->schid.sch_no); | ||
2706 | qdio_release_irq_memory(irq_ptr); | 3058 | qdio_release_irq_memory(irq_ptr); |
2707 | return -ENOBUFS; | 3059 | return -ENOBUFS; |
2708 | } | 3060 | } |
@@ -2747,6 +3099,10 @@ int qdio_fill_irq(struct qdio_initialize *init_data) | |||
2747 | irq_ptr->qdr->qkey=QDIO_STORAGE_KEY; | 3099 | irq_ptr->qdr->qkey=QDIO_STORAGE_KEY; |
2748 | 3100 | ||
2749 | /* fill in qib */ | 3101 | /* fill in qib */ |
3102 | irq_ptr->is_qebsm = is_passthrough; | ||
3103 | if (irq_ptr->is_qebsm) | ||
3104 | irq_ptr->qib.rflags |= QIB_RFLAGS_ENABLE_QEBSM; | ||
3105 | |||
2750 | irq_ptr->qib.qfmt=init_data->q_format; | 3106 | irq_ptr->qib.qfmt=init_data->q_format; |
2751 | if (init_data->no_input_qs) | 3107 | if (init_data->no_input_qs) |
2752 | irq_ptr->qib.isliba=(unsigned long)(irq_ptr->input_qs[0]->slib); | 3108 | irq_ptr->qib.isliba=(unsigned long)(irq_ptr->input_qs[0]->slib); |
@@ -2829,7 +3185,7 @@ qdio_establish(struct qdio_initialize *init_data) | |||
2829 | tiqdio_set_delay_target(irq_ptr,TIQDIO_DELAY_TARGET); | 3185 | tiqdio_set_delay_target(irq_ptr,TIQDIO_DELAY_TARGET); |
2830 | } | 3186 | } |
2831 | 3187 | ||
2832 | sprintf(dbf_text,"qest%4x",cdev->private->irq); | 3188 | sprintf(dbf_text,"qest%4x",cdev->private->sch_no); |
2833 | QDIO_DBF_TEXT0(0,setup,dbf_text); | 3189 | QDIO_DBF_TEXT0(0,setup,dbf_text); |
2834 | QDIO_DBF_TEXT0(0,trace,dbf_text); | 3190 | QDIO_DBF_TEXT0(0,trace,dbf_text); |
2835 | 3191 | ||
@@ -2855,9 +3211,10 @@ qdio_establish(struct qdio_initialize *init_data) | |||
2855 | sprintf(dbf_text,"eq:io%4x",result); | 3211 | sprintf(dbf_text,"eq:io%4x",result); |
2856 | QDIO_DBF_TEXT2(1,setup,dbf_text); | 3212 | QDIO_DBF_TEXT2(1,setup,dbf_text); |
2857 | } | 3213 | } |
2858 | QDIO_PRINT_WARN("establish queues on irq %04x: do_IO " \ | 3214 | QDIO_PRINT_WARN("establish queues on irq 0.%x.%04x: do_IO " \ |
2859 | "returned %i, next try returned %i\n", | 3215 | "returned %i, next try returned %i\n", |
2860 | irq_ptr->irq,result,result2); | 3216 | irq_ptr->schid.ssid, irq_ptr->schid.sch_no, |
3217 | result, result2); | ||
2861 | result=result2; | 3218 | result=result2; |
2862 | if (result) | 3219 | if (result) |
2863 | ccw_device_set_timeout(cdev, 0); | 3220 | ccw_device_set_timeout(cdev, 0); |
@@ -2884,7 +3241,7 @@ qdio_establish(struct qdio_initialize *init_data) | |||
2884 | return -EIO; | 3241 | return -EIO; |
2885 | } | 3242 | } |
2886 | 3243 | ||
2887 | irq_ptr->qdioac=qdio_check_siga_needs(irq_ptr->irq); | 3244 | qdio_get_ssqd_information(irq_ptr); |
2888 | /* if this gets set once, we're running under VM and can omit SVSes */ | 3245 | /* if this gets set once, we're running under VM and can omit SVSes */ |
2889 | if (irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_NECESSARY) | 3246 | if (irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_NECESSARY) |
2890 | omit_svs=1; | 3247 | omit_svs=1; |
@@ -2930,7 +3287,7 @@ qdio_activate(struct ccw_device *cdev, int flags) | |||
2930 | goto out; | 3287 | goto out; |
2931 | } | 3288 | } |
2932 | 3289 | ||
2933 | sprintf(dbf_text,"qact%4x", irq_ptr->irq); | 3290 | sprintf(dbf_text,"qact%4x", irq_ptr->schid.sch_no); |
2934 | QDIO_DBF_TEXT2(0,setup,dbf_text); | 3291 | QDIO_DBF_TEXT2(0,setup,dbf_text); |
2935 | QDIO_DBF_TEXT2(0,trace,dbf_text); | 3292 | QDIO_DBF_TEXT2(0,trace,dbf_text); |
2936 | 3293 | ||
@@ -2955,9 +3312,10 @@ qdio_activate(struct ccw_device *cdev, int flags) | |||
2955 | sprintf(dbf_text,"aq:io%4x",result); | 3312 | sprintf(dbf_text,"aq:io%4x",result); |
2956 | QDIO_DBF_TEXT2(1,setup,dbf_text); | 3313 | QDIO_DBF_TEXT2(1,setup,dbf_text); |
2957 | } | 3314 | } |
2958 | QDIO_PRINT_WARN("activate queues on irq %04x: do_IO " \ | 3315 | QDIO_PRINT_WARN("activate queues on irq 0.%x.%04x: do_IO " \ |
2959 | "returned %i, next try returned %i\n", | 3316 | "returned %i, next try returned %i\n", |
2960 | irq_ptr->irq,result,result2); | 3317 | irq_ptr->schid.ssid, irq_ptr->schid.sch_no, |
3318 | result, result2); | ||
2961 | result=result2; | 3319 | result=result2; |
2962 | } | 3320 | } |
2963 | 3321 | ||
@@ -3015,30 +3373,40 @@ static inline void | |||
3015 | qdio_do_qdio_fill_input(struct qdio_q *q, unsigned int qidx, | 3373 | qdio_do_qdio_fill_input(struct qdio_q *q, unsigned int qidx, |
3016 | unsigned int count, struct qdio_buffer *buffers) | 3374 | unsigned int count, struct qdio_buffer *buffers) |
3017 | { | 3375 | { |
3376 | struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr; | ||
3377 | qidx &= (QDIO_MAX_BUFFERS_PER_Q - 1); | ||
3378 | if (irq->is_qebsm) { | ||
3379 | while (count) | ||
3380 | set_slsb(q, &qidx, SLSB_CU_INPUT_EMPTY, &count); | ||
3381 | return; | ||
3382 | } | ||
3018 | for (;;) { | 3383 | for (;;) { |
3019 | set_slsb(&q->slsb.acc.val[qidx],SLSB_CU_INPUT_EMPTY); | 3384 | set_slsb(q, &qidx, SLSB_CU_INPUT_EMPTY, &count); |
3020 | count--; | 3385 | count--; |
3021 | if (!count) break; | 3386 | if (!count) break; |
3022 | qidx=(qidx+1)&(QDIO_MAX_BUFFERS_PER_Q-1); | 3387 | qidx = (qidx + 1) & (QDIO_MAX_BUFFERS_PER_Q - 1); |
3023 | } | 3388 | } |
3024 | |||
3025 | /* not necessary, as the queues are synced during the SIGA read */ | ||
3026 | /*SYNC_MEMORY;*/ | ||
3027 | } | 3389 | } |
3028 | 3390 | ||
3029 | static inline void | 3391 | static inline void |
3030 | qdio_do_qdio_fill_output(struct qdio_q *q, unsigned int qidx, | 3392 | qdio_do_qdio_fill_output(struct qdio_q *q, unsigned int qidx, |
3031 | unsigned int count, struct qdio_buffer *buffers) | 3393 | unsigned int count, struct qdio_buffer *buffers) |
3032 | { | 3394 | { |
3395 | struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr; | ||
3396 | |||
3397 | qidx &= (QDIO_MAX_BUFFERS_PER_Q - 1); | ||
3398 | if (irq->is_qebsm) { | ||
3399 | while (count) | ||
3400 | set_slsb(q, &qidx, SLSB_CU_OUTPUT_PRIMED, &count); | ||
3401 | return; | ||
3402 | } | ||
3403 | |||
3033 | for (;;) { | 3404 | for (;;) { |
3034 | set_slsb(&q->slsb.acc.val[qidx],SLSB_CU_OUTPUT_PRIMED); | 3405 | set_slsb(q, &qidx, SLSB_CU_OUTPUT_PRIMED, &count); |
3035 | count--; | 3406 | count--; |
3036 | if (!count) break; | 3407 | if (!count) break; |
3037 | qidx=(qidx+1)&(QDIO_MAX_BUFFERS_PER_Q-1); | 3408 | qidx = (qidx + 1) & (QDIO_MAX_BUFFERS_PER_Q - 1); |
3038 | } | 3409 | } |
3039 | |||
3040 | /* SIGA write will sync the queues */ | ||
3041 | /*SYNC_MEMORY;*/ | ||
3042 | } | 3410 | } |
3043 | 3411 | ||
3044 | static inline void | 3412 | static inline void |
@@ -3083,6 +3451,9 @@ do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags, | |||
3083 | struct qdio_buffer *buffers) | 3451 | struct qdio_buffer *buffers) |
3084 | { | 3452 | { |
3085 | int used_elements; | 3453 | int used_elements; |
3454 | unsigned int cnt, start_buf; | ||
3455 | unsigned char state = 0; | ||
3456 | struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr; | ||
3086 | 3457 | ||
3087 | /* This is the outbound handling of queues */ | 3458 | /* This is the outbound handling of queues */ |
3088 | #ifdef QDIO_PERFORMANCE_STATS | 3459 | #ifdef QDIO_PERFORMANCE_STATS |
@@ -3115,9 +3486,15 @@ do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags, | |||
3115 | * SYNC_MEMORY :-/ ), we try to | 3486 | * SYNC_MEMORY :-/ ), we try to |
3116 | * fast-requeue buffers | 3487 | * fast-requeue buffers |
3117 | */ | 3488 | */ |
3118 | if (q->slsb.acc.val[(qidx+QDIO_MAX_BUFFERS_PER_Q-1) | 3489 | if (irq->is_qebsm) { |
3119 | &(QDIO_MAX_BUFFERS_PER_Q-1)]!= | 3490 | cnt = 1; |
3120 | SLSB_CU_OUTPUT_PRIMED) { | 3491 | start_buf = ((qidx+QDIO_MAX_BUFFERS_PER_Q-1) & |
3492 | (QDIO_MAX_BUFFERS_PER_Q-1)); | ||
3493 | qdio_do_eqbs(q, &state, &start_buf, &cnt); | ||
3494 | } else | ||
3495 | state = q->slsb.acc.val[(qidx+QDIO_MAX_BUFFERS_PER_Q-1) | ||
3496 | &(QDIO_MAX_BUFFERS_PER_Q-1) ]; | ||
3497 | if (state != SLSB_CU_OUTPUT_PRIMED) { | ||
3121 | qdio_kick_outbound_q(q); | 3498 | qdio_kick_outbound_q(q); |
3122 | } else { | 3499 | } else { |
3123 | QDIO_DBF_TEXT3(0,trace, "fast-req"); | 3500 | QDIO_DBF_TEXT3(0,trace, "fast-req"); |
@@ -3150,7 +3527,7 @@ do_QDIO(struct ccw_device *cdev,unsigned int callflags, | |||
3150 | #ifdef CONFIG_QDIO_DEBUG | 3527 | #ifdef CONFIG_QDIO_DEBUG |
3151 | char dbf_text[20]; | 3528 | char dbf_text[20]; |
3152 | 3529 | ||
3153 | sprintf(dbf_text,"doQD%04x",cdev->private->irq); | 3530 | sprintf(dbf_text,"doQD%04x",cdev->private->sch_no); |
3154 | QDIO_DBF_TEXT3(0,trace,dbf_text); | 3531 | QDIO_DBF_TEXT3(0,trace,dbf_text); |
3155 | #endif /* CONFIG_QDIO_DEBUG */ | 3532 | #endif /* CONFIG_QDIO_DEBUG */ |
3156 | 3533 | ||