1 /*
2  *
3  * linux/drivers/s390/qdio.c
4  *
5  * Linux for S/390 QDIO base support, Hipersocket base support
6  * version 2
7  *
8  * Copyright 2000,2002 IBM Corporation
9  * Author(s): Utz Bacher <utz.bacher@de.ibm.com>
10  *
11  * Restriction: only 63 iqdio subchannels would have its own indicator,
12  * after that, subsequent subchannels share one indicator
13  *
14  *
15  *
16  *
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation; either version 2, or (at your option)
20  * any later version.
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30  */
31 
32 /* we want the eyecatcher to be at the top of the code */
qdio_eyecatcher(void)33 void volatile qdio_eyecatcher(void)
34 {
35 	return;
36 }
37 
38 #include <linux/config.h>
39 
40 #include <linux/module.h>
41 
42 #include <linux/version.h>
43 #include <linux/slab.h>
44 #include <linux/kernel.h>
45 #include <linux/proc_fs.h>
46 #include <linux/init.h>
47 #include <linux/timer.h>
48 #include <linux/mm.h>
49 
50 #include <asm/irq.h>
51 #include <asm/io.h>
52 #include <asm/atomic.h>
53 #include <asm/semaphore.h>
54 #include <asm/page.h>
55 
56 #include <asm/debug.h>
57 
58 #include <asm/qdio.h>
59 
60 #define VERSION_QDIO_C "$Revision: 1.145.4.9 $"
61 
62 /****************** MODULE PARAMETER VARIABLES ********************/
63 MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
64 MODULE_DESCRIPTION("QDIO base support version 2, " \
65 		   "Copyright 2000 IBM Corporation");
66 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,12))
67 MODULE_LICENSE("GPL");
68 #endif
69 
70 /******************** HERE WE GO ***********************************/
71 
72 static const char *version="QDIO base support version 2 ("
73 	VERSION_QDIO_C "/" VERSION_QDIO_H ")";
74 
75 #ifdef QDIO_PERFORMANCE_STATS
76 static int proc_perf_file_registration;
77 unsigned long i_p_c=0,i_p_nc=0,o_p_c=0,o_p_nc=0,ii_p_c=0,ii_p_nc=0;
78 
79 static struct {
80 	unsigned int tl_runs;
81 
82 	unsigned int siga_outs;
83 	unsigned int siga_ins;
84 	unsigned int siga_syncs;
85 	unsigned int pcis;
86 	unsigned int thinints;
87 	unsigned int fast_reqs;
88 
89 	__u64 start_time_outbound;
90 	unsigned int outbound_cnt;
91 	unsigned int outbound_time;
92 	__u64 start_time_inbound;
93 	unsigned int inbound_cnt;
94 	unsigned int inbound_time;
95 } perf_stats;
96 
97 #endif /* QDIO_PERFORMANCE_STATS */
98 
99 static int hydra_thinints=0;
100 static int omit_svs=0;
101 
102 static int indicator_used[INDICATORS_PER_CACHELINE];
103 static __u32 * volatile indicators;
104 static __u32 volatile spare_indicator;
105 static atomic_t spare_indicator_usecount;
106 
107 static debug_info_t *qdio_dbf_setup=NULL;
108 static debug_info_t *qdio_dbf_sbal=NULL;
109 static debug_info_t *qdio_dbf_trace=NULL;
110 static debug_info_t *qdio_dbf_sense=NULL;
111 #ifdef QDIO_DBF_LIKE_HELL
112 static debug_info_t *qdio_dbf_slsb_out=NULL;
113 static debug_info_t *qdio_dbf_slsb_in=NULL;
114 #endif /* QDIO_DBF_LIKE_HELL */
115 
116 static qdio_irq_t *first_irq[QDIO_IRQ_BUCKETS]={
117 	[0 ... (QDIO_IRQ_BUCKETS-1)] = NULL
118 };
119 static rwlock_t irq_list_lock[QDIO_IRQ_BUCKETS]={
120 	[0 ... (QDIO_IRQ_BUCKETS-1)] = RW_LOCK_UNLOCKED
121 };
122 
123 static struct semaphore init_sema;
124 
125 static qdio_chsc_area_t *chsc_area;
126 static spinlock_t chsc_area_lock=SPIN_LOCK_UNLOCKED;
127 /* iQDIO stuff: */
128 static volatile qdio_q_t *tiq_list=NULL; /* volatile as it could change
129 					   during a while loop */
130 static spinlock_t ttiq_list_lock=SPIN_LOCK_UNLOCKED;
131 static int register_thinint_result;
132 static void tiqdio_tl(unsigned long);
133 static DECLARE_TASKLET(tiqdio_tasklet,tiqdio_tl,0);
134 
135 #define HEXDUMP16(importance,header,ptr) \
136 QDIO_PRINT_##importance(header "%02x %02x %02x %02x  " \
137 			"%02x %02x %02x %02x  %02x %02x %02x %02x  " \
138 			"%02x %02x %02x %02x\n",*(((char*)ptr)), \
139 			*(((char*)ptr)+1),*(((char*)ptr)+2), \
140 			*(((char*)ptr)+3),*(((char*)ptr)+4), \
141 			*(((char*)ptr)+5),*(((char*)ptr)+6), \
142 			*(((char*)ptr)+7),*(((char*)ptr)+8), \
143 			*(((char*)ptr)+9),*(((char*)ptr)+10), \
144 			*(((char*)ptr)+11),*(((char*)ptr)+12), \
145 			*(((char*)ptr)+13),*(((char*)ptr)+14), \
146 			*(((char*)ptr)+15)); \
147 QDIO_PRINT_##importance(header "%02x %02x %02x %02x  %02x %02x %02x %02x  " \
148 			"%02x %02x %02x %02x  %02x %02x %02x %02x\n", \
149 			*(((char*)ptr)+16),*(((char*)ptr)+17), \
150 			*(((char*)ptr)+18),*(((char*)ptr)+19), \
151 			*(((char*)ptr)+20),*(((char*)ptr)+21), \
152 			*(((char*)ptr)+22),*(((char*)ptr)+23), \
153 			*(((char*)ptr)+24),*(((char*)ptr)+25), \
154 			*(((char*)ptr)+26),*(((char*)ptr)+27), \
155 			*(((char*)ptr)+28),*(((char*)ptr)+29), \
156 			*(((char*)ptr)+30),*(((char*)ptr)+31));
157 
158 #define atomic_swap(a,b) xchg((int*)a.counter,b)
159 
160 /* not a macro, as one of the arguments is atomic_read */
qdio_min(int a,int b)161 static inline int qdio_min(int a,int b)
162 {
163 	if (a<b)
164 		return a;
165 	else
166 		return b;
167 }
168 
169 /* unlikely as the later the better */
170 #define SYNC_MEMORY if (unlikely(q->siga_sync)) qdio_siga_sync_q(q)
171 #define SYNC_MEMORY_ALL if (unlikely(q->siga_sync)) \
172 	qdio_siga_sync(q,~0U,~0U)
173 #define SYNC_MEMORY_ALL_OUTB if (unlikely(q->siga_sync)) \
174 	qdio_siga_sync(q,~0U,0)
175 
176 #define NOW qdio_get_micros()
177 #define SAVE_TIMESTAMP(q) q->timing.last_transfer_time=NOW
178 #define GET_SAVED_TIMESTAMP(q) (q->timing.last_transfer_time)
179 #define SAVE_FRONTIER(q,val) q->last_move_ftc=val
180 #define GET_SAVED_FRONTIER(q) (q->last_move_ftc)
181 
182 #define MY_MODULE_STRING(x) #x
183 
184 #ifdef QDIO_32_BIT
185 #define QDIO_GET_32BIT_ADDR(x) ((__u32)(long)x)
186 #else /* QDIO_32_BIT */
187 #define QDIO_GET_32BIT_ADDR(x) ((__u32)(unsigned long)x)
188 #endif /* QDIO_32_BIT */
189 
190 #define QDIO_PFIX_GET_ADDR(x) ((flags&QDIO_PFIX) ? \
191 			       pfix_get_addr(x):((unsigned long)x))
192 
193 /***************** SCRUBBER HELPER ROUTINES **********************/
194 
qdio_get_micros(void)195 static inline volatile __u64 qdio_get_micros(void)
196 {
197         __u64 time;
198 
199         asm volatile ("STCK %0" : "=m" (time));
200         return time>>12; /* time>>12 is microseconds*/
201 }
qdio_get_millis(void)202 static inline unsigned long qdio_get_millis(void)
203 {
204 	return (unsigned long)(qdio_get_micros()>>10);
205 }
206 
atomic_return_add(int i,atomic_t * v)207 static __inline__ int atomic_return_add (int i, atomic_t *v)
208 {
209 	int old, new;
210 	__CS_LOOP(old, new, v, i, "ar");
211 	return old;
212 }
213 
qdio_wait_nonbusy(unsigned int timeout)214 static void qdio_wait_nonbusy(unsigned int timeout)
215 {
216         unsigned int start;
217         char dbf_text[15];
218 
219 	sprintf(dbf_text,"wtnb%4x",timeout);
220 	QDIO_DBF_TEXT3(0,trace,dbf_text);
221 
222 	start=qdio_get_millis();
223 	for (;;) {
224 		set_task_state(current,TASK_INTERRUPTIBLE);
225 		if (qdio_get_millis()-start>timeout) {
226 			goto out;
227 		}
228 		schedule_timeout(((start+timeout-qdio_get_millis())>>10)*HZ);
229 	}
230 out:
231 	set_task_state(current,TASK_RUNNING);
232 }
233 
qdio_wait_for_no_use_count(atomic_t * use_count)234 static int qdio_wait_for_no_use_count(atomic_t *use_count)
235 {
236 	unsigned long start;
237 
238 	QDIO_DBF_TEXT3(0,trace,"wtnousec");
239 	start=qdio_get_millis();
240 	for (;;) {
241 		if (qdio_get_millis()-start>QDIO_NO_USE_COUNT_TIMEOUT) {
242 			QDIO_DBF_TEXT1(1,trace,"WTNOUSTO");
243 			return -ETIME;
244 		}
245 		if (!atomic_read(use_count)) {
246 			QDIO_DBF_TEXT3(0,trace,"wtnoused");
247 			return 0;
248 		}
249 		qdio_wait_nonbusy(QDIO_NO_USE_COUNT_TIME);
250 	}
251 }
252 
253 /* unfortunately, we can't just xchg the values; in do_QDIO we want to reserve
254  * the q in any case, so that we'll not be interrupted when we are in
255  * qdio_mark_tiq... shouldn't have a really bad impact, as reserving almost
256  * ever works (last famous words) */
qdio_reserve_q(qdio_q_t * q)257 static inline int qdio_reserve_q(qdio_q_t *q)
258 {
259 	return atomic_return_add(1,&q->use_count);
260 }
261 
qdio_release_q(qdio_q_t * q)262 static inline void qdio_release_q(qdio_q_t *q)
263 {
264 	atomic_dec(&q->use_count);
265 }
266 #ifdef QDIO_DBF_LIKE_HELL
267 #define set_slsb(x,y) \
268   if(q->queue_type==QDIO_TRACE_QTYPE) { \
269         if(q->is_input_q) { \
270             QDIO_DBF_HEX2(0,slsb_in,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \
271         } else { \
272             QDIO_DBF_HEX2(0,slsb_out,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \
273         } \
274   } \
275   qdio_set_slsb(x,y); \
276   if(q->queue_type==QDIO_TRACE_QTYPE) { \
277         if(q->is_input_q) { \
278             QDIO_DBF_HEX2(0,slsb_in,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \
279         } else { \
280             QDIO_DBF_HEX2(0,slsb_out,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \
281         } \
282   }
283 #else /* QDIO_DBF_LIKE_HELL */
284 #define set_slsb(x,y) qdio_set_slsb(x,y)
285 #endif /* QDIO_DBF_LIKE_HELL */
qdio_set_slsb(volatile char * slsb,unsigned char value)286 static volatile inline void qdio_set_slsb(volatile char *slsb,
287 					  unsigned char value)
288 {
289 	xchg((char*)slsb,value);
290 }
291 
qdio_siga_sync(qdio_q_t * q,unsigned int gpr2,unsigned int gpr3)292 static inline int qdio_siga_sync(qdio_q_t *q,
293 				 unsigned int gpr2,
294 				 unsigned int gpr3)
295 {
296 	int cc;
297 
298 #ifdef QDIO_DBF_LIKE_HELL
299 	QDIO_DBF_TEXT4(0,trace,"sigasync");
300 	QDIO_DBF_HEX4(0,trace,&q,sizeof(int));
301 	QDIO_DBF_HEX4(0,trace,&gpr2,sizeof(int));
302 	QDIO_DBF_HEX4(0,trace,&gpr3,sizeof(int));
303 #endif /* QDIO_DBF_LIKE_HELL */
304 
305 #ifdef QDIO_PERFORMANCE_STATS
306 	perf_stats.siga_syncs++;
307 #endif /* QDIO_PERFORMANCE_STATS */
308 
309 #ifdef QDIO_32_BIT
310 	asm volatile (
311 		"lhi	0,2	\n\t"
312 		"lr	1,%1	\n\t"
313 		"lr	2,%2	\n\t"
314 		"lr	3,%3	\n\t"
315 		"siga   0	\n\t"
316 		"ipm	%0	\n\t"
317 		"srl	%0,28	\n\t"
318 		: "=d" (cc)
319 		: "d" (0x10000|q->irq), "d" (gpr2), "d" (gpr3)
320 		: "cc", "0", "1", "2", "3"
321 		);
322 #else /* QDIO_32_BIT */
323 	asm volatile (
324 		"lghi	0,2	\n\t"
325 		"llgfr	1,%1	\n\t"
326 		"llgfr	2,%2	\n\t"
327 		"llgfr	3,%3	\n\t"
328 		"siga   0	\n\t"
329 		"ipm	%0	\n\t"
330 		"srl	%0,28	\n\t"
331 		: "=d" (cc)
332 		: "d" (0x10000|q->irq), "d" (gpr2), "d" (gpr3)
333 		: "cc", "0", "1", "2", "3"
334 		);
335 #endif /* QDIO_32_BIT */
336 
337 	if (cc) {
338 #ifndef QDIO_DBF_LIKE_HELL
339 		/* when QDIO_DBF_LIKE_HELL, we put that already out */
340 		QDIO_DBF_TEXT3(0,trace,"sigasync");
341 		QDIO_DBF_HEX3(0,trace,&q,sizeof(void*));
342 #endif /* QDIO_DBF_LIKE_HELL */
343 		QDIO_DBF_HEX3(0,trace,&cc,sizeof(int*));
344 	}
345 
346 	return cc;
347 }
348 
qdio_siga_sync_q(qdio_q_t * q)349 static inline int qdio_siga_sync_q(qdio_q_t *q)
350 {
351 	if (q->is_input_q) {
352 		return qdio_siga_sync(q,0,q->mask);
353 	} else {
354 		return qdio_siga_sync(q,q->mask,0);
355 	}
356 }
357 
358 /* returns QDIO_SIGA_ERROR_ACCESS_EXCEPTION as cc, when SIGA returns
359    an access exception */
qdio_siga_output(qdio_q_t * q)360 static inline int qdio_siga_output(qdio_q_t *q)
361 {
362 	int cc;
363 	__u32 busy_bit;
364 	__u64 start_time=0;
365 
366 #ifdef QDIO_PERFORMANCE_STATS
367 	perf_stats.siga_outs++;
368 #endif /* QDIO_PERFORMANCE_STATS */
369 
370 #ifdef QDIO_DBF_LIKE_HELL
371 	QDIO_DBF_TEXT4(0,trace,"sigaout");
372 	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
373 #endif /* QDIO_DBF_LIKE_HELL */
374 
375 	for (;;) {
376 
377 #ifdef QDIO_32_BIT
378 		asm volatile (
379 		      "lhi	0,0	\n\t"
380 		      "lr	1,%2	\n\t"
381 		      "lr	2,%3	\n\t"
382 		      "siga	0	\n\t"
383 		      "0:"
384 		      "ipm	%0	\n\t"
385 		      "srl	%0,28	\n\t"
386 		      "srl	0,31	\n\t"
387 		      "lr	%1,0	\n\t"
388 		      "1:	\n\t"
389 		      ".section .fixup,\"ax\"\n\t"
390 		      "2:	\n\t"
391 		      "lhi	%0,%4	\n\t"
392 		      "bras	1,3f	\n\t"
393 		      ".long 1b	\n\t"
394 		      "3:	\n\t"
395 		      "l	1,0(1)	\n\t"
396 		      "br	1	\n\t"
397 		      ".previous	\n\t"
398 		      ".section __ex_table,\"a\"\n\t"
399 		      ".align 4	\n\t"
400 		      ".long	0b,2b	\n\t"
401 		      ".previous	\n\t"
402 			: "=d" (cc), "=d" (busy_bit)
403 			: "d" (0x10000|q->irq), "d" (q->mask),
404 			"i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION)
405 			: "cc", "0", "1", "2", "memory"
406 		);
407 #else /* QDIO_32_BIT */
408 		asm volatile (
409 		      "lghi	0,0	\n\t"
410 		      "llgfr	1,%2	\n\t"
411 		      "llgfr	2,%3	\n\t"
412 	      	      "siga	0	\n\t"
413 		      "0:"
414 		      "ipm	%0	\n\t"
415 		      "srl	%0,28	\n\t"
416 		      "srl	0,31	\n\t"
417 		      "llgfr	%1,0	\n\t"
418 		      "1:	\n\t"
419 		      ".section .fixup,\"ax\"\n\t"
420 		      "lghi	%0,%4	\n\t"
421 		      "jg	1b	\n\t"
422 		      ".previous\n\t"
423       		      ".section __ex_table,\"a\"\n\t"
424       		      ".align 8	\n\t"
425       		      ".quad	0b,1b	\n\t"
426       		      ".previous	\n\t"
427 		      : "=d" (cc), "=d" (busy_bit)
428 		      : "d" (0x10000|q->irq), "d" (q->mask),
429 	      	      "i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION)
430 	      	      : "cc", "0", "1", "2", "memory"
431 	     );
432 #endif /* QDIO_32_BIT */
433 
434 //QDIO_PRINT_ERR("cc=%x, busy=%x\n",cc,busy_bit);
435 	     if ( (cc==2) && (busy_bit) &&
436 		  (q->is_iqdio_q) ) {
437 		     if (!start_time) start_time=NOW;
438 		     if ((NOW-start_time)>QDIO_BUSY_BIT_PATIENCE)
439 			     break;
440 	     } else
441 		     break;
442 	}
443 
444 	if ((cc==2) && (busy_bit)) cc|=QDIO_SIGA_ERROR_B_BIT_SET;
445 
446 	if (cc) {
447 #ifndef QDIO_DBF_LIKE_HELL
448 		QDIO_DBF_TEXT3(0,trace,"sigaout");
449 		QDIO_DBF_HEX3(0,trace,&q,sizeof(void*));
450 #endif /* QDIO_DBF_LIKE_HELL */
451 		QDIO_DBF_HEX3(0,trace,&cc,sizeof(int*));
452 	}
453 
454 	return cc;
455 }
456 
qdio_siga_input(qdio_q_t * q)457 static inline int qdio_siga_input(qdio_q_t *q)
458 {
459 	int cc;
460 
461 #ifdef QDIO_DBF_LIKE_HELL
462 	QDIO_DBF_TEXT4(0,trace,"sigain");
463 	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
464 #endif /* QDIO_DBF_LIKE_HELL */
465 
466 #ifdef QDIO_PERFORMANCE_STATS
467 	perf_stats.siga_ins++;
468 #endif /* QDIO_PERFORMANCE_STATS */
469 
470 #ifdef QDIO_32_BIT
471 	asm volatile (
472 		"lhi	0,1	\n\t"
473 		"lr	1,%1	\n\t"
474 		"lr	2,%2	\n\t"
475 		"siga   0	\n\t"
476 		"ipm	%0	\n\t"
477 		"srl	%0,28	\n\t"
478 		: "=d" (cc)
479 		: "d" (0x10000|q->irq), "d" (q->mask)
480 		: "cc", "0", "1", "2", "memory"
481 		);
482 #else /* QDIO_32_BIT */
483 	asm volatile (
484 		"lghi	0,1	\n\t"
485 		"llgfr	1,%1	\n\t"
486 		"llgfr	2,%2	\n\t"
487 		"siga   0	\n\t"
488 		"ipm	%0	\n\t"
489 		"srl	%0,28	\n\t"
490 		: "=d" (cc)
491 		: "d" (0x10000|q->irq), "d" (q->mask)
492 		: "cc", "0", "1", "2", "memory"
493 		);
494 #endif /* QDIO_32_BIT */
495 
496 	if (cc) {
497 #ifndef QDIO_DBF_LIKE_HELL
498 		QDIO_DBF_TEXT3(0,trace,"sigain");
499 		QDIO_DBF_HEX3(0,trace,&q,sizeof(void*));
500 #endif /* QDIO_DBF_LIKE_HELL */
501 		QDIO_DBF_HEX3(0,trace,&cc,sizeof(int*));
502 	}
503 
504 	return cc;
505 }
506 
507 /* locked by the locks in qdio_activate and qdio_cleanup */
qdio_get_indicator(void)508 static __u32 * volatile qdio_get_indicator(void)
509 {
510 	int i=1;
511 	int found=0;
512 
513 	while (i<INDICATORS_PER_CACHELINE) {
514 		if (!indicator_used[i]) {
515 			indicator_used[i]=1;
516 			found=1;
517 			break;
518 		}
519 		i++;
520 	}
521 
522 	if (found)
523 		return indicators+i;
524 	else {
525 		atomic_inc(&spare_indicator_usecount);
526 		return (__u32 * volatile) &spare_indicator;
527 	}
528 }
529 
530 /* locked by the locks in qdio_activate and qdio_cleanup */
qdio_put_indicator(__u32 * addr)531 static void qdio_put_indicator(__u32 *addr)
532 {
533 	int i;
534 
535 	if ( (addr) && (addr!=&spare_indicator) ) {
536 		i=addr-indicators;
537 		indicator_used[i]=0;
538 	}
539 	if (addr==&spare_indicator) {
540 		atomic_dec(&spare_indicator_usecount);
541 	}
542 }
543 
tiqdio_clear_summary_bit(__u32 * location)544 static inline volatile void tiqdio_clear_summary_bit(__u32 *location)
545 {
546 #ifdef QDIO_DBF_LIKE_HELL
547 	QDIO_DBF_TEXT5(0,trace,"clrsummb");
548 	QDIO_DBF_HEX5(0,trace,&location,sizeof(void*));
549 #endif /* QDIO_DBF_LIKE_HELL */
550 	xchg(location,0);
551 }
552 
tiqdio_set_summary_bit(__u32 * location)553 static inline volatile void tiqdio_set_summary_bit(__u32 *location)
554 {
555 #ifdef QDIO_DBF_LIKE_HELL
556 	QDIO_DBF_TEXT5(0,trace,"setsummb");
557 	QDIO_DBF_HEX5(0,trace,&location,sizeof(void*));
558 #endif /* QDIO_DBF_LIKE_HELL */
559 	xchg(location,-1);
560 }
561 
tiqdio_sched_tl(void)562 static inline void tiqdio_sched_tl(void)
563 {
564 	tasklet_hi_schedule(&tiqdio_tasklet);
565 }
566 
qdio_mark_tiq(qdio_q_t * q)567 static inline void qdio_mark_tiq(qdio_q_t *q)
568 {
569 	unsigned long flags;
570 #ifdef QDIO_DBF_LIKE_HELL
571 	QDIO_DBF_TEXT4(0,trace,"mark iq");
572 	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
573 #endif /* QDIO_DBF_LIKE_HELL */
574 
575 	spin_lock_irqsave(&ttiq_list_lock,flags);
576 	if (unlikely(atomic_read(&q->is_in_shutdown))) goto out_unlock;
577 
578 	if (q->is_input_q) {
579 		if ((q->list_prev) || (q->list_next)) goto out_unlock;
580 
581 		if (!tiq_list) {
582 			tiq_list=q;
583 			q->list_prev=q;
584 			q->list_next=q;
585 		} else {
586 			q->list_next=tiq_list;
587 			q->list_prev=tiq_list->list_prev;
588 			tiq_list->list_prev->list_next=q;
589 			tiq_list->list_prev=q;
590 		}
591 		spin_unlock_irqrestore(&ttiq_list_lock,flags);
592 
593 		tiqdio_set_summary_bit((__u32*)q->dev_st_chg_ind);
594 		tiqdio_sched_tl();
595 	}
596 	return;
597 out_unlock:
598 	spin_unlock_irqrestore(&ttiq_list_lock,flags);
599 	return;
600 }
601 
qdio_mark_q(qdio_q_t * q)602 static inline void qdio_mark_q(qdio_q_t *q)
603 {
604 #ifdef QDIO_DBF_LIKE_HELL
605 	QDIO_DBF_TEXT4(0,trace,"mark q");
606 	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
607 #endif /* QDIO_DBF_LIKE_HELL */
608 
609 	if (unlikely(atomic_read(&q->is_in_shutdown))) return;
610 
611 	tasklet_schedule(&q->tasklet);
612 }
613 
qdio_stop_polling(qdio_q_t * q)614 static inline int qdio_stop_polling(qdio_q_t *q)
615 {
616 #ifdef QDIO_USE_PROCESSING_STATE
617 	int gsf;
618 
619 	if (!atomic_swap(&q->polling,0)) return 1;
620 
621 #ifdef QDIO_DBF_LIKE_HELL
622 	QDIO_DBF_TEXT4(0,trace,"stoppoll");
623 	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
624 #endif /* QDIO_DBF_LIKE_HELL */
625 
626 	/* show the card that we are not polling anymore */
627 	if (q->is_input_q) {
628 		gsf=GET_SAVED_FRONTIER(q);
629 		set_slsb(&q->slsb.acc.val[(gsf+QDIO_MAX_BUFFERS_PER_Q-1)&
630 			 (QDIO_MAX_BUFFERS_PER_Q-1)],SLSB_P_INPUT_NOT_INIT);
631 		/* we don't issue this SYNC_MEMORY, as we trust Rick T and
632 		 * moreover will not use the PROCESSING state under VM,
633 		 * so q->polling was 0 anyway.
634 		SYNC_MEMORY;*/
635 		if (q->slsb.acc.val[gsf]==SLSB_P_INPUT_PRIMED) {
636 			/* set our summary bit again, as otherwise there is a
637 			 * small window we can miss between resetting it and
638 			 * checking for PRIMED state */
639 			if (q->is_thinint_q)
640 				tiqdio_set_summary_bit
641 					((__u32*)q->dev_st_chg_ind);
642 			return 0;
643 		}
644 	}
645 #endif /* QDIO_USE_PROCESSING_STATE */
646 	return 1;
647 }
648 
649 /* see the comment in do_QDIO and before qdio_reserve_q about the
650  * sophisticated locking outside of unmark_q, so that we don't need to
651  * disable the interrupts :-) */
qdio_unmark_q(qdio_q_t * q)652 static inline void qdio_unmark_q(qdio_q_t *q)
653 {
654 	unsigned long flags;
655 
656 #ifdef QDIO_DBF_LIKE_HELL
657 	QDIO_DBF_TEXT4(0,trace,"unmark q");
658 	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
659 #endif /* QDIO_DBF_LIKE_HELL */
660 
661 	if ((!q->list_prev)||(!q->list_next)) return;
662 
663 	if ((q->is_thinint_q)&&(q->is_input_q)) {
664 		/* iQDIO */
665 		spin_lock_irqsave(&ttiq_list_lock,flags);
666 		/* in case cleanup has done this already and simultanously
667 		 * qdio_unmark_q is called from the interrupt handler, we've
668 		 * got to check this in this specific case again */
669 		if ((!q->list_prev)||(!q->list_next))
670 			goto out;
671 		if (q->list_next==q) {
672 			/* q was the only interesting q */
673 			tiq_list=NULL;
674 			q->list_next=NULL;
675 			q->list_prev=NULL;
676 		} else {
677 			q->list_next->list_prev=q->list_prev;
678 			q->list_prev->list_next=q->list_next;
679 			tiq_list=q->list_next;
680 			q->list_next=NULL;
681 			q->list_prev=NULL;
682 		}
683 out:
684 		spin_unlock_irqrestore(&ttiq_list_lock,flags);
685 	}
686 }
687 
tiqdio_clear_global_summary(void)688 static inline volatile unsigned long tiqdio_clear_global_summary(void)
689 {
690 	unsigned long time;
691 
692 #ifdef QDIO_DBF_LIKE_HELL
693 	QDIO_DBF_TEXT5(0,trace,"clrglobl");
694 #endif /* QDIO_DBF_LIKE_HELL */
695 
696 #ifdef QDIO_32_BIT
697 	asm volatile (
698 		"lhi	1,3	\n\t"
699 		".insn	rre,0xb2650000,2,0	\n\t"
700 		"lr	%0,3	\n\t"
701 		: "=d" (time) : : "cc", "1", "2", "3"
702 		);
703 #else /* QDIO_32_BIT */
704 	asm volatile (
705 		"lghi	1,3	\n\t"
706 		".insn	rre,0xb2650000,2,0	\n\t"
707 		"lgr	%0,3	\n\t"
708 		: "=d" (time) : : "cc", "1", "2", "3"
709 		);
710 #endif /* QDIO_32_BIT */
711 
712 #ifdef QDIO_DBF_LIKE_HELL
713 	QDIO_DBF_HEX5(0,trace,&time,sizeof(unsigned long));
714 #endif /* QDIO_DBF_LIKE_HELL */
715 	return time;
716 }
717 
718 /************************* OUTBOUND ROUTINES *******************************/
719 
qdio_translate_buffer_back(qdio_q_t * q,int bufno)720 static inline void qdio_translate_buffer_back(qdio_q_t *q,int bufno)
721 {
722 	if (unlikely(!q->is_0copy_sbals_q))
723 		memcpy(q->qdio_buffers[bufno],
724 		       (void*)q->sbal[bufno],SBAL_SIZE);
725 }
726 
qdio_get_outbound_buffer_frontier(qdio_q_t * q)727 static inline int qdio_get_outbound_buffer_frontier(qdio_q_t *q)
728 {
729 	int f,f_mod_no;
730 	volatile char *slsb;
731 	int first_not_to_check;
732 	char dbf_text[15];
733 	char slsbyte;
734 
735 #ifdef QDIO_DBF_LIKE_HELL
736 	QDIO_DBF_TEXT4(0,trace,"getobfro");
737 	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
738 #endif /* QDIO_DBF_LIKE_HELL */
739 
740 	slsb=&q->slsb.acc.val[0];
741 	f_mod_no=f=q->first_to_check;
742 	/* f point to already processed elements, so f+no_used is correct...
743 	 * ... but: we don't check 128 buffers, as otherwise
744 	 * qdio_has_outbound_q_moved would return 0 */
745 	first_not_to_check=f+qdio_min(atomic_read(&q->number_of_buffers_used),
746 				      (QDIO_MAX_BUFFERS_PER_Q-1));
747 
748 	if ((!q->is_iqdio_q)&&(!q->hydra_gives_outbound_pcis)) {
749 		SYNC_MEMORY;
750 	}
751 
752 check_next:
753 	if (f==first_not_to_check) goto out;
754 	slsbyte=slsb[f_mod_no];
755 
756 	/* the card has not fetched the output yet */
757 	if (slsbyte==SLSB_CU_OUTPUT_PRIMED) {
758 #ifdef QDIO_DBF_LIKE_HELL
759 		QDIO_DBF_TEXT5(0,trace,"outpprim");
760 #endif /* QDIO_DBF_LIKE_HELL */
761 		goto out;
762 	}
763 
764 	/* the card got it */
765 	if (slsbyte==SLSB_P_OUTPUT_EMPTY) {
766 		atomic_dec(&q->number_of_buffers_used);
767 		f++;
768 		f_mod_no=f&(QDIO_MAX_BUFFERS_PER_Q-1);
769 #ifdef QDIO_DBF_LIKE_HELL
770 		QDIO_DBF_TEXT5(0,trace,"outpempt");
771 #endif /* QDIO_DBF_LIKE_HELL */
772 		goto check_next;
773 	}
774 
775 	if (slsbyte==SLSB_P_OUTPUT_ERROR) {
776 		QDIO_DBF_TEXT3(0,trace,"outperr");
777 		sprintf(dbf_text,"%x-%x-%x",f_mod_no,
778 			q->sbal[f_mod_no]->element[14].sbalf.value,
779 			q->sbal[f_mod_no]->element[15].sbalf.value);
780 		QDIO_DBF_TEXT3(1,trace,dbf_text);
781 		QDIO_DBF_HEX2(1,sbal,q->sbal[f_mod_no],256);
782 
783 		/* kind of process the buffer */
784 		set_slsb(&q->slsb.acc.val[f_mod_no],
785 			 SLSB_P_OUTPUT_NOT_INIT);
786 
787 		qdio_translate_buffer_back(q,f_mod_no);
788 
789 		/* we increment the frontier, as this buffer
790 		 * was processed obviously */
791 		atomic_dec(&q->number_of_buffers_used);
792 		f_mod_no=(f_mod_no+1)&(QDIO_MAX_BUFFERS_PER_Q-1);
793 
794 		if (q->qdio_error)
795 			q->error_status_flags|=
796 				QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR;
797 		q->qdio_error=SLSB_P_OUTPUT_ERROR;
798 		q->error_status_flags|=QDIO_STATUS_LOOK_FOR_ERROR;
799 
800 		goto out;
801 	}
802 
803 	/* no new buffers */
804 #ifdef QDIO_DBF_LIKE_HELL
805 	QDIO_DBF_TEXT5(0,trace,"outpni");
806 #endif /* QDIO_DBF_LIKE_HELL */
807 	goto out;
808 
809 out:
810 	return (q->first_to_check=f_mod_no);
811 }
812 
813 /* all buffers are processed */
qdio_is_outbound_q_done(qdio_q_t * q)814 static inline int qdio_is_outbound_q_done(qdio_q_t *q)
815 {
816 	int no_used;
817 #ifdef QDIO_DBF_LIKE_HELL
818 	char dbf_text[15];
819 #endif /* QDIO_DBF_LIKE_HELL */
820 
821 	no_used=atomic_read(&q->number_of_buffers_used);
822 
823 #ifdef QDIO_DBF_LIKE_HELL
824 	if (no_used) {
825 		sprintf(dbf_text,"oqisnt%02x",no_used);
826 		QDIO_DBF_TEXT4(0,trace,dbf_text);
827 	} else {
828 		QDIO_DBF_TEXT4(0,trace,"oqisdone");
829 	}
830 	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
831 #endif /* QDIO_DBF_LIKE_HELL */
832 	return (no_used==0);
833 }
834 
qdio_has_outbound_q_moved(qdio_q_t * q)835 static inline int qdio_has_outbound_q_moved(qdio_q_t *q)
836 {
837 	int i;
838 
839 	i=qdio_get_outbound_buffer_frontier(q);
840 
841 	if ( (i!=GET_SAVED_FRONTIER(q)) ||
842 	     (q->error_status_flags&QDIO_STATUS_LOOK_FOR_ERROR) ) {
843 		SAVE_FRONTIER(q,i);
844 #ifdef QDIO_DBF_LIKE_HELL
845 		QDIO_DBF_TEXT4(0,trace,"oqhasmvd");
846 		QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
847 #endif /* QDIO_DBF_LIKE_HELL */
848 		return 1;
849 	} else {
850 #ifdef QDIO_DBF_LIKE_HELL
851 		QDIO_DBF_TEXT4(0,trace,"oqhsntmv");
852 		QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
853 #endif /* QDIO_DBF_LIKE_HELL */
854 		return 0;
855 	}
856 }
857 
qdio_kick_outbound_q(qdio_q_t * q)858 static inline void qdio_kick_outbound_q(qdio_q_t *q)
859 {
860 	int result;
861 	char dbf_text[15];
862 #ifdef QDIO_DBF_LIKE_HELL
863 	QDIO_DBF_TEXT4(0,trace,"kickoutq");
864 	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
865 #endif /* QDIO_DBF_LIKE_HELL */
866 
867 	if (!q->siga_out) return;
868 
869 	/* here's the story with cc=2 and busy bit set (thanks, Rick):
870 	 * VM's CP could present us cc=2 and busy bit set on SIGA-write
871 	 * during reconfiguration of their Guest LAN (only in HIPERS mode,
872 	 * QDIO mode is asynchronous -- cc=2 and busy bit there will take
873 	 * the queues down immediately; and not being under VM we have a
874 	 * problem on cc=2 and busy bit set right away).
875 	 *
876 	 * Therefore qdio_siga_output will try for a short time constantly,
877 	 * if such a condition occurs. If it doesn't change, it will
878 	 * increase the busy_siga_counter and save the timestamp, and
879 	 * schedule the queue for later processing (via mark_q, using the
880 	 * queue tasklet). __qdio_outbound_processing will check out the
881 	 * counter. If non-zero, it will call qdio_kick_outbound_q as often
882 	 * as the value of the counter. This will attempt further SIGA
883 	 * instructions.
884 	 * Every successful SIGA instruction will decrease the counter.
885 	 * After some time of no movement, qdio_kick_outbound_q will
886 	 * finally fail and reflect corresponding error codes to call
887 	 * the upper layer module and have it take the queues down.
888 	 *
889 	 * Note that this is a change from the original HiperSockets design
890 	 * (saying cc=2 and busy bit means take the queues down), but in
891 	 * these days Guest LAN didn't exist... excessive cc=2 with busy bit
892 	 * conditions will still take the queues down, but the threshold is
893 	 * higher due to the Guest LAN environment.
894 	 */
895 
896 	result=qdio_siga_output(q);
897 
898 		switch (result) {
899 		case 0:
900 		/* went smooth this time, reset timestamp */
901 			QDIO_DBF_TEXT3(0,trace,"cc2reslv");
902 			sprintf(dbf_text,"%4x%2x%2x",q->irq,q->q_no,
903 				atomic_read(&q->busy_siga_counter));
904 			QDIO_DBF_TEXT3(0,trace,dbf_text);
905 			q->timing.busy_start=0;
906 			break;
907 		case (2|QDIO_SIGA_ERROR_B_BIT_SET):
908 			/* cc=2 and busy bit: */
909 		atomic_inc(&q->busy_siga_counter);
910 
911 			/* if the last siga was successful, save
912 			 * timestamp here */
913 			if (!q->timing.busy_start)
914 				q->timing.busy_start=NOW;
915 
916 			/* if we're in time, don't touch error_status_flags
917 			 * and siga_error */
918 			if (NOW-q->timing.busy_start<QDIO_BUSY_BIT_GIVE_UP) {
919 				qdio_mark_q(q);
920 				break;
921 			}
922 			QDIO_DBF_TEXT2(0,trace,"cc2REPRT");
923 			sprintf(dbf_text,"%4x%2x%2x",q->irq,q->q_no,
924 				atomic_read(&q->busy_siga_counter));
925 			QDIO_DBF_TEXT3(0,trace,dbf_text);
926 			/* else fallthrough and report error */
927 		default:
928 			/* for plain cc=1, 2 or 3: */
929 		if (q->siga_error)
930 			q->error_status_flags|=
931 				QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR;
932 		q->error_status_flags|=
933 			QDIO_STATUS_LOOK_FOR_ERROR;
934 		q->siga_error=result;
935 	}
936 }
937 
qdio_kick_outbound_handler(qdio_q_t * q)938 static inline void qdio_kick_outbound_handler(qdio_q_t *q)
939 {
940 #ifdef QDIO_DBF_LIKE_HELL
941 	char dbf_text[15];
942 #endif /* QDIO_DBF_LIKE_HELL */
943 
944 	int start=q->first_element_to_kick;
945 	/* last_move_ftc was just updated */
946 	int real_end=GET_SAVED_FRONTIER(q);
947 	int end=(real_end+QDIO_MAX_BUFFERS_PER_Q-1)&
948 		(QDIO_MAX_BUFFERS_PER_Q-1);
949 	int count=(end+QDIO_MAX_BUFFERS_PER_Q+1-start)&
950 		(QDIO_MAX_BUFFERS_PER_Q-1);
951 
952 #ifdef QDIO_DBF_LIKE_HELL
953 	QDIO_DBF_TEXT4(0,trace,"kickouth");
954 	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
955 #endif /* QDIO_DBF_LIKE_HELL */
956 
957 #ifdef QDIO_DBF_LIKE_HELL
958 	sprintf(dbf_text,"s=%2xc=%2x",start,count);
959 	QDIO_DBF_TEXT4(0,trace,dbf_text);
960 #endif /* QDIO_DBF_LIKE_HELL */
961 
962 	if (q->state==QDIO_IRQ_STATE_ACTIVE)
963 		q->handler(q->irq,QDIO_STATUS_OUTBOUND_INT|
964 			   q->error_status_flags,
965 			   q->qdio_error,q->siga_error,q->q_no,start,count,
966 			   q->int_parm);
967 
968 	/* for the next time: */
969 	q->first_element_to_kick=real_end;
970 	q->qdio_error=0;
971 	q->siga_error=0;
972 	q->error_status_flags=0;
973 }
974 
__qdio_outbound_processing(qdio_q_t * q)975 static inline void __qdio_outbound_processing(qdio_q_t *q)
976 {
977 	int siga_attempts;
978 #ifdef QDIO_DBF_LIKE_HELL
979 	QDIO_DBF_TEXT4(0,trace,"qoutproc");
980 	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
981 #endif /* QDIO_DBF_LIKE_HELL */
982 
983 	if (unlikely(qdio_reserve_q(q))) {
984 		qdio_release_q(q);
985 #ifdef QDIO_PERFORMANCE_STATS
986 		o_p_c++;
987 #endif /* QDIO_PERFORMANCE_STATS */
988 		/* as we're sissies, we'll check next time */
989 		if (likely(!atomic_read(&q->is_in_shutdown))) {
990 			qdio_mark_q(q);
991 #ifdef QDIO_DBF_LIKE_HELL
992 			QDIO_DBF_TEXT4(0,trace,"busy,agn");
993 #endif /* QDIO_DBF_LIKE_HELL */
994 		}
995 		return;
996 	}
997 #ifdef QDIO_PERFORMANCE_STATS
998 	o_p_nc++;
999 #endif /* QDIO_PERFORMANCE_STATS */
1000 
1001 	/* see comment in qdio_kick_outbound_q */
1002 	siga_attempts=atomic_read(&q->busy_siga_counter);
1003 	while (siga_attempts) {
1004 		atomic_dec(&q->busy_siga_counter);
1005 		qdio_kick_outbound_q(q);
1006 		siga_attempts--;
1007 	}
1008 
1009 #ifdef QDIO_PERFORMANCE_STATS
1010 	perf_stats.tl_runs++;
1011 #endif /* QDIO_PERFORMANCE_STATS */
1012 
1013 	if (qdio_has_outbound_q_moved(q)) {
1014 		qdio_kick_outbound_handler(q);
1015 	}
1016 
1017 	if (q->is_iqdio_q) {
1018 		/* for asynchronous queues, we better check, if the fill
1019 		 * level is too high. for synchronous queues, the fill
1020 		 * level will never be that high. */
1021 		if (atomic_read(&q->number_of_buffers_used)>
1022 		    IQDIO_FILL_LEVEL_TO_POLL) {
1023 			qdio_mark_q(q);
1024 		}
1025 	} else if (!q->hydra_gives_outbound_pcis) {
1026 		if (!qdio_is_outbound_q_done(q)) {
1027 			qdio_mark_q(q);
1028 		}
1029 	}
1030 
1031 	qdio_release_q(q);
1032 }
1033 
qdio_outbound_processing(qdio_q_t * q)1034 static void qdio_outbound_processing(qdio_q_t *q)
1035 {
1036 	__qdio_outbound_processing(q);
1037 }
1038 
1039 /************************* INBOUND ROUTINES *******************************/
1040 
1041 
qdio_get_inbound_buffer_frontier(qdio_q_t * q)1042 static inline int qdio_get_inbound_buffer_frontier(qdio_q_t *q)
1043 {
1044 	int f,f_mod_no;
1045 	volatile char *slsb;
1046 	char slsbyte;
1047 	int first_not_to_check;
1048 	char dbf_text[15];
1049 #ifdef QDIO_USE_PROCESSING_STATE
1050 	int last_position=-1;
1051 #endif /* QDIO_USE_PROCESSING_STATE */
1052 
1053 #ifdef QDIO_DBF_LIKE_HELL
1054 	QDIO_DBF_TEXT4(0,trace,"getibfro");
1055 	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
1056 #endif /* QDIO_DBF_LIKE_HELL */
1057 
1058 	slsb=&q->slsb.acc.val[0];
1059 	f_mod_no=f=q->first_to_check;
1060 	/* we don't check 128 buffers, as otherwise qdio_has_inbound_q_moved
1061 	 * would return 0 */
1062 	first_not_to_check=f+qdio_min(atomic_read(&q->number_of_buffers_used),
1063 				      (QDIO_MAX_BUFFERS_PER_Q-1));
1064 
1065 	/* we don't use this one, as a PCI or we after a thin interrupt
1066 	 * will sync the queues
1067 	SYNC_MEMORY;*/
1068 
1069 check_next:
1070 	f_mod_no=f&(QDIO_MAX_BUFFERS_PER_Q-1);
1071 	if (f==first_not_to_check) goto out;
1072 	slsbyte=slsb[f_mod_no];
1073 
1074 	/* CU_EMPTY means frontier is reached */
1075 	if (slsbyte==SLSB_CU_INPUT_EMPTY) {
1076 #ifdef QDIO_DBF_LIKE_HELL
1077 		QDIO_DBF_TEXT5(0,trace,"inptempt");
1078 #endif /* QDIO_DBF_LIKE_HELL */
1079 		goto out;
1080 	}
1081 
1082 	/* P_PRIMED means set slsb to P_PROCESSING and move on */
1083 	if (slsbyte==SLSB_P_INPUT_PRIMED) {
1084 #ifdef QDIO_DBF_LIKE_HELL
1085 		QDIO_DBF_TEXT5(0,trace,"inptprim");
1086 #endif /* QDIO_DBF_LIKE_HELL */
1087 
1088 #ifdef QDIO_USE_PROCESSING_STATE
1089 		/* as soon as running under VM, polling the input queues will
1090 		 * kill VM in terms of CP overhead */
1091 		if (q->siga_sync) {
1092 			set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_NOT_INIT);
1093 		} else {
1094 			/* set the previous buffer to NOT_INIT. The current
1095 			 * buffer will be set to PROCESSING at the end of
1096 			 * this function to avoid further interrupts. */
1097 			if (last_position>=0)
1098 				set_slsb(&slsb[last_position],
1099 					SLSB_P_INPUT_NOT_INIT);
1100 			atomic_set(&q->polling,1);
1101 			last_position=f_mod_no;
1102 		}
1103 #else /* QDIO_USE_PROCESSING_STATE */
1104 		set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_NOT_INIT);
1105 #endif /* QDIO_USE_PROCESSING_STATE */
1106 		/* not needed, as the inbound queue will be synced on the next
1107 		 * siga-r
1108 		SYNC_MEMORY;*/
1109 		f++;
1110 		atomic_dec(&q->number_of_buffers_used);
1111 		goto check_next;
1112 	}
1113 
1114 	if ( (slsbyte==SLSB_P_INPUT_NOT_INIT) ||
1115 	     (slsbyte==SLSB_P_INPUT_PROCESSING) ) {
1116 #ifdef QDIO_DBF_LIKE_HELL
1117 		QDIO_DBF_TEXT5(0,trace,"inpnipro");
1118 #endif /* QDIO_DBF_LIKE_HELL */
1119 		goto out;
1120 	}
1121 
1122 	/* P_ERROR means frontier is reached, break and report error */
1123 	if (slsbyte==SLSB_P_INPUT_ERROR) {
1124 		sprintf(dbf_text,"inperr%2x",f_mod_no);
1125 		QDIO_DBF_TEXT3(1,trace,dbf_text);
1126 		QDIO_DBF_HEX2(1,sbal,q->sbal[f_mod_no],256);
1127 
1128 		/* kind of process the buffer */
1129 		set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_NOT_INIT);
1130 
1131 		if (q->qdio_error)
1132 			q->error_status_flags|=
1133 				QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR;
1134 		q->qdio_error=SLSB_P_INPUT_ERROR;
1135 		q->error_status_flags|=QDIO_STATUS_LOOK_FOR_ERROR;
1136 
1137 		/* we increment the frontier, as this buffer
1138 		 * was processed obviously */
1139 		f_mod_no=(f_mod_no+1)&(QDIO_MAX_BUFFERS_PER_Q-1);
1140 		atomic_dec(&q->number_of_buffers_used);
1141 
1142 #ifdef QDIO_USE_PROCESSING_STATE
1143 		last_position=-1;
1144 #endif /* QDIO_USE_PROCESSING_STATE */
1145 
1146 		goto out;
1147 	}
1148 
1149 	/* everything else means frontier not changed (HALTED or so) */
1150 out:
1151 	q->first_to_check=f_mod_no;
1152 
1153 #ifdef QDIO_USE_PROCESSING_STATE
1154 	if (last_position>=0)
1155 		set_slsb(&slsb[last_position],SLSB_P_INPUT_PROCESSING);
1156 #endif /* QDIO_USE_PROCESSING_STATE */
1157 
1158 #ifdef QDIO_DBF_LIKE_HELL
1159 	QDIO_DBF_HEX4(0,trace,&q->first_to_check,sizeof(int));
1160 #endif /* QDIO_DBF_LIKE_HELL */
1161 
1162 	return q->first_to_check;
1163 }
1164 
qdio_has_inbound_q_moved(qdio_q_t * q)1165 static inline int qdio_has_inbound_q_moved(qdio_q_t *q)
1166 {
1167 	int i;
1168 
1169 #ifdef QDIO_PERFORMANCE_STATS
1170 	static int old_pcis=0;
1171 	static int old_thinints=0;
1172 
1173 	if ((old_pcis==perf_stats.pcis)&&(old_thinints==perf_stats.thinints))
1174 		perf_stats.start_time_inbound=NOW;
1175 	else
1176 		old_pcis=perf_stats.pcis;
1177 #endif /* QDIO_PERFORMANCE_STATS */
1178 
1179 	i=qdio_get_inbound_buffer_frontier(q);
1180 	if ( (i!=GET_SAVED_FRONTIER(q)) ||
1181 	     (q->error_status_flags&QDIO_STATUS_LOOK_FOR_ERROR) ) {
1182 		SAVE_FRONTIER(q,i);
1183 		if ((!q->siga_sync)&&(!q->hydra_gives_outbound_pcis)) {
1184 			SAVE_TIMESTAMP(q);
1185 		}
1186 
1187 #ifdef QDIO_DBF_LIKE_HELL
1188 		QDIO_DBF_TEXT4(0,trace,"inhasmvd");
1189 		QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
1190 #endif /* QDIO_DBF_LIKE_HELL */
1191 		return 1;
1192 	} else {
1193 #ifdef QDIO_DBF_LIKE_HELL
1194 		QDIO_DBF_TEXT4(0,trace,"inhsntmv");
1195 		QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
1196 #endif /* QDIO_DBF_LIKE_HELL */
1197 		return 0;
1198 	}
1199 }
1200 
1201 /* means, no more buffers to be filled */
iqdio_is_inbound_q_done(qdio_q_t * q)1202 static inline int iqdio_is_inbound_q_done(qdio_q_t *q)
1203 {
1204 	int no_used;
1205 #ifdef QDIO_DBF_LIKE_HELL
1206 	char dbf_text[15];
1207 #endif /* QDIO_DBF_LIKE_HELL */
1208 
1209 	no_used=atomic_read(&q->number_of_buffers_used);
1210 
1211 	/* propagate the change from 82 to 80 through VM */
1212 	SYNC_MEMORY;
1213 
1214 #ifdef QDIO_DBF_LIKE_HELL
1215 	if (no_used) {
1216 		sprintf(dbf_text,"iqisnt%02x",no_used);
1217 		QDIO_DBF_TEXT4(0,trace,dbf_text);
1218 	} else {
1219 		QDIO_DBF_TEXT4(0,trace,"iniqisdo");
1220 	}
1221 	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
1222 #endif /* QDIO_DBF_LIKE_HELL */
1223 
1224 	if (!no_used) {
1225 		return 1;
1226 	}
1227 
1228 	if (q->siga_sync) {
1229 		if (q->slsb.acc.val[q->first_to_check]==SLSB_P_INPUT_PRIMED) {
1230 			/* ok, the next input buffer is primed. that means,
1231 			 * that device state change indicator and adapter
1232 			 * local summary are set, so we will find it next
1233 			 * time.
1234 			 * we will return 0 below, as there is nothing to
1235 			 * do, except of scheduling ourselves for the next
1236 			 * time. */
1237 			tiqdio_set_summary_bit((__u32*)q->dev_st_chg_ind);
1238 			tiqdio_sched_tl();
1239 		} else {
1240 			/* nothing more to do, if next buffer is not PRIMED.
1241 			 * note that we did a SYNC_MEMORY before, that there
1242 			 * has been a sychnronization.
1243 			 * we will return 0 below, as there is nothing to do
1244 			 * (stop_polling not necessary, as we have not been
1245 			 * using the PROCESSING state */
1246 		}
1247 	} else {
1248 		/* we'll check for more primed buffers
1249 		 * in qeth_stop_polling */
1250 	}
1251 
1252 	return 0;
1253 }
1254 
qdio_is_inbound_q_done(qdio_q_t * q)1255 static inline int qdio_is_inbound_q_done(qdio_q_t *q)
1256 {
1257 	int no_used;
1258 #ifdef QDIO_DBF_LIKE_HELL
1259 	char dbf_text[15];
1260 #endif /* QDIO_DBF_LIKE_HELL */
1261 
1262 	no_used=atomic_read(&q->number_of_buffers_used);
1263 
1264 	/* we need that one for synchronization with the OSA/FCP card, as it
1265 	 * does a kind of PCI avoidance */
1266 	SYNC_MEMORY;
1267 
1268 	if (!no_used) {
1269 #ifdef QDIO_DBF_LIKE_HELL
1270 		QDIO_DBF_TEXT4(0,trace,"inqisdnA");
1271 		QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
1272 		QDIO_DBF_TEXT4(0,trace,dbf_text);
1273 #endif /* QDIO_DBF_LIKE_HELL */
1274 		return 1;
1275 	}
1276 
1277 	if (q->slsb.acc.val[q->first_to_check]==SLSB_P_INPUT_PRIMED) {
1278 		/* we got something to do */
1279 #ifdef QDIO_DBF_LIKE_HELL
1280 		QDIO_DBF_TEXT4(0,trace,"inqisntA");
1281 		QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
1282 #endif /* QDIO_DBF_LIKE_HELL */
1283 		return 0;
1284 	}
1285 
1286 	/* on VM, we don't poll, so the q is always done here */
1287 	if (q->siga_sync) return 1;
1288 	if (q->hydra_gives_outbound_pcis) return 1;
1289 
1290 	/* at this point we know, that inbound first_to_check
1291 	   has (probably) not moved (see qdio_inbound_processing) */
1292 	if (NOW>GET_SAVED_TIMESTAMP(q)+q->timing.threshold) {
1293 #ifdef QDIO_DBF_LIKE_HELL
1294 		QDIO_DBF_TEXT4(0,trace,"inqisdon");
1295 		QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
1296 		sprintf(dbf_text,"pf%02xcn%02x",q->first_to_check,no_used);
1297 		QDIO_DBF_TEXT4(0,trace,dbf_text);
1298 #endif /* QDIO_DBF_LIKE_HELL */
1299 		return 1;
1300 	} else {
1301 #ifdef QDIO_DBF_LIKE_HELL
1302 		QDIO_DBF_TEXT4(0,trace,"inqisntd");
1303 		QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
1304 		sprintf(dbf_text,"pf%02xcn%02x",q->first_to_check,no_used);
1305 		QDIO_DBF_TEXT4(0,trace,dbf_text);
1306 #endif /* QDIO_DBF_LIKE_HELL */
1307 		return 0;
1308 	}
1309 }
1310 
qdio_kick_inbound_handler(qdio_q_t * q)1311 static inline void qdio_kick_inbound_handler(qdio_q_t *q)
1312 {
1313 	int count=0;
1314 	int start,end,real_end,i;
1315 #ifdef QDIO_DBF_LIKE_HELL
1316 	char dbf_text[15];
1317 
1318 	QDIO_DBF_TEXT4(0,trace,"kickinh");
1319 	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
1320 #endif /* QDIO_DBF_LIKE_HELL */
1321 
1322 	start=q->first_element_to_kick;
1323 	real_end=q->first_to_check;
1324 	end=(real_end+QDIO_MAX_BUFFERS_PER_Q-1)&(QDIO_MAX_BUFFERS_PER_Q-1);
1325 
1326 	i=start;
1327 	while (1) {
1328 		count++;
1329 		qdio_translate_buffer_back(q,i);
1330 		if (i==end) break;
1331 		i=(i+1)&(QDIO_MAX_BUFFERS_PER_Q-1);
1332 	}
1333 
1334 #ifdef QDIO_DBF_LIKE_HELL
1335 	sprintf(dbf_text,"s=%2xc=%2x",start,count);
1336 	QDIO_DBF_TEXT4(0,trace,dbf_text);
1337 #endif /* QDIO_DBF_LIKE_HELL */
1338 
1339 	if (likely(q->state==QDIO_IRQ_STATE_ACTIVE))
1340 		q->handler(q->irq,
1341 			   QDIO_STATUS_INBOUND_INT|q->error_status_flags,
1342 			   q->qdio_error,q->siga_error,q->q_no,start,count,
1343 			   q->int_parm);
1344 
1345 	/* for the next time: */
1346 	q->first_element_to_kick=real_end;
1347 	q->qdio_error=0;
1348 	q->siga_error=0;
1349 	q->error_status_flags=0;
1350 
1351 #ifdef QDIO_PERFORMANCE_STATS
1352 	perf_stats.inbound_time+=NOW-perf_stats.start_time_inbound;
1353 	perf_stats.inbound_cnt++;
1354 #endif /* QDIO_PERFORMANCE_STATS */
1355 }
1356 
__tiqdio_inbound_processing(qdio_q_t * q,int spare_ind_was_set)1357 static inline void __tiqdio_inbound_processing(qdio_q_t *q,
1358 					       int spare_ind_was_set)
1359 {
1360 	qdio_irq_t *irq_ptr;
1361 	qdio_q_t *oq;
1362 	int i;
1363 
1364 #ifdef QDIO_DBF_LIKE_HELL
1365 	QDIO_DBF_TEXT4(0,trace,"iqinproc");
1366 	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
1367 #endif /* QDIO_DBF_LIKE_HELL */
1368 
1369 	/* we first want to reserve the q, so that we know, that we don't
1370 	 * interrupt ourselves and call qdio_unmark_q, as is_in_shutdown might
1371 	 * be set */
1372 	if (unlikely(qdio_reserve_q(q))) {
1373 		qdio_release_q(q);
1374 #ifdef QDIO_PERFORMANCE_STATS
1375 		ii_p_c++;
1376 #endif /* QDIO_PERFORMANCE_STATS */
1377 		/* as we might just be about to stop polling, we make
1378 		 * sure that we check again at least once more */
1379 		tiqdio_sched_tl();
1380 		return;
1381 	}
1382 #ifdef QDIO_PERFORMANCE_STATS
1383 	ii_p_nc++;
1384 #endif /* QDIO_PERFORMANCE_STATS */
1385 	if (unlikely(atomic_read(&q->is_in_shutdown))) {
1386 		qdio_unmark_q(q);
1387 		goto out;
1388 	}
1389 
1390 	/* we reset spare_ind_was_set, when the queue does not use the
1391 	 * spare indicator */
1392 	if (spare_ind_was_set) {
1393 		spare_ind_was_set==(q->dev_st_chg_ind==&spare_indicator);
1394 	}
1395 
1396 	if ( (*(q->dev_st_chg_ind)) || (spare_ind_was_set) ) {
1397 		/* q->dev_st_chg_ind is the indicator, be it shared or not.
1398 		 * only clear it, if indicator is non-shared */
1399 		if (!spare_ind_was_set) {
1400 			tiqdio_clear_summary_bit((__u32*)q->dev_st_chg_ind);
1401 		}
1402 
1403 		if (q->hydra_gives_outbound_pcis) {
1404 			if (!q->siga_sync_done_on_thinints) {
1405 				SYNC_MEMORY_ALL;
1406 			} else if ((!q->siga_sync_done_on_outb_tis)&&
1407 				   (q->hydra_gives_outbound_pcis)) {
1408 				SYNC_MEMORY_ALL_OUTB;
1409 			}
1410 		} else {
1411 			SYNC_MEMORY;
1412 		}
1413 
1414 		/* maybe we have to do work on our outbound queues... at least
1415 		 * we have to check for outbound-int-capable thinint-capable
1416 		 * queues */
1417 		if (q->hydra_gives_outbound_pcis) {
1418 			irq_ptr=(qdio_irq_t*)q->irq_ptr;
1419  			for (i=0;i<irq_ptr->no_output_qs;i++) {
1420  				oq=irq_ptr->output_qs[i];
1421 #ifdef QDIO_PERFORMANCE_STATS
1422 				perf_stats.tl_runs--;
1423 #endif /* QDIO_PERFORMANCE_STATS */
1424 				if (!qdio_is_outbound_q_done(oq)) {
1425 					__qdio_outbound_processing(oq);
1426 				}
1427 			}
1428 		}
1429 
1430 		if (qdio_has_inbound_q_moved(q)) {
1431 			qdio_kick_inbound_handler(q);
1432 			if (iqdio_is_inbound_q_done(q)) {
1433 				if (!qdio_stop_polling(q)) {
1434 					/* we set the flags to get into
1435 					 * the stuff next time, see also
1436 					 * comment in qdio_stop_polling */
1437 					tiqdio_set_summary_bit
1438 						((__u32*)q->dev_st_chg_ind);
1439 					tiqdio_sched_tl();
1440 				}
1441 			}
1442 		}
1443 	}
1444 out:
1445 	qdio_release_q(q);
1446 }
1447 
tiqdio_inbound_processing(qdio_q_t * q)1448 static void tiqdio_inbound_processing(qdio_q_t *q)
1449 {
1450 	__tiqdio_inbound_processing(q,atomic_read(&spare_indicator_usecount));
1451 }
1452 
__qdio_inbound_processing(qdio_q_t * q)1453 static inline void __qdio_inbound_processing(qdio_q_t *q)
1454 {
1455 	int q_laps=0;
1456 
1457 #ifdef QDIO_DBF_LIKE_HELL
1458 	QDIO_DBF_TEXT4(0,trace,"qinproc");
1459 	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
1460 #endif /* QDIO_DBF_LIKE_HELL */
1461 
1462 	if (unlikely(qdio_reserve_q(q))) {
1463 		qdio_release_q(q);
1464 #ifdef QDIO_PERFORMANCE_STATS
1465 		i_p_c++;
1466 #endif /* QDIO_PERFORMANCE_STATS */
1467 		/* as we're sissies, we'll check next time */
1468 		if (likely(!atomic_read(&q->is_in_shutdown))) {
1469 			qdio_mark_q(q);
1470 #ifdef QDIO_DBF_LIKE_HELL
1471 			QDIO_DBF_TEXT4(0,trace,"busy,agn");
1472 #endif /* QDIO_DBF_LIKE_HELL */
1473 		}
1474 		return;
1475 	}
1476 #ifdef QDIO_PERFORMANCE_STATS
1477 	i_p_nc++;
1478 	perf_stats.tl_runs++;
1479 #endif /* QDIO_PERFORMANCE_STATS */
1480 
1481 again:
1482 	if (qdio_has_inbound_q_moved(q)) {
1483 		qdio_kick_inbound_handler(q);
1484 		if (!qdio_stop_polling(q)) {
1485 			q_laps++;
1486 			if (q_laps<QDIO_Q_LAPS) goto again;
1487 		}
1488 		qdio_mark_q(q);
1489 	} else {
1490 		if (!qdio_is_inbound_q_done(q)) /* means poll time is
1491 						   not yet over */
1492 			qdio_mark_q(q);
1493 	}
1494 
1495 	qdio_release_q(q);
1496 }
1497 
qdio_inbound_processing(qdio_q_t * q)1498 static void qdio_inbound_processing(qdio_q_t *q)
1499 {
1500 	__qdio_inbound_processing(q);
1501 }
1502 
1503 /************************* MAIN ROUTINES *******************************/
1504 
tiqdio_inbound_checks(void)1505 static inline void tiqdio_inbound_checks(void)
1506 {
1507 	qdio_q_t *q;
1508 	int spare_ind_was_set=0;
1509 #ifdef QDIO_USE_PROCESSING_STATE
1510 	int q_laps=0;
1511 #endif /* QDIO_USE_PROCESSING_STATE */
1512 
1513 #ifdef QDIO_DBF_LIKE_HELL
1514 	char dbf_text[15];
1515 
1516 	QDIO_DBF_TEXT4(0,trace,"iqdinbck");
1517 #endif /* QDIO_DBF_LIKE_HELL */
1518 
1519 #ifdef QDIO_DBF_LIKE_HELL
1520 	QDIO_DBF_TEXT5(0,trace,"iqlocsum");
1521 #endif /* QDIO_DBF_LIKE_HELL */
1522 
1523 #ifdef QDIO_USE_PROCESSING_STATE
1524 again:
1525 #endif /* QDIO_USE_PROCESSING_STATE */
1526 
1527 	/* when the spare indicator is used and set, save that and clear it */
1528 	if ( (atomic_read(&spare_indicator_usecount)) && (spare_indicator) ) {
1529 		spare_ind_was_set=1;
1530 		tiqdio_clear_summary_bit((__u32*)&spare_indicator);
1531 	}
1532 
1533 	q=(qdio_q_t*)tiq_list;
1534 	/* switch all active queues to processing state */
1535 	do {
1536 		if (!q) break;
1537 		__tiqdio_inbound_processing(q,spare_ind_was_set);
1538 		q=(qdio_q_t*)q->list_next;
1539 	} while (q!=(qdio_q_t*)tiq_list);
1540 
1541 	/* switch off all queues' processing state, see comments in
1542 	 * qdio_get_inbound_buffer_frontier */
1543 #ifdef QDIO_USE_PROCESSING_STATE
1544 	q=(qdio_q_t*)tiq_list;
1545 	do {
1546 		if (!q) {
1547 			tiqdio_sched_tl();
1548 			break;
1549 		}
1550 		/* under VM, we have not used the PROCESSING state, so no
1551 		 * need to stop polling */
1552 		if (q->siga_sync) {
1553 			q=(qdio_q_t*)q->list_next;
1554 			continue;
1555 		}
1556 
1557 		if (unlikely(qdio_reserve_q(q))) {
1558 			qdio_release_q(q);
1559 #ifdef QDIO_PERFORMANCE_STATS
1560 			ii_p_c++;
1561 #endif /* QDIO_PERFORMANCE_STATS */
1562 			/* as we might just be about to stop polling, we make
1563 			 * sure that we check again at least once more */
1564 
1565 			/* sanity -- we'd get here without setting the
1566 			 * dev st chg ind */
1567 			tiqdio_set_summary_bit((__u32*)q->dev_st_chg_ind);
1568 			tiqdio_sched_tl();
1569 			break;
1570 		}
1571 		if (!qdio_stop_polling(q)) {
1572 			q_laps++;
1573 			if (q_laps<QDIO_Q_LAPS) {
1574 				qdio_release_q(q);
1575 				goto again;
1576 			} else {
1577 				/* we set the flags to get into the stuff
1578 				 * next time, see also comment in
1579 				 * qdio_stop_polling */
1580 				tiqdio_set_summary_bit((__u32*)
1581 						      q->dev_st_chg_ind);
1582 				tiqdio_sched_tl();
1583 			}
1584 		}
1585 		qdio_release_q(q);
1586 		q=(qdio_q_t*)q->list_next;
1587 	} while (q!=(qdio_q_t*)tiq_list);
1588 #endif /* QDIO_USE_PROCESSING_STATE */
1589 }
1590 
tiqdio_tl(unsigned long data)1591 static void tiqdio_tl(unsigned long data)
1592 {
1593 #ifdef QDIO_DBF_LIKE_HELL
1594 	QDIO_DBF_TEXT4(0,trace,"tiqdio_tl");
1595 #endif /* QDIO_DBF_LIKE_HELL */
1596 #ifdef QDIO_PERFORMANCE_STATS
1597 	perf_stats.tl_runs++;
1598 #endif /* QDIO_PERFORMANCE_STATS */
1599 
1600 	tiqdio_inbound_checks();
1601 }
1602 
1603 /********************* GENERAL HELPER_ROUTINES ***********************/
1604 
qdio_get_irq_ptr(int irq)1605 static qdio_irq_t *qdio_get_irq_ptr(int irq)
1606 {
1607 	qdio_irq_t *irq_ptr;
1608 	int bucket=irq&(QDIO_IRQ_BUCKETS-1);
1609 
1610 	read_lock(&irq_list_lock[bucket]);
1611 	irq_ptr=first_irq[bucket];
1612 	while (irq_ptr) {
1613 		if (irq_ptr->irq==irq) break;
1614 		irq_ptr=irq_ptr->next;
1615 	}
1616 	read_unlock(&irq_list_lock[bucket]);
1617 	return irq_ptr;
1618 }
1619 
qdio_get_irq_ptr_wolock(int irq)1620 static qdio_irq_t *qdio_get_irq_ptr_wolock(int irq)
1621 {
1622 	qdio_irq_t *irq_ptr=first_irq[irq&(QDIO_IRQ_BUCKETS-1)];
1623 
1624 	while (irq_ptr) {
1625 		if (irq_ptr->irq==irq) break;
1626 		irq_ptr=irq_ptr->next;
1627 	}
1628 	return irq_ptr;
1629 }
1630 
1631 /* irq_ptr->irq should be set already! */
qdio_insert_irq_ptr(qdio_irq_t * irq_ptr)1632 static void qdio_insert_irq_ptr(qdio_irq_t *irq_ptr)
1633 {
1634 	qdio_irq_t *i_p;
1635 	int irq,bucket;
1636 
1637 	if (!irq_ptr) return;
1638 
1639 	irq=irq_ptr->irq;
1640 	bucket=irq&(QDIO_IRQ_BUCKETS-1);
1641 
1642 	write_lock(&irq_list_lock[bucket]);
1643 
1644 	if (irq_ptr==qdio_get_irq_ptr_wolock(irq)) goto out;
1645 
1646 	if (!first_irq[bucket]) {
1647 		first_irq[bucket]=irq_ptr;
1648 	} else {
1649 		i_p=first_irq[bucket];
1650 		while (i_p->next)
1651 			i_p=i_p->next;
1652 		i_p->next=irq_ptr;
1653 	}
1654 	irq_ptr->next=NULL;
1655 out:
1656 	write_unlock(&irq_list_lock[bucket]);
1657 }
1658 
qdio_remove_irq_ptr(qdio_irq_t * irq_ptr)1659 static void qdio_remove_irq_ptr(qdio_irq_t *irq_ptr)
1660 {
1661 	qdio_irq_t *i_p;
1662 	int irq,bucket;
1663 
1664 	if (!irq_ptr) return;
1665 
1666 	irq=irq_ptr->irq;
1667 	bucket=irq&(QDIO_IRQ_BUCKETS-1);
1668 
1669 	write_lock(&irq_list_lock[bucket]);
1670 
1671 	if (!qdio_get_irq_ptr_wolock(irq)) goto out;
1672 
1673 	if (first_irq[irq&(QDIO_IRQ_BUCKETS-1)]==irq_ptr) {
1674 		first_irq[irq&(QDIO_IRQ_BUCKETS-1)]=irq_ptr->next;
1675 	} else {
1676 		for (i_p=first_irq[irq&(QDIO_IRQ_BUCKETS-1)];
1677 		     i_p->next!=irq_ptr;i_p=i_p->next);
1678 		i_p->next=irq_ptr->next;
1679 	}
1680 	irq_ptr->next=NULL;
1681 out:
1682 	write_unlock(&irq_list_lock[bucket]);
1683 }
1684 
qdio_release_irq_memory(qdio_irq_t * irq_ptr)1685 static void qdio_release_irq_memory(qdio_irq_t *irq_ptr)
1686 {
1687 	int i,j;
1688 	int available;
1689 
1690 	for (i=0;i<QDIO_MAX_QUEUES_PER_IRQ;i++) {
1691 		if (!irq_ptr->input_qs[i]) goto next;
1692 		available=0;
1693 		if (!irq_ptr->input_qs[i]->is_0copy_sbals_q)
1694 			for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) {
1695 				if (!available) {
1696 					if (irq_ptr->input_qs[i]->sbal[j])
1697 						kfree((void*)irq_ptr->
1698 						      input_qs[i]->sbal[j]);
1699 					available=PAGE_SIZE;
1700 				}
1701 				available-=sizeof(sbal_t);
1702 			}
1703 		if (irq_ptr->input_qs[i]->slib)
1704 			kfree(irq_ptr->input_qs[i]->slib);
1705 			kfree(irq_ptr->input_qs[i]);
1706 
1707 next:
1708 		if (!irq_ptr->output_qs[i]) continue;
1709 		available=0;
1710 		if (!irq_ptr->output_qs[i]->is_0copy_sbals_q)
1711 			for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) {
1712 				if (!available) {
1713 					if (irq_ptr->output_qs[i]->sbal[j])
1714 						kfree((void*)irq_ptr->
1715 						      output_qs[i]->sbal[j]);
1716 					available=PAGE_SIZE;
1717 				}
1718 				available-=sizeof(sbal_t);
1719 			}
1720 		if (irq_ptr->output_qs[i]->slib)
1721 			kfree(irq_ptr->output_qs[i]->slib);
1722 		kfree(irq_ptr->output_qs[i]);
1723 
1724 	}
1725 	kfree(irq_ptr->qdr);
1726 	kfree(irq_ptr);
1727 }
1728 
qdio_wakeup(atomic_t * var,qdio_irq_t * irq_ptr)1729 static inline void qdio_wakeup(atomic_t *var,qdio_irq_t *irq_ptr)
1730 {
1731 	wait_queue_head_t *wait_q;
1732 
1733 #ifdef QDIO_DBF_LIKE_HELL
1734 	char dbf_text[20];
1735 	sprintf(dbf_text,"qwkp%4x",irq_ptr->irq);
1736 	QDIO_DBF_TEXT3(0,trace,dbf_text);
1737 #endif /* QDIO_DBF_LIKE_HELL */
1738 
1739 	atomic_set(var,1);
1740 	if ((wait_q=&irq_ptr->wait_q))
1741 		wake_up(wait_q);
1742 }
1743 
qdio_sleepon(atomic_t * var,int timeout,qdio_irq_t * irq_ptr)1744 static int qdio_sleepon(atomic_t *var,int timeout,qdio_irq_t *irq_ptr)
1745 {
1746         __u64 stop;
1747 	int retval;
1748         DECLARE_WAITQUEUE (current_wait_q,current);
1749 
1750 #ifdef QDIO_DBF_LIKE_HELL
1751 	char dbf_text[20];
1752 	sprintf(dbf_text,"qslp%4x",irq_ptr->irq);
1753 	QDIO_DBF_TEXT3(0,trace,dbf_text);
1754 #endif /* QDIO_DBF_LIKE_HELL */
1755 
1756 	add_wait_queue(&irq_ptr->wait_q,&current_wait_q);
1757         stop=(qdio_get_micros()>>10)+timeout;
1758         for (;;) {
1759 		set_task_state(current,TASK_INTERRUPTIBLE);
1760 		if (atomic_read(var)) {
1761 			atomic_set(var,0);
1762                         retval=0;
1763 			goto out;
1764                 }
1765                 if (qdio_get_micros()>>10>stop) {
1766 #ifdef QDIO_DBF_LIKE_HELL
1767 			sprintf(dbf_text,"%xtime",irq_ptr->irq);
1768 			QDIO_DBF_TEXT3(0,trace,dbf_text);
1769 #endif /* QDIO_DBF_LIKE_HELL */
1770 			retval=-ETIME;
1771 			goto out;
1772 		}
1773                 schedule_timeout(((stop-(qdio_get_micros()>>10))>>10)*HZ);
1774         }
1775  out:
1776 	set_task_state(current,TASK_RUNNING);
1777 	remove_wait_queue(&irq_ptr->wait_q,&current_wait_q);
1778 	return retval;
1779 }
1780 
qdio_set_impl_params(qdio_irq_t * irq_ptr,unsigned int qib_param_field_format,unsigned char * qib_param_field,unsigned int no_input_qs,unsigned int no_output_qs,unsigned long * input_slib_elements,unsigned long * output_slib_elements)1781 static void qdio_set_impl_params(qdio_irq_t *irq_ptr,
1782 				 unsigned int qib_param_field_format,
1783 			  /* pointer to 128 bytes or NULL, if no param field */
1784 				 unsigned char *qib_param_field,
1785 				 unsigned int no_input_qs,
1786 				 unsigned int no_output_qs,
1787 			  /* pointer to no_queues*128 words of data or NULL */
1788 				 unsigned long *input_slib_elements,
1789 				 unsigned long *output_slib_elements)
1790 {
1791 	int i,j;
1792 
1793 	if (!irq_ptr) return;
1794 
1795 	irq_ptr->qib.pfmt=qib_param_field_format;
1796 	if (qib_param_field)
1797 		memcpy(irq_ptr->qib.parm,qib_param_field,
1798 		       QDIO_MAX_BUFFERS_PER_Q);
1799 
1800 	if (input_slib_elements)
1801 		for (i=0;i<no_input_qs;i++) {
1802 			for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++)
1803 				irq_ptr->input_qs[i]->slib->slibe[j].parms=
1804 					input_slib_elements[
1805 						i*QDIO_MAX_BUFFERS_PER_Q+j];
1806 		}
1807 	if (output_slib_elements)
1808 		for (i=0;i<no_output_qs;i++) {
1809 			for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++)
1810 				irq_ptr->output_qs[i]->slib->slibe[j].parms=
1811 					output_slib_elements[
1812 						i*QDIO_MAX_BUFFERS_PER_Q+j];
1813 		}
1814 }
1815 
1816 
1817 
qdio_alloc_qs(qdio_irq_t * irq_ptr,int no_input_qs,int no_output_qs,qdio_handler_t * input_handler,qdio_handler_t * output_handler,unsigned long int_parm,int q_format,unsigned long flags,void ** inbound_sbals_array,void ** outbound_sbals_array)1818 static int qdio_alloc_qs(qdio_irq_t *irq_ptr,int no_input_qs,int no_output_qs,
1819 			 qdio_handler_t *input_handler,
1820 			 qdio_handler_t *output_handler,
1821 			 unsigned long int_parm,int q_format,
1822 			 unsigned long flags,
1823 			 void **inbound_sbals_array,
1824 			 void **outbound_sbals_array)
1825 {
1826 	qdio_q_t *q;
1827 	int i,j,result=0;
1828 	char dbf_text[20]; /* see qdio_initialize */
1829 	void *ptr;
1830 	int available;
1831 
1832 	for (i=0;i<no_input_qs;i++) {
1833 		q=kmalloc(sizeof(qdio_q_t),GFP_KERNEL);
1834 
1835 		if (!q) {
1836 			QDIO_PRINT_ERR("kmalloc of q failed!\n");
1837 			goto out;
1838 		}
1839 		memset(q,0,sizeof(qdio_q_t));
1840 
1841 		sprintf(dbf_text,"in-q%4x",i);
1842 		QDIO_DBF_TEXT0(0,setup,dbf_text);
1843 		QDIO_DBF_HEX0(0,setup,&q,sizeof(void*));
1844 
1845 		q->slib=kmalloc(PAGE_SIZE,GFP_KERNEL);
1846 		if (!q->slib) {
1847 			QDIO_PRINT_ERR("kmalloc of slib failed!\n");
1848 			goto out;
1849 		}
1850 		memset(q->slib,0,PAGE_SIZE);
1851 		q->sl=(sl_t*)(((char*)q->slib)+PAGE_SIZE/2);
1852 
1853 		available=0;
1854 		if (flags&QDIO_INBOUND_0COPY_SBALS) {
1855 			for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) {
1856 				q->sbal[j]=*(inbound_sbals_array++);
1857 			}
1858 		} else for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) {
1859 			if (!available) {
1860 				q->sbal[j]=kmalloc(PAGE_SIZE,GFP_KERNEL);
1861 				if (!q->sbal[j]) {
1862 					goto out;
1863 				}
1864 				available=PAGE_SIZE;
1865 				memset((void*)q->sbal[j],0,PAGE_SIZE);
1866 			} else {
1867 				q->sbal[j]=(volatile sbal_t *)
1868 					(((char*)q->sbal[j-1])+sizeof(sbal_t));
1869 			}
1870 			available-=sizeof(sbal_t);
1871 		}
1872 
1873                 q->queue_type=q_format;
1874 		q->int_parm=int_parm;
1875 		irq_ptr->input_qs[i]=q;
1876 		q->irq=irq_ptr->irq;
1877 		q->irq_ptr=irq_ptr;
1878 		q->mask=1<<(31-i);
1879 		q->q_no=i;
1880 		q->is_input_q=1;
1881 		q->is_0copy_sbals_q=flags&QDIO_INBOUND_0COPY_SBALS;
1882 		q->first_to_check=0;
1883 		q->last_move_ftc=0;
1884 		q->handler=input_handler;
1885 		q->dev_st_chg_ind=irq_ptr->dev_st_chg_ind;
1886 
1887 		q->tasklet.data=(unsigned long)q;
1888 		/* q->is_thinint_q isn't valid at this time, but
1889 		 * irq_ptr->is_thinint_irq is */
1890 		q->tasklet.func=(void(*)(unsigned long))
1891 			((irq_ptr->is_thinint_irq)?&tiqdio_inbound_processing:
1892 			 &qdio_inbound_processing);
1893 
1894 		/* actually this is not used for inbound queues. yet. */
1895 		atomic_set(&q->busy_siga_counter,0);
1896 		q->timing.busy_start=0;
1897 
1898 /*		for (j=0;j<QDIO_STATS_NUMBER;j++)
1899 			q->timing.last_transfer_times[j]=(qdio_get_micros()/
1900 							  QDIO_STATS_NUMBER)*j;
1901 		q->timing.last_transfer_index=QDIO_STATS_NUMBER-1;
1902 */
1903 
1904 		/* fill in slib */
1905 		if (i>0) irq_ptr->input_qs[i-1]->slib->nsliba=
1906 				 QDIO_PFIX_GET_ADDR(q->slib);
1907 		q->slib->sla=QDIO_PFIX_GET_ADDR(q->sl);
1908 		q->slib->slsba=QDIO_PFIX_GET_ADDR((void *)&q->slsb.acc.val[0]);
1909 
1910 		/* fill in sl */
1911 		for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++)
1912 			q->sl->element[j].sbal=
1913 				QDIO_PFIX_GET_ADDR((void *)q->sbal[j]);
1914 
1915 		QDIO_DBF_TEXT2(0,setup,"sl-sb-b0");
1916 		ptr=(void*)q->sl;
1917 		QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*));
1918 		ptr=(void*)&q->slsb;
1919 		QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*));
1920 		ptr=(void*)q->sbal[0];
1921 		QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*));
1922 
1923 		/* fill in slsb */
1924 		for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) {
1925 			set_slsb(&q->slsb.acc.val[j],
1926 		   		 SLSB_P_INPUT_NOT_INIT);
1927 			q->sbal[j]->element[1].sbalf.i1.key=
1928 				QDIO_STORAGE_ACC_KEY;
1929 		}
1930 	}
1931 
1932 	for (i=0;i<no_output_qs;i++) {
1933 		q=kmalloc(sizeof(qdio_q_t),GFP_KERNEL);
1934 
1935 		if (!q) {
1936 			goto out;
1937 		}
1938 		memset(q,0,sizeof(qdio_q_t));
1939 
1940 		sprintf(dbf_text,"outq%4x",i);
1941 		QDIO_DBF_TEXT0(0,setup,dbf_text);
1942 		QDIO_DBF_HEX0(0,setup,&q,sizeof(void*));
1943 
1944 		q->slib=kmalloc(PAGE_SIZE,GFP_KERNEL);
1945 		if (!q->slib) {
1946 			QDIO_PRINT_ERR("kmalloc of slib failed!\n");
1947 			goto out;
1948 		}
1949 		memset(q->slib,0,PAGE_SIZE);
1950 		q->sl=(sl_t*)(((char*)q->slib)+PAGE_SIZE/2);
1951 
1952 		available=0;
1953 		if (flags&QDIO_OUTBOUND_0COPY_SBALS) {
1954 			for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) {
1955 				q->sbal[j]=*(outbound_sbals_array++);
1956 			}
1957 		} else for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) {
1958 			if (!available) {
1959 				q->sbal[j]=kmalloc(PAGE_SIZE,GFP_KERNEL);
1960 				if (!q->sbal[j]) {
1961 					goto out;
1962 				}
1963 				available=PAGE_SIZE;
1964 				memset((void*)q->sbal[j],0,PAGE_SIZE);
1965 			} else {
1966 				q->sbal[j]=(volatile sbal_t *)
1967 					(((char*)q->sbal[j-1])+sizeof(sbal_t));
1968 			}
1969 			available-=sizeof(sbal_t);
1970 		}
1971 
1972                 q->queue_type=q_format;
1973 		q->int_parm=int_parm;
1974 		irq_ptr->output_qs[i]=q;
1975 		q->is_input_q=0;
1976 		q->is_0copy_sbals_q=flags&QDIO_OUTBOUND_0COPY_SBALS;
1977 		q->irq=irq_ptr->irq;
1978 		q->irq_ptr=irq_ptr;
1979 		q->mask=1<<(31-i);
1980 		q->q_no=i;
1981 		q->first_to_check=0;
1982 		q->last_move_ftc=0;
1983 		q->handler=output_handler;
1984 
1985 		q->tasklet.data=(unsigned long)q;
1986 		q->tasklet.func=(void(*)(unsigned long))
1987 			&qdio_outbound_processing;
1988 
1989 		atomic_set(&q->busy_siga_counter,0);
1990 		q->timing.busy_start=0;
1991 
1992 		/* fill in slib */
1993 		if (i>0) irq_ptr->output_qs[i-1]->slib->nsliba=
1994 				 QDIO_PFIX_GET_ADDR(q->slib);
1995 		q->slib->sla=QDIO_PFIX_GET_ADDR(q->sl);
1996 		q->slib->slsba=QDIO_PFIX_GET_ADDR((void *)&q->slsb.acc.val[0]);
1997 
1998 		/* fill in sl */
1999 		for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++)
2000 			q->sl->element[j].sbal=
2001 				QDIO_PFIX_GET_ADDR((void *)q->sbal[j]);
2002 
2003 		QDIO_DBF_TEXT2(0,setup,"sl-sb-b0");
2004 		ptr=(void*)q->sl;
2005 		QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*));
2006 		ptr=(void*)&q->slsb;
2007 		QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*));
2008 		ptr=(void*)q->sbal[0];
2009 		QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*));
2010 
2011 		/* fill in slsb */
2012 		for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) {
2013 			set_slsb(&q->slsb.acc.val[j],
2014 		   		 SLSB_P_OUTPUT_NOT_INIT);
2015 			q->sbal[j]->element[1].sbalf.i1.key=
2016 				QDIO_STORAGE_ACC_KEY;
2017 		}
2018 	}
2019 
2020 	result=1;
2021 out:
2022 	return result;
2023 }
2024 
qdio_fill_thresholds(qdio_irq_t * irq_ptr,unsigned int no_input_qs,unsigned int no_output_qs,unsigned int min_input_threshold,unsigned int max_input_threshold,unsigned int min_output_threshold,unsigned int max_output_threshold)2025 static void qdio_fill_thresholds(qdio_irq_t *irq_ptr,
2026 				 unsigned int no_input_qs,
2027 				 unsigned int no_output_qs,
2028 				 unsigned int min_input_threshold,
2029 				 unsigned int max_input_threshold,
2030 				 unsigned int min_output_threshold,
2031 				 unsigned int max_output_threshold)
2032 {
2033 	int i;
2034 	qdio_q_t *q;
2035 
2036 	for (i=0;i<no_input_qs;i++) {
2037 		q=irq_ptr->input_qs[i];
2038 		q->timing.threshold=max_input_threshold;
2039 /*		for (j=0;j<QDIO_STATS_CLASSES;j++) {
2040 			q->threshold_classes[j].threshold=
2041 				min_input_threshold+
2042 				(max_input_threshold-min_input_threshold)/
2043 				QDIO_STATS_CLASSES;
2044 		}
2045 		qdio_use_thresholds(q,QDIO_STATS_CLASSES/2);*/
2046 	}
2047 	for (i=0;i<no_output_qs;i++) {
2048 		q=irq_ptr->output_qs[i];
2049 		q->timing.threshold=max_output_threshold;
2050 /*		for (j=0;j<QDIO_STATS_CLASSES;j++) {
2051 			q->threshold_classes[j].threshold=
2052 				min_output_threshold+
2053 				(max_output_threshold-min_output_threshold)/
2054 				QDIO_STATS_CLASSES;
2055 		}
2056 		qdio_use_thresholds(q,QDIO_STATS_CLASSES/2);*/
2057 	}
2058 }
2059 
tiqdio_thinint_handler(__u32 intparm)2060 static int tiqdio_thinint_handler(__u32 intparm)
2061 {
2062 #ifdef QDIO_DBF_LIKE_HELL
2063 	QDIO_DBF_TEXT4(0,trace,"thin_int");
2064 #endif /* QDIO_DBF_LIKE_HELL */
2065 
2066 #ifdef QDIO_PERFORMANCE_STATS
2067 	perf_stats.thinints++;
2068 	perf_stats.start_time_inbound=NOW;
2069 #endif /* QDIO_PERFORMANCE_STATS */
2070 
2071 	/* SVS only when needed:
2072 	 * issue SVS to benefit from iqdio interrupt avoidance
2073 	 * (SVS clears AISOI)*/
2074 	if (!omit_svs) {
2075 		tiqdio_clear_global_summary();
2076 	}
2077 
2078 	tiqdio_inbound_checks();
2079 	return 0;
2080 }
2081 
qdio_set_state(qdio_irq_t * irq_ptr,int state)2082 static void qdio_set_state(qdio_irq_t *irq_ptr,int state)
2083 {
2084 	int i;
2085 	char dbf_text[15];
2086 
2087 	QDIO_DBF_TEXT5(0,trace,"newstate");
2088 	sprintf(dbf_text,"%4x%4x",irq_ptr->irq,state);
2089 	QDIO_DBF_TEXT5(0,trace,dbf_text);
2090 
2091 	irq_ptr->state=state;
2092 	for (i=0;i<irq_ptr->no_input_qs;i++)
2093 		irq_ptr->input_qs[i]->state=state;
2094 	for (i=0;i<irq_ptr->no_output_qs;i++)
2095 		irq_ptr->output_qs[i]->state=state;
2096 	mb();
2097 }
2098 
qdio_handler(int irq,devstat_t * devstat,struct pt_regs * p)2099 static void qdio_handler(int irq,devstat_t *devstat,struct pt_regs *p)
2100 {
2101 	qdio_irq_t *irq_ptr;
2102 	qdio_q_t *q;
2103 	int i;
2104 	int cstat,dstat;
2105 	int rqparam;
2106 	char dbf_text[15]="qintXXXX";
2107 
2108         cstat = devstat->cstat;
2109         dstat = devstat->dstat;
2110         rqparam=devstat->intparm;
2111 
2112 	*((int*)(&dbf_text[4]))=irq;
2113 	QDIO_DBF_HEX4(0,trace,dbf_text,QDIO_DBF_TRACE_LEN);
2114 
2115 	if (!rqparam) {
2116 		QDIO_PRINT_STUPID("got unsolicited interrupt in qdio " \
2117 				  "handler, irq 0x%x\n",irq);
2118 		return;
2119 	}
2120 
2121 	irq_ptr=qdio_get_irq_ptr(irq);
2122 	if (!irq_ptr) {
2123 		sprintf(dbf_text,"uint%4x",irq);
2124 		QDIO_DBF_TEXT2(1,trace,dbf_text);
2125 		QDIO_PRINT_ERR("received interrupt on unused irq 0x%04x!\n",
2126 			       irq);
2127 		return;
2128 	}
2129 
2130 	if (devstat->flag&DEVSTAT_FLAG_SENSE_AVAIL) {
2131 		sprintf(dbf_text,"sens%4x",irq);
2132 		QDIO_DBF_TEXT2(1,trace,dbf_text);
2133 		QDIO_DBF_HEX0(0,sense,&devstat->ii.irb,QDIO_DBF_SENSE_LEN);
2134 
2135 		QDIO_PRINT_WARN("sense data available on qdio channel.\n");
2136 		HEXDUMP16(WARN,"irb: ",&devstat->ii.irb);
2137 		HEXDUMP16(WARN,"sense data: ",&devstat->ii.sense.data[0]);
2138 	}
2139 
2140 	irq_ptr->io_result_cstat=ioinfo[irq]->devstat.cstat;
2141 	irq_ptr->io_result_dstat=ioinfo[irq]->devstat.dstat;
2142 	irq_ptr->io_result_flags=ioinfo[irq]->devstat.flag;
2143 
2144 	if ( (rqparam==QDIO_DOING_ACTIVATE) &&
2145 	     (cstat & SCHN_STAT_PCI) ) {
2146 #ifdef QDIO_PERFORMANCE_STATS
2147 		perf_stats.pcis++;
2148 		perf_stats.start_time_inbound=NOW;
2149 #endif /* QDIO_PERFORMANCE_STATS */
2150 		for (i=0;i<irq_ptr->no_input_qs;i++) {
2151 			q=irq_ptr->input_qs[i];
2152 			if (q->is_input_q&QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT)
2153 				qdio_mark_q(q);
2154 			else {
2155 #ifdef QDIO_PERFORMANCE_STATS
2156 				perf_stats.tl_runs--;
2157 #endif /* QDIO_PERFORMANCE_STATS */
2158 				__qdio_inbound_processing(q);
2159 			}
2160 		}
2161 		if (irq_ptr->hydra_gives_outbound_pcis) {
2162  			for (i=0;i<irq_ptr->no_output_qs;i++) {
2163  				q=irq_ptr->output_qs[i];
2164 #ifdef QDIO_PERFORMANCE_STATS
2165 				perf_stats.tl_runs--;
2166 #endif /* QDIO_PERFORMANCE_STATS */
2167 				if (!qdio_is_outbound_q_done(q)) {
2168 					if (!irq_ptr->sync_done_on_outb_pcis) {
2169 						SYNC_MEMORY;
2170 					}
2171 					__qdio_outbound_processing(q);
2172 				}
2173 			}
2174 		}
2175 		return;
2176 	}
2177 
2178 	if ( (rqparam==QDIO_DOING_ACTIVATE) &&
2179 	     (!cstat) &&
2180 	     (!dstat) ) {
2181 		rqparam=QDIO_DOING_CLEANUP;
2182 	}
2183 
2184 	if ( (rqparam==QDIO_DOING_ESTABLISH) &&
2185 	     ( (cstat) ||
2186 	       (dstat & ~(DEV_STAT_CHN_END|DEV_STAT_DEV_END)) ) ) {
2187 		sprintf(dbf_text,"ick1%4x",irq);
2188 		QDIO_DBF_TEXT2(1,trace,dbf_text);
2189 		QDIO_DBF_HEX2(0,trace,&rqparam,sizeof(int));
2190 		QDIO_DBF_HEX2(0,trace,&dstat,sizeof(int));
2191 		QDIO_DBF_HEX2(0,trace,&cstat,sizeof(int));
2192 		QDIO_PRINT_ERR("received check condition on establish " \
2193 			       "queues on irq 0x%x (cs=x%x, ds=x%x).\n",
2194 			       irq,cstat,dstat);
2195 		qdio_set_state(irq_ptr,QDIO_IRQ_STATE_STOPPED);
2196 		return;
2197 	}
2198 
2199 	if ( ( (rqparam==QDIO_DOING_ACTIVATE) &&
2200 	       (dstat==(DEV_STAT_CHN_END|DEV_STAT_DEV_END)) ) ||
2201 	     ( (rqparam==QDIO_DOING_CLEANUP) || (!rqparam) ) ) {
2202 		qdio_wakeup(&irq_ptr->interrupt_has_been_cleaned,irq_ptr);
2203 		return;
2204 	}
2205 
2206 	if ( (rqparam==QDIO_DOING_ACTIVATE) &&
2207 	     ( (cstat & ~SCHN_STAT_PCI) ||
2208 	       (dstat) ) ) {
2209 		sprintf(dbf_text,"ick2%4x",irq);
2210 		QDIO_DBF_TEXT2(1,trace,dbf_text);
2211 		QDIO_DBF_HEX2(0,trace,&rqparam,sizeof(int));
2212 		QDIO_DBF_HEX2(0,trace,&dstat,sizeof(int));
2213 		QDIO_DBF_HEX2(0,trace,&cstat,sizeof(int));
2214 		QDIO_PRINT_ERR("received check condition on activate " \
2215 			       "queues on irq 0x%x (cs=x%x, ds=x%x).\n",
2216 			       irq,cstat,dstat);
2217 		if (irq_ptr->no_input_qs) {
2218 			q=irq_ptr->input_qs[0];
2219 		} else if (irq_ptr->no_output_qs) {
2220 			q=irq_ptr->output_qs[0];
2221 		} else {
2222 			QDIO_PRINT_ERR("oops... no queue registered on irq " \
2223 				  "0x%x!?\n",irq);
2224 			goto omit_handler_call;
2225 		}
2226 		q->handler(q->irq,QDIO_STATUS_ACTIVATE_CHECK_CONDITION|
2227 			   QDIO_STATUS_LOOK_FOR_ERROR,
2228 			   0,0,0,-1,-1,q->int_parm);
2229 	omit_handler_call:
2230 		qdio_set_state(irq_ptr,QDIO_IRQ_STATE_STOPPED);
2231 		return;
2232 	}
2233 
2234 	qdio_wakeup(&irq_ptr->interrupt_has_arrived,irq_ptr);
2235 }
2236 
2237 /* this is for mp3 */
qdio_synchronize(int irq,unsigned int flags,unsigned int queue_number)2238 int qdio_synchronize(int irq,unsigned int flags,
2239 		     unsigned int queue_number)
2240 {
2241 	unsigned int gpr2,gpr3;
2242 	int cc;
2243 	qdio_q_t *q;
2244 	qdio_irq_t *irq_ptr;
2245 	char dbf_text[15]="SyncXXXX";
2246 	void *ptr;
2247 
2248 	*((int*)(&dbf_text[4]))=irq;
2249 	QDIO_DBF_HEX4(0,trace,dbf_text,QDIO_DBF_TRACE_LEN);
2250 	*((int*)(&dbf_text[0]))=flags;
2251 	*((int*)(&dbf_text[4]))=queue_number;
2252 	QDIO_DBF_HEX4(0,trace,dbf_text,QDIO_DBF_TRACE_LEN);
2253 
2254 	irq_ptr=qdio_get_irq_ptr(irq);
2255 	if (!irq_ptr) return -ENODEV;
2256 
2257 	if (flags&QDIO_FLAG_SYNC_INPUT) {
2258 		q=irq_ptr->input_qs[queue_number];
2259 		if (!q) return -EINVAL;
2260 
2261 		gpr2=0;
2262 		gpr3=q->mask;
2263 	} else if (flags&QDIO_FLAG_SYNC_OUTPUT) {
2264 		q=irq_ptr->output_qs[queue_number];
2265 		if (!q) return -EINVAL;
2266 
2267 		gpr2=q->mask;
2268 		gpr3=0;
2269 	} else return -EINVAL;
2270 
2271 #ifdef QDIO_32_BIT
2272 	asm volatile (
2273 		"lhi	0,2	\n\t"
2274 		"lr	1,%1	\n\t"
2275 		"lr	2,%2	\n\t"
2276 		"lr	3,%3	\n\t"
2277 		"siga   0	\n\t"
2278 		"ipm	%0	\n\t"
2279 		"srl	%0,28	\n\t"
2280 		: "=d" (cc)
2281 		: "d" (0x10000|q->irq), "d" (gpr2), "d" (gpr3)
2282 		: "cc", "0", "1", "2", "3"
2283 		);
2284 #else /* QDIO_32_BIT */
2285 	asm volatile (
2286 		"lghi	0,2	\n\t"
2287 		"llgfr	1,%1	\n\t"
2288 		"llgfr	2,%2	\n\t"
2289 		"llgfr	3,%3	\n\t"
2290 		"siga   0	\n\t"
2291 		"ipm	%0	\n\t"
2292 		"srl	%0,28	\n\t"
2293 		: "=d" (cc)
2294 		: "d" (0x10000|q->irq), "d" (gpr2), "d" (gpr3)
2295 		: "cc", "0", "1", "2", "3"
2296 		);
2297 #endif /* QDIO_32_BIT */
2298 
2299 	ptr=&cc;
2300 	if (cc) QDIO_DBF_HEX3(0,trace,&ptr,sizeof(int));
2301 
2302 	return cc;
2303 }
2304 
qdio_get_slsb_state(int irq,unsigned int flag,unsigned int queue_number,unsigned int qidx)2305 unsigned char qdio_get_slsb_state(int irq,unsigned int flag,
2306 				  unsigned int queue_number,
2307 				  unsigned int qidx)
2308 {
2309 	qdio_irq_t *irq_ptr;
2310 	qdio_q_t *q;
2311 
2312 	irq_ptr=qdio_get_irq_ptr(irq);
2313 	if (!irq_ptr) return SLSB_ERROR_DURING_LOOKUP;
2314 
2315 	if (flag&QDIO_FLAG_SYNC_INPUT) {
2316 		q=irq_ptr->input_qs[queue_number];
2317 	} else if (flag&QDIO_FLAG_SYNC_OUTPUT) {
2318 		q=irq_ptr->output_qs[queue_number];
2319 	} else return SLSB_ERROR_DURING_LOOKUP;
2320 
2321 	return q->slsb.acc.val[qidx&(QDIO_MAX_BUFFERS_PER_Q-1)];
2322 }
2323 
qdio_chsc(qdio_chsc_area_t * chsc_area)2324 static int qdio_chsc(qdio_chsc_area_t *chsc_area)
2325 {
2326 	int cc;
2327 
2328 #ifdef QDIO_32_BIT
2329 	asm volatile (
2330 		".insn	rre,0xb25f0000,%1,0	\n\t"
2331 		"ipm	%0	\n\t"
2332 		"srl	%0,28	\n\t"
2333 		: "=d" (cc) : "d" (chsc_area) : "cc"
2334 		);
2335 #else /* QDIO_32_BIT */
2336 	asm volatile (
2337 		".insn	rre,0xb25f0000,%1,0	\n\t"
2338 		"ipm	%0	\n\t"
2339 		"srl	%0,28	\n\t"
2340 		: "=d" (cc) : "d" (chsc_area) : "cc"
2341 		);
2342 #endif /* QDIO_32_BIT */
2343 
2344 	return cc;
2345 }
2346 
qdio_check_siga_needs(int sch)2347 static unsigned char qdio_check_siga_needs(int sch)
2348 {
2349 	int resp_code,result;
2350 	unsigned long flags;
2351 
2352 	spin_lock_irqsave(&chsc_area_lock,flags);
2353 
2354 	memset(chsc_area,0,sizeof(qdio_chsc_area_t));
2355 	chsc_area->request_block.command_code1=0x0010; /* length */
2356 	chsc_area->request_block.command_code2=0x0024; /* op code */
2357 	chsc_area->request_block.first_sch=sch;
2358 	chsc_area->request_block.last_sch=sch;
2359 
2360 	result=qdio_chsc(chsc_area);
2361 
2362 	if (result) {
2363 		QDIO_PRINT_WARN("CHSC returned cc %i. Using all " \
2364 				"SIGAs for sch x%x.\n",
2365 				result,sch);
2366 		result=-1; /* all flags set */
2367 		goto out;
2368 	}
2369 
2370 	resp_code=chsc_area->request_block.operation_data_area.
2371 		store_qdio_data_response.response_code;
2372 	if (resp_code!=QDIO_CHSC_RESPONSE_CODE_OK) {
2373 		QDIO_PRINT_WARN("response upon checking SIGA needs " \
2374 				"is 0x%x. Using all SIGAs for sch x%x.\n",
2375 				resp_code,sch);
2376 		result=-1; /* all flags set */
2377 		goto out;
2378 	}
2379 	if (
2380 	    (!(chsc_area->request_block.operation_data_area.
2381 	       store_qdio_data_response.flags&CHSC_FLAG_QDIO_CAPABILITY)) ||
2382 	    (!(chsc_area->request_block.operation_data_area.
2383 	       store_qdio_data_response.flags&CHSC_FLAG_VALIDITY)) ||
2384 	    (chsc_area->request_block.operation_data_area.
2385 	     store_qdio_data_response.sch!=sch)
2386 	    ) {
2387 		QDIO_PRINT_WARN("huh? problems checking out sch x%x... " \
2388 				"using all SIGAs.\n",sch);
2389 		result=CHSC_FLAG_SIGA_INPUT_NECESSARY |
2390 			CHSC_FLAG_SIGA_OUTPUT_NECESSARY |
2391 			CHSC_FLAG_SIGA_SYNC_NECESSARY; /* worst case */
2392 		goto out;
2393 	}
2394 
2395 	result=chsc_area->request_block.operation_data_area.
2396 		store_qdio_data_response.qdioac;
2397 out:
2398 	spin_unlock_irqrestore(&chsc_area_lock,flags);
2399 	return result;
2400 }
2401 
qdio_check_for_machine_features(void)2402 static void qdio_check_for_machine_features(void)
2403 {
2404 	int i,result;
2405 	unsigned long flags;
2406 
2407 	spin_lock_irqsave(&chsc_area_lock,flags);
2408 
2409 	memset(chsc_area,0,sizeof(qdio_chsc_area_t));
2410 	chsc_area->request_block.command_code1=0x0010;
2411 	chsc_area->request_block.command_code2=0x0010;
2412 	result=qdio_chsc(chsc_area);
2413 
2414 	if (result) {
2415 		QDIO_PRINT_WARN("CHSC returned cc %i. Won't use adapter " \
2416 				"interrupts for any QDIO device.\n",result);
2417 		result=0;
2418 		goto out;
2419 	}
2420 
2421 	i=chsc_area->request_block.operation_data_area.
2422 		store_qdio_data_response.response_code;
2423 	if (i!=1) {
2424 		QDIO_PRINT_WARN("Was not able to determine general " \
2425 				"characteristics of all QDIO devices " \
2426 				"aboard.\n");
2427 		result=0;
2428 		goto out;
2429 	}
2430 
2431 	/* 4: request block
2432 	 * 2: general char
2433 	 * 512: chsc char */
2434 	/* check for bit 67 */
2435 	if ( (*(((unsigned int*)(chsc_area))+4+2+2)&0x10000000)!=0x10000000) {
2436 		hydra_thinints=0;
2437 	} else {
2438 		hydra_thinints=1;
2439 	}
2440 
2441 	/* check for bit 56: if aif time delay disablement fac installed,
2442 	 * omit svs even under lpar (good point by rick again) */
2443 	if ( (*(((unsigned int*)(chsc_area))+4+2+1)&0x00000080)!=0x00000080) {
2444 		omit_svs=1;
2445 	} else {
2446 		omit_svs=0;
2447 	}
2448 out:
2449 	spin_unlock_irqrestore(&chsc_area_lock,flags);
2450 }
2451 
2452 /* the chsc_area is locked by the lock in qdio_activate */
tiqdio_check_chsc_availability(void)2453 static unsigned int tiqdio_check_chsc_availability(void) {
2454 	int result;
2455 	int i;
2456 	unsigned long flags;
2457 
2458 	spin_lock_irqsave(&chsc_area_lock,flags);
2459 
2460 	memset(chsc_area,0,sizeof(qdio_chsc_area_t));
2461 	chsc_area->request_block.command_code1=0x0010;
2462 	chsc_area->request_block.command_code2=0x0010;
2463 	result=qdio_chsc(chsc_area);
2464 	if (result) {
2465 		QDIO_PRINT_WARN("Was not able to determine " \
2466 				"available CHSCs, cc=%i.\n",
2467 				result);
2468 		result=-EIO;
2469 		goto exit;
2470 	}
2471 	result=0;
2472 	i=chsc_area->request_block.operation_data_area.
2473 		store_qdio_data_response.response_code;
2474 	if (i!=1) {
2475 		QDIO_PRINT_WARN("Was not able to determine " \
2476 				"available CHSCs.\n");
2477 		result=-EIO;
2478 		goto exit;
2479 	}
2480 	/* 4: request block
2481 	 * 2: general char
2482 	 * 512: chsc char */
2483 	/* check for bit 41 */
2484 	if ( (*(((unsigned int*)(chsc_area))+4+2+1)&0x00400000)!=0x00400000) {
2485 		QDIO_PRINT_WARN("Adapter interruption facility not " \
2486 				"installed.\n");
2487 		result=-ENOENT;
2488 		goto exit;
2489 	}
2490 	/* check for bits 107 and 108 */
2491 	if ( (*(((unsigned int*)(chsc_area))+4+512+3)&0x00180000)!=
2492 	     0x00180000 ) {
2493 		QDIO_PRINT_WARN("Set Chan Subsys. Char. & Fast-CHSCs " \
2494 				"not available.\n");
2495 		result=-ENOENT;
2496 		goto exit;
2497 	}
2498 exit:
2499 	spin_unlock_irqrestore(&chsc_area_lock,flags);
2500 	return result;
2501 }
2502 
2503 /* the chsc_area is locked by the lock in qdio_activate */
tiqdio_set_subchannel_ind(qdio_irq_t * irq_ptr,int reset_to_zero)2504 static unsigned int tiqdio_set_subchannel_ind(qdio_irq_t *irq_ptr,
2505 					     int reset_to_zero)
2506 {
2507 	unsigned long real_addr_local_summary_bit;
2508 	unsigned long real_addr_dev_st_chg_ind;
2509 	void *ptr;
2510 	unsigned long flags;
2511 	char dbf_text[15];
2512 
2513 	unsigned int resp_code;
2514 	int result;
2515 
2516 	if (!irq_ptr->is_thinint_irq) return -ENODEV;
2517 
2518 	if (reset_to_zero) {
2519 		real_addr_local_summary_bit=0;
2520 		real_addr_dev_st_chg_ind=0;
2521 	} else {
2522 		real_addr_local_summary_bit=
2523 			virt_to_phys((volatile void *)indicators);
2524 		real_addr_dev_st_chg_ind=
2525 			virt_to_phys((volatile void *)irq_ptr->dev_st_chg_ind);
2526 	}
2527 
2528 	spin_lock_irqsave(&chsc_area_lock,flags);
2529 
2530 	memset(chsc_area,0,sizeof(qdio_chsc_area_t));
2531 	chsc_area->request_block.command_code1=0x0fe0;
2532 	chsc_area->request_block.command_code2=0x0021;
2533 	chsc_area->request_block.operation_code=0;
2534 	chsc_area->request_block.image_id=0;
2535 
2536 	chsc_area->request_block.operation_data_area.set_chsc.
2537 		summary_indicator_addr=real_addr_local_summary_bit;
2538 	chsc_area->request_block.operation_data_area.set_chsc.
2539 		subchannel_indicator_addr=real_addr_dev_st_chg_ind;
2540 	chsc_area->request_block.operation_data_area.set_chsc.
2541 		ks=QDIO_STORAGE_ACC_KEY;
2542 	chsc_area->request_block.operation_data_area.set_chsc.
2543 		kc=QDIO_STORAGE_ACC_KEY;
2544 	chsc_area->request_block.operation_data_area.set_chsc.
2545 		isc=TIQDIO_THININT_ISC;
2546 	chsc_area->request_block.operation_data_area.set_chsc.
2547 		subsystem_id=(1<<16)+irq_ptr->irq;
2548 
2549 	result=qdio_chsc(chsc_area);
2550 	if (result) {
2551 		QDIO_PRINT_WARN("could not set indicators on irq x%x, " \
2552 				"cc=%i.\n",irq_ptr->irq,result);
2553 		result=-EIO;
2554 		goto out;
2555 	}
2556 
2557 	resp_code=chsc_area->response_block.response_code;
2558 	if (resp_code!=QDIO_CHSC_RESPONSE_CODE_OK) {
2559 		QDIO_PRINT_WARN("response upon setting indicators " \
2560 				"is 0x%x.\n",resp_code);
2561 		sprintf(dbf_text,"sidR%4x",resp_code);
2562 		QDIO_DBF_TEXT1(0,trace,dbf_text);
2563 		QDIO_DBF_TEXT1(0,setup,dbf_text);
2564 		ptr=&chsc_area->response_block;
2565 		QDIO_DBF_HEX2(1,setup,&ptr,QDIO_DBF_SETUP_LEN);
2566 		result=-EIO;
2567 		goto out;
2568 	}
2569 
2570 	QDIO_DBF_TEXT2(0,setup,"setscind");
2571 	QDIO_DBF_HEX2(0,setup,&real_addr_local_summary_bit,
2572 		      sizeof(unsigned long));
2573 	QDIO_DBF_HEX2(0,setup,&real_addr_dev_st_chg_ind,sizeof(unsigned long));
2574 	result=0;
2575 out:
2576 	spin_unlock_irqrestore(&chsc_area_lock,flags);
2577 	return result;
2578 }
2579 
2580 /* chsc_area would have to be locked if called from outside qdio_activate */
tiqdio_set_delay_target(qdio_irq_t * irq_ptr,unsigned long delay_target)2581 static unsigned int tiqdio_set_delay_target(qdio_irq_t *irq_ptr,
2582        					   unsigned long delay_target)
2583 {
2584 	unsigned int resp_code;
2585 	int result;
2586 	void *ptr;
2587 	unsigned long flags;
2588 	char dbf_text[15];
2589 
2590 	if (!irq_ptr->is_thinint_irq) return -ENODEV;
2591 
2592 	spin_lock_irqsave(&chsc_area_lock,flags);
2593 
2594 	memset(chsc_area,0,sizeof(qdio_chsc_area_t));
2595 	chsc_area->request_block.command_code1=0x0fe0;
2596 	chsc_area->request_block.command_code2=0x1027;
2597 	chsc_area->request_block.operation_data_area.set_chsc_fast.
2598 		delay_target=delay_target<<16;
2599 
2600 	result=qdio_chsc(chsc_area);
2601 	if (result) {
2602 		QDIO_PRINT_WARN("could not set delay target on irq x%x, " \
2603 				"cc=%i. Continuing.\n",irq_ptr->irq,result);
2604 		result=-EIO;
2605 		goto out;
2606 	}
2607 
2608 	resp_code=chsc_area->response_block.response_code;
2609 	if (resp_code!=QDIO_CHSC_RESPONSE_CODE_OK) {
2610 		QDIO_PRINT_WARN("response upon setting delay target " \
2611 				"is 0x%x. Continuing.\n",resp_code);
2612 		sprintf(dbf_text,"sdtR%4x",resp_code);
2613 		QDIO_DBF_TEXT1(0,trace,dbf_text);
2614 		QDIO_DBF_TEXT1(0,setup,dbf_text);
2615 		ptr=&chsc_area->response_block;
2616 		QDIO_DBF_HEX2(1,trace,&ptr,QDIO_DBF_TRACE_LEN);
2617 	}
2618 	QDIO_DBF_TEXT2(0,trace,"delytrgt");
2619 	QDIO_DBF_HEX2(0,trace,&delay_target,sizeof(unsigned long));
2620 	result=0;
2621 out:
2622 	spin_unlock_irqrestore(&chsc_area_lock,flags);
2623 	return result;
2624 }
2625 
qdio_cleanup(int irq,int how)2626 int qdio_cleanup(int irq,int how)
2627 {
2628 	qdio_irq_t *irq_ptr;
2629 	int i,result;
2630 	int do_an_irqrestore=0;
2631 	unsigned long flags;
2632 	int timeout;
2633 	char dbf_text[15];
2634 
2635 	result=0;
2636 	sprintf(dbf_text,"qcln%4x",irq);
2637 	QDIO_DBF_TEXT1(0,trace,dbf_text);
2638 	QDIO_DBF_TEXT0(0,setup,dbf_text);
2639 
2640 	irq_ptr=qdio_get_irq_ptr(irq);
2641 	if (!irq_ptr) return -ENODEV;
2642 
2643 	down(&irq_ptr->setting_up_lock);
2644 
2645 	/* mark all qs as uninteresting */
2646 	for (i=0;i<irq_ptr->no_input_qs;i++) {
2647 		atomic_set(&irq_ptr->input_qs[i]->is_in_shutdown,1);
2648 	}
2649 	for (i=0;i<irq_ptr->no_output_qs;i++) {
2650 		atomic_set(&irq_ptr->output_qs[i]->is_in_shutdown,1);
2651 	}
2652 
2653 	tasklet_kill(&tiqdio_tasklet);
2654 
2655 	for (i=0;i<irq_ptr->no_input_qs;i++) {
2656 		qdio_unmark_q(irq_ptr->input_qs[i]);
2657 		tasklet_kill(&irq_ptr->input_qs[i]->tasklet);
2658 		if (qdio_wait_for_no_use_count(&irq_ptr->input_qs[i]->
2659 					       use_count))
2660 			result=-EINPROGRESS;
2661 	}
2662 
2663 	for (i=0;i<irq_ptr->no_output_qs;i++) {
2664 		tasklet_kill(&irq_ptr->output_qs[i]->tasklet);
2665 		if (qdio_wait_for_no_use_count(&irq_ptr->output_qs[i]->
2666 					       use_count))
2667 			result=-EINPROGRESS;
2668 	}
2669 
2670 	atomic_set(&irq_ptr->interrupt_has_been_cleaned,0);
2671 
2672 	/* cleanup subchannel */
2673 	s390irq_spin_lock_irqsave(irq,flags);
2674 	if (how&QDIO_FLAG_CLEANUP_USING_CLEAR) {
2675 		clear_IO(irq_ptr->irq,QDIO_DOING_CLEANUP,0);
2676 		timeout=QDIO_CLEANUP_CLEAR_TIMEOUT;
2677 	} else if (how&QDIO_FLAG_CLEANUP_USING_HALT) {
2678 		halt_IO(irq_ptr->irq,QDIO_DOING_CLEANUP,0);
2679 		timeout=QDIO_CLEANUP_HALT_TIMEOUT;
2680 	} else { /* default behaviour */
2681 		halt_IO(irq_ptr->irq,QDIO_DOING_CLEANUP,0);
2682 		timeout=QDIO_CLEANUP_HALT_TIMEOUT;
2683 	}
2684 	s390irq_spin_unlock_irqrestore(irq,flags);
2685 
2686 	if (qdio_sleepon(&irq_ptr->interrupt_has_been_cleaned,
2687 			 timeout,irq_ptr)==-ETIME) {
2688 		s390irq_spin_lock_irqsave(irq,flags);
2689 		QDIO_PRINT_INFO("Did not get interrupt on %s_IO, " \
2690 				"irq=0x%x.\n",
2691 				(how==QDIO_FLAG_CLEANUP_USING_CLEAR)?
2692 				"clear":"halt",irq);
2693 		do_an_irqrestore=1;
2694 	}
2695 
2696 	if (irq_ptr->is_thinint_irq) {
2697 		qdio_put_indicator((__u32*)irq_ptr->dev_st_chg_ind);
2698 		tiqdio_set_subchannel_ind(irq_ptr,1); /* reset adapter
2699 							interrupt indicators */
2700 	}
2701 
2702 	/* exchange int handlers, if necessary */
2703 	if ((void*)ioinfo[irq]->irq_desc.handler
2704 	    ==(void*)qdio_handler) {
2705 		ioinfo[irq]->irq_desc.handler=
2706 			irq_ptr->original_int_handler;
2707 /*		irq_ptr->original_int_handler=NULL; */
2708 	}
2709 
2710 	qdio_set_state(irq_ptr,QDIO_IRQ_STATE_INACTIVE);
2711 
2712 	if (do_an_irqrestore)
2713 		s390irq_spin_unlock_irqrestore(irq,flags);
2714 
2715 	up(&irq_ptr->setting_up_lock);
2716 
2717 	qdio_remove_irq_ptr(irq_ptr);
2718 	qdio_release_irq_memory(irq_ptr);
2719 
2720 	QDIO_DBF_TEXT3(0,setup,"MOD_DEC_");
2721 	MOD_DEC_USE_COUNT;
2722 
2723 	return result;
2724 }
2725 
qdio_get_characteristics(int irq)2726 unsigned long qdio_get_characteristics(int irq)
2727 {
2728 	qdio_irq_t *irq_ptr;
2729 	int result=0;
2730 
2731 	irq_ptr=qdio_get_irq_ptr(irq);
2732 	if (!irq_ptr) return -ENODEV;
2733 
2734 	if (irq_ptr->state!=QDIO_IRQ_STATE_ACTIVE) {
2735 		return -EBUSY;
2736 	}
2737 
2738 	if (irq_ptr->state==QDIO_IRQ_STATE_INACTIVE) {
2739 		result|=QDIO_STATE_INACTIVE;
2740 	} else if (irq_ptr->state==QDIO_IRQ_STATE_ESTABLISHED) {
2741 		result|=QDIO_STATE_ESTABLISHED;
2742 	} else if (irq_ptr->state==QDIO_IRQ_STATE_ACTIVE) {
2743 		result|=QDIO_STATE_ACTIVE;
2744 	} else if (irq_ptr->state==QDIO_IRQ_STATE_STOPPED) {
2745 		result|=QDIO_STATE_STOPPED;
2746 	}
2747 
2748 	if (irq_ptr->hydra_gives_outbound_pcis)
2749 		result|=QDIO_STATE_MUST_USE_OUTB_PCI;
2750 
2751 	return result;
2752 }
2753 
qdio_initialize(qdio_initialize_t * init_data)2754 int qdio_initialize(qdio_initialize_t *init_data)
2755 {
2756 	int i,ciw_cnt;
2757 	unsigned long saveflags;
2758 	qdio_irq_t *irq_ptr=NULL;
2759 	int result,result2;
2760 	int found;
2761 	unsigned long flags;
2762 	char dbf_text[20]; /* if a printf printed out more than 8 chars */
2763 
2764 	down(&init_sema);
2765 
2766 	sprintf(dbf_text,"qini%4x",init_data->irq);
2767 	QDIO_DBF_TEXT0(0,setup,dbf_text);
2768 	QDIO_DBF_TEXT0(0,trace,dbf_text);
2769 	sprintf(dbf_text,"qfmt:%x",init_data->q_format);
2770 	QDIO_DBF_TEXT0(0,setup,dbf_text);
2771 	QDIO_DBF_HEX0(0,setup,init_data->adapter_name,8);
2772 	sprintf(dbf_text,"qpff%4x",init_data->qib_param_field_format);
2773 	QDIO_DBF_TEXT0(0,setup,dbf_text);
2774 	QDIO_DBF_HEX0(0,setup,&init_data->qib_param_field,sizeof(char*));
2775 	QDIO_DBF_HEX0(0,setup,&init_data->input_slib_elements,sizeof(long*));
2776 	QDIO_DBF_HEX0(0,setup,&init_data->output_slib_elements,sizeof(long*));
2777 	sprintf(dbf_text,"miit%4x",init_data->min_input_threshold);
2778 	QDIO_DBF_TEXT0(0,setup,dbf_text);
2779 	sprintf(dbf_text,"mait%4x",init_data->min_input_threshold);
2780 	QDIO_DBF_TEXT0(0,setup,dbf_text);
2781 	sprintf(dbf_text,"miot%4x",init_data->max_output_threshold);
2782 	QDIO_DBF_TEXT0(0,setup,dbf_text);
2783 	sprintf(dbf_text,"maot%4x",init_data->max_output_threshold);
2784 	QDIO_DBF_TEXT0(0,setup,dbf_text);
2785 	sprintf(dbf_text,"niq:%4x",init_data->no_input_qs);
2786 	QDIO_DBF_TEXT0(0,setup,dbf_text);
2787 	sprintf(dbf_text,"noq:%4x",init_data->no_output_qs);
2788 	QDIO_DBF_TEXT0(0,setup,dbf_text);
2789 	QDIO_DBF_HEX0(0,setup,&init_data->input_handler,sizeof(void*));
2790 	QDIO_DBF_HEX0(0,setup,&init_data->output_handler,sizeof(void*));
2791 	QDIO_DBF_HEX0(0,setup,&init_data->int_parm,sizeof(long));
2792 	QDIO_DBF_HEX0(0,setup,&init_data->flags,sizeof(long));
2793 	QDIO_DBF_HEX0(0,setup,&init_data->input_sbal_addr_array,sizeof(void*));
2794 	QDIO_DBF_HEX0(0,setup,&init_data->output_sbal_addr_array,sizeof(void*));
2795 	flags=init_data->flags;
2796 
2797 	/* sanity checks */
2798 	if (qdio_get_irq_ptr(init_data->irq)) {
2799 		result=-EBUSY;
2800 		goto out;
2801 	}
2802 
2803 	if (ioinfo[init_data->irq]==INVALID_STORAGE_AREA) {
2804 		result=-ENODEV;
2805 		goto out;
2806 	}
2807 
2808 	if (!ioinfo[init_data->irq]) {
2809 		QDIO_PRINT_WARN("ioinfo[%i] is NULL!\n",init_data->irq);
2810 		result=-ENODEV;
2811 		goto out;
2812 	}
2813 
2814 #define DEVSTAT_FLAG_IRQ_QDIO ~0UL
2815 	if (!(ioinfo[init_data->irq]->devstat.flag&DEVSTAT_FLAG_IRQ_QDIO)) {
2816 		QDIO_PRINT_WARN("ioinfo[%i]->devstat.flag=0x%08x\n",
2817 				init_data->irq,
2818 				ioinfo[init_data->irq]->devstat.flag);
2819 		result=-ENODEV;
2820 		goto out;
2821 	}
2822 
2823 	if ( (init_data->no_input_qs>QDIO_MAX_QUEUES_PER_IRQ) ||
2824 	     (init_data->no_output_qs>QDIO_MAX_QUEUES_PER_IRQ) ||
2825 	     ((init_data->no_input_qs) && (!init_data->input_handler)) ||
2826 	     ((init_data->no_output_qs) && (!init_data->output_handler)) ) {
2827 		result=-EINVAL;
2828 		goto out;
2829 	}
2830 
2831 	if ( (init_data->flags&QDIO_INBOUND_0COPY_SBALS)&&
2832 	     (!init_data->input_sbal_addr_array) ) {
2833 		result=-EINVAL;
2834 		goto out;
2835 	}
2836 	if ( (init_data->flags&QDIO_OUTBOUND_0COPY_SBALS)&&
2837 	     (!init_data->output_sbal_addr_array) ) {
2838 		result=-EINVAL;
2839 		goto out;
2840 	}
2841 
2842 	/* create irq */
2843 	irq_ptr=kmalloc(sizeof(qdio_irq_t),GFP_DMA);
2844 
2845 	QDIO_DBF_TEXT0(0,setup,"irq_ptr:");
2846 	QDIO_DBF_HEX0(0,setup,&irq_ptr,sizeof(void*));
2847 
2848 	if (!irq_ptr) {
2849 		QDIO_PRINT_ERR("kmalloc of irq_ptr failed!\n");
2850 		result=-ENOMEM;
2851 		goto out;
2852 	}
2853 
2854 	memset(irq_ptr,0,sizeof(qdio_irq_t)); /* wipes qib.ac,
2855 						 required by ar7063 */
2856 
2857 	irq_ptr->qdr=kmalloc(sizeof(qdr_t),GFP_DMA);
2858   	if (!(irq_ptr->qdr)) {
2859    		kfree(irq_ptr);
2860     		QDIO_PRINT_ERR("kmalloc of irq_ptr->qdr failed!\n");
2861      		result=-ENOMEM;
2862       		goto out;
2863        	}
2864 	memset(irq_ptr->qdr,0,sizeof(qdr_t));
2865 	QDIO_DBF_TEXT0(0,setup,"qdr:");
2866 	QDIO_DBF_HEX0(0,setup,&irq_ptr->qdr,sizeof(void*));
2867 
2868 	init_waitqueue_head(&irq_ptr->wait_q);
2869 
2870 	irq_ptr->int_parm=init_data->int_parm;
2871 
2872 	irq_ptr->irq=init_data->irq;
2873 	irq_ptr->no_input_qs=init_data->no_input_qs;
2874 	irq_ptr->no_output_qs=init_data->no_output_qs;
2875 
2876 	if (init_data->q_format==QDIO_IQDIO_QFMT) {
2877 		irq_ptr->is_iqdio_irq=1;
2878 		irq_ptr->is_thinint_irq=1;
2879 	} else {
2880 		irq_ptr->is_iqdio_irq=0;
2881 		irq_ptr->is_thinint_irq=hydra_thinints;
2882 	}
2883 	sprintf(dbf_text,"is_i_t%1x%1x",
2884 		irq_ptr->is_iqdio_irq,irq_ptr->is_thinint_irq);
2885 	QDIO_DBF_TEXT2(0,setup,dbf_text);
2886 
2887 	if (irq_ptr->is_thinint_irq) {
2888 		irq_ptr->dev_st_chg_ind=qdio_get_indicator();
2889 		QDIO_DBF_HEX1(0,setup,&irq_ptr->dev_st_chg_ind,sizeof(void*));
2890 		if (!irq_ptr->dev_st_chg_ind) {
2891 			QDIO_PRINT_WARN("no indicator location available " \
2892 					"for irq 0x%x\n",irq_ptr->irq);
2893 			qdio_release_irq_memory(irq_ptr);
2894 			result=-ENOBUFS;
2895 			goto out;
2896 		}
2897 	}
2898 
2899 	if (flags&QDIO_PFIX)
2900 		irq_ptr->other_flags |= QDIO_PFIX;
2901 
2902 	/* defaults */
2903 	irq_ptr->commands.eq=DEFAULT_ESTABLISH_QS_CMD;
2904 	irq_ptr->commands.count_eq=DEFAULT_ESTABLISH_QS_COUNT;
2905 	irq_ptr->commands.aq=DEFAULT_ACTIVATE_QS_CMD;
2906 	irq_ptr->commands.count_aq=DEFAULT_ACTIVATE_QS_COUNT;
2907 
2908 	if (!qdio_alloc_qs(irq_ptr,init_data->no_input_qs,
2909 			   init_data->no_output_qs,
2910 			   init_data->input_handler,
2911 			   init_data->output_handler,init_data->int_parm,
2912 			   init_data->q_format,init_data->flags,
2913 			   init_data->input_sbal_addr_array,
2914 			   init_data->output_sbal_addr_array)) {
2915 		qdio_release_irq_memory(irq_ptr);
2916 		result=-ENOMEM;
2917 		goto out;
2918 	}
2919 
2920 	qdio_set_state(irq_ptr,QDIO_IRQ_STATE_INACTIVE);
2921 
2922 	sema_init(&irq_ptr->setting_up_lock,1);
2923 
2924 	MOD_INC_USE_COUNT;
2925 	QDIO_DBF_TEXT3(0,setup,"MOD_INC_");
2926 
2927 	down(&irq_ptr->setting_up_lock);
2928 
2929 	qdio_insert_irq_ptr(irq_ptr);
2930 
2931 	qdio_fill_thresholds(irq_ptr,init_data->no_input_qs,
2932 			     init_data->no_output_qs,
2933 			     init_data->min_input_threshold,
2934 			     init_data->max_input_threshold,
2935 			     init_data->min_output_threshold,
2936 			     init_data->max_output_threshold);
2937 
2938 	/* fill in qdr */
2939 	irq_ptr->qdr->qfmt=init_data->q_format;
2940 	irq_ptr->qdr->iqdcnt=init_data->no_input_qs;
2941 	irq_ptr->qdr->oqdcnt=init_data->no_output_qs;
2942 	irq_ptr->qdr->iqdsz=sizeof(qdesfmt0_t)/4; /* size in words */
2943 	irq_ptr->qdr->oqdsz=sizeof(qdesfmt0_t)/4;
2944 
2945 	irq_ptr->qdr->qiba=QDIO_PFIX_GET_ADDR(&irq_ptr->qib);
2946 	irq_ptr->qdr->qkey=QDIO_STORAGE_ACC_KEY;
2947 
2948 	/* fill in qib */
2949 	irq_ptr->qib.qfmt=init_data->q_format;
2950 	if (init_data->no_input_qs) irq_ptr->qib.isliba=
2951 				 QDIO_PFIX_GET_ADDR(irq_ptr->input_qs[0]->slib);
2952 	if (init_data->no_output_qs) irq_ptr->qib.osliba=(unsigned long)
2953 				  QDIO_PFIX_GET_ADDR(irq_ptr->output_qs[0]->slib);
2954 	memcpy(irq_ptr->qib.ebcnam,init_data->adapter_name,8);
2955 
2956 	qdio_set_impl_params(irq_ptr,init_data->qib_param_field_format,
2957 			     init_data->qib_param_field,
2958 			     init_data->no_input_qs,
2959 			     init_data->no_output_qs,
2960 			     init_data->input_slib_elements,
2961 			     init_data->output_slib_elements);
2962 
2963 	/* first input descriptors, then output descriptors */
2964 	for (i=0;i<init_data->no_input_qs;i++) {
2965 		irq_ptr->input_qs[i]->is_iqdio_q=
2966 			(init_data->q_format==QDIO_IQDIO_QFMT)?1:0;
2967 		irq_ptr->input_qs[i]->is_thinint_q=irq_ptr->is_thinint_irq;
2968 
2969 		irq_ptr->qdr->qdf0[i].sliba=
2970 			QDIO_PFIX_GET_ADDR(irq_ptr->input_qs[i]->slib);
2971 
2972 		irq_ptr->qdr->qdf0[i].sla=
2973 			QDIO_PFIX_GET_ADDR(irq_ptr->input_qs[i]->sl);
2974 
2975 		irq_ptr->qdr->qdf0[i].slsba=
2976 			QDIO_PFIX_GET_ADDR
2977 			((void *)&irq_ptr->input_qs[i]->slsb.acc.val[0]);
2978 
2979 		irq_ptr->qdr->qdf0[i].akey=QDIO_STORAGE_ACC_KEY;
2980 		irq_ptr->qdr->qdf0[i].bkey=QDIO_STORAGE_ACC_KEY;
2981 		irq_ptr->qdr->qdf0[i].ckey=QDIO_STORAGE_ACC_KEY;
2982 		irq_ptr->qdr->qdf0[i].dkey=QDIO_STORAGE_ACC_KEY;
2983 	}
2984 
2985 	for (i=0;i<init_data->no_output_qs;i++) {
2986 		irq_ptr->output_qs[i]->is_iqdio_q=
2987 			(init_data->q_format==QDIO_IQDIO_QFMT)?1:0;
2988 		irq_ptr->output_qs[i]->is_thinint_q=irq_ptr->is_thinint_irq;
2989 
2990 		irq_ptr->qdr->qdf0[i+init_data->no_input_qs].sliba=
2991 			QDIO_PFIX_GET_ADDR(irq_ptr->output_qs[i]->slib);
2992 
2993 		irq_ptr->qdr->qdf0[i+init_data->no_input_qs].sla=
2994 			QDIO_PFIX_GET_ADDR(irq_ptr->output_qs[i]->sl);
2995 
2996 		irq_ptr->qdr->qdf0[i+init_data->no_input_qs].slsba=
2997 			QDIO_PFIX_GET_ADDR
2998 			((void *)&irq_ptr->output_qs[i]->slsb.acc.val[0]);
2999 
3000 		irq_ptr->qdr->qdf0[i+init_data->no_input_qs].akey=
3001 			QDIO_STORAGE_ACC_KEY;
3002 		irq_ptr->qdr->qdf0[i+init_data->no_input_qs].bkey=
3003 			QDIO_STORAGE_ACC_KEY;
3004 		irq_ptr->qdr->qdf0[i+init_data->no_input_qs].ckey=
3005 			QDIO_STORAGE_ACC_KEY;
3006 		irq_ptr->qdr->qdf0[i+init_data->no_input_qs].dkey=
3007 			QDIO_STORAGE_ACC_KEY;
3008 	}
3009 	/* qdr, qib, sls, slsbs, slibs, sbales filled. */
3010 
3011 	s390irq_spin_lock_irqsave(irq_ptr->irq,saveflags);
3012 	/* keep track of original int handler */
3013 	irq_ptr->original_int_handler=ioinfo[irq_ptr->irq]->irq_desc.handler;
3014 
3015 	/* insert qdio int handler */
3016 	ioinfo[irq_ptr->irq]->irq_desc.handler=(void*)qdio_handler;
3017 
3018 	s390irq_spin_unlock_irqrestore(irq_ptr->irq,saveflags);
3019 
3020 #define TAKEOVER_CIW(x) irq_ptr->commands.x=ioinfo[irq_ptr->irq]->senseid.ciw[ciw_cnt].cmd; irq_ptr->commands.count_##x=ioinfo[irq_ptr->irq]->senseid.ciw[ciw_cnt].count
3021 	/* get qdio commands */
3022 	found=0;
3023 	for (ciw_cnt=0;ciw_cnt<MAX_CIWS;ciw_cnt++) {
3024 		switch (ioinfo[irq_ptr->irq]->senseid.ciw[ciw_cnt].ct) {
3025 		case CIW_TYPE_RCD: TAKEOVER_CIW(rcd); break;
3026 		case CIW_TYPE_SII: TAKEOVER_CIW(sii); break;
3027 		case CIW_TYPE_RNI: TAKEOVER_CIW(rni); break;
3028 		case CIW_TYPE_EQUEUE: TAKEOVER_CIW(eq); found++; break;
3029 		case CIW_TYPE_AQUEUE: TAKEOVER_CIW(aq); found++; break;
3030 		}
3031 		if ( (ciw_cnt>0) &&
3032 		     (ioinfo[irq_ptr->irq]->senseid.ciw[ciw_cnt].ct==0) &&
3033 		     (ioinfo[irq_ptr->irq]->senseid.ciw[ciw_cnt].cmd==0) &&
3034 		     (ioinfo[irq_ptr->irq]->senseid.ciw[ciw_cnt].count) )
3035 			break;
3036 	}
3037 	if (found<2) {
3038 		QDIO_DBF_TEXT2(1,setup,"no ciws");
3039 		QDIO_PRINT_INFO("No CIWs found for QDIO commands. Trying to " \
3040 				"use defaults.\n");
3041 	}
3042 
3043 	/* the thinint CHSC stuff */
3044 	if (irq_ptr->is_thinint_irq) {
3045 /*		iqdio_enable_adapter_int_facility(irq_ptr);*/
3046 
3047 		if (tiqdio_check_chsc_availability()) {
3048 			QDIO_PRINT_ERR("Not all CHSCs supported. " \
3049 				       "Continuing.\n");
3050 		}
3051 		result=tiqdio_set_subchannel_ind(irq_ptr,0);
3052 		if (result) {
3053 			up(&irq_ptr->setting_up_lock);
3054 			qdio_cleanup(irq_ptr->irq,
3055 				     QDIO_FLAG_CLEANUP_USING_CLEAR);
3056 			goto out;
3057 		}
3058 		tiqdio_set_delay_target(irq_ptr,TIQDIO_DELAY_TARGET);
3059 	}
3060 
3061 	/* establish q */
3062 	irq_ptr->ccw.cmd_code=irq_ptr->commands.eq;
3063 	irq_ptr->ccw.flags=CCW_FLAG_SLI;
3064 	irq_ptr->ccw.count=irq_ptr->commands.count_eq;
3065 	irq_ptr->ccw.cda=QDIO_GET_32BIT_ADDR(QDIO_PFIX_GET_ADDR(irq_ptr->qdr));
3066 
3067 	s390irq_spin_lock_irqsave(irq_ptr->irq,saveflags);
3068 	atomic_set(&irq_ptr->interrupt_has_arrived,0);
3069 
3070 	result=do_IO(irq_ptr->irq,&irq_ptr->ccw,QDIO_DOING_ESTABLISH,0,
3071 		     ((irq_ptr->other_flags&QDIO_PFIX)?DOIO_USE_DIAG98:0));
3072 	if (result) {
3073 		result2=do_IO(irq_ptr->irq,&irq_ptr->ccw,
3074 			      QDIO_DOING_ESTABLISH,0,
3075 			      ((irq_ptr->other_flags&QDIO_PFIX)?
3076 			       DOIO_USE_DIAG98:0));
3077 		sprintf(dbf_text,"eq:io%4x",result);
3078 		QDIO_DBF_TEXT2(1,setup,dbf_text);
3079 		if (result2) {
3080 			sprintf(dbf_text,"eq:io%4x",result);
3081 			QDIO_DBF_TEXT2(1,setup,dbf_text);
3082 		}
3083 		QDIO_PRINT_WARN("establish queues on irq %04x: do_IO " \
3084                            "returned %i, next try returned %i\n",
3085                            irq_ptr->irq,result,result2);
3086 		result=result2;
3087 	}
3088 
3089 	s390irq_spin_unlock_irqrestore(irq_ptr->irq,saveflags);
3090 
3091 	if (result) {
3092 		up(&irq_ptr->setting_up_lock);
3093 		qdio_cleanup(irq_ptr->irq,QDIO_FLAG_CLEANUP_USING_CLEAR);
3094 		goto out;
3095 	}
3096 
3097 	result=qdio_sleepon(&irq_ptr->interrupt_has_arrived,
3098 			    QDIO_ESTABLISH_TIMEOUT,irq_ptr);
3099 
3100 	if (result) {
3101 		QDIO_PRINT_ERR("establish queues on irq %04x: timed out\n",
3102 			   irq_ptr->irq);
3103 		QDIO_DBF_TEXT2(1,setup,"eq:timeo");
3104 		up(&irq_ptr->setting_up_lock);
3105 		qdio_cleanup(irq_ptr->irq,QDIO_FLAG_CLEANUP_USING_CLEAR);
3106 		goto out;
3107 	}
3108 
3109 	if (!(irq_ptr->io_result_dstat & DEV_STAT_DEV_END)) {
3110 		QDIO_DBF_TEXT2(1,setup,"eq:no de");
3111 		QDIO_DBF_HEX2(0,setup,&irq_ptr->io_result_dstat,
3112 			      sizeof(irq_ptr->io_result_dstat));
3113 		QDIO_DBF_HEX2(0,setup,&irq_ptr->io_result_cstat,
3114 			      sizeof(irq_ptr->io_result_cstat));
3115 		QDIO_DBF_HEX2(0,setup,&irq_ptr->io_result_flags,
3116 			      sizeof(irq_ptr->io_result_flags));
3117 		QDIO_PRINT_ERR("establish queues on irq %04x: didn't get " \
3118 			       "device end: dstat=%02x, cstat=%02x, " \
3119 			       "flags=%02x\n",
3120 			       irq_ptr->irq,irq_ptr->io_result_dstat,
3121 			       irq_ptr->io_result_cstat,
3122 			       irq_ptr->io_result_flags);
3123 		up(&irq_ptr->setting_up_lock);
3124 		qdio_cleanup(irq_ptr->irq,QDIO_FLAG_CLEANUP_USING_CLEAR);
3125 		result=-EIO;
3126 		goto out;
3127 	}
3128 
3129 	if (irq_ptr->io_result_dstat & ~(DEV_STAT_CHN_END|DEV_STAT_DEV_END)) {
3130 		QDIO_DBF_TEXT2(1,setup,"eq:badio");
3131 		QDIO_DBF_HEX2(0,setup,&irq_ptr->io_result_dstat,
3132 			      sizeof(irq_ptr->io_result_dstat));
3133 		QDIO_DBF_HEX2(0,setup,&irq_ptr->io_result_cstat,
3134 			      sizeof(irq_ptr->io_result_cstat));
3135 		QDIO_DBF_HEX2(0,setup,&irq_ptr->io_result_flags,
3136 			      sizeof(irq_ptr->io_result_flags));
3137 		QDIO_PRINT_ERR("establish queues on irq %04x: got " \
3138 			       "the following devstat: dstat=%02x, " \
3139 			       "cstat=%02x, flags=%02x\n",
3140 			       irq_ptr->irq,irq_ptr->io_result_dstat,
3141 			       irq_ptr->io_result_cstat,
3142 			       irq_ptr->io_result_flags);
3143 		result=-EIO;
3144 		up(&irq_ptr->setting_up_lock);
3145 		goto out;
3146 	}
3147 
3148 		irq_ptr->qdioac=qdio_check_siga_needs(irq_ptr->irq);
3149 	sprintf(dbf_text,"qdioac%2x",irq_ptr->qdioac);
3150 	QDIO_DBF_TEXT2(0,setup,dbf_text);
3151 
3152 	/* if this gets set once, we're running under VM and can omit SVSes */
3153 	if (irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_NECESSARY) {
3154 		omit_svs=1;
3155 	}
3156 
3157 	sprintf(dbf_text,"qib ac%2x",irq_ptr->qib.ac);
3158 	QDIO_DBF_TEXT2(0,setup,dbf_text);
3159 
3160 	if (init_data->flags&QDIO_USE_OUTBOUND_PCIS) {
3161 		irq_ptr->hydra_gives_outbound_pcis=
3162 			irq_ptr->qib.ac&QIB_AC_OUTBOUND_PCI_SUPPORTED;
3163 	} else {
3164 		irq_ptr->hydra_gives_outbound_pcis=0;
3165 	}
3166 	irq_ptr->sync_done_on_outb_pcis=
3167 		irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS;
3168 
3169 	for (i=0;i<init_data->no_input_qs;i++) {
3170 		irq_ptr->input_qs[i]->siga_sync=
3171 			irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_NECESSARY;
3172 		irq_ptr->input_qs[i]->siga_in=
3173 			irq_ptr->qdioac&CHSC_FLAG_SIGA_INPUT_NECESSARY;
3174 		irq_ptr->input_qs[i]->siga_out=
3175 			irq_ptr->qdioac&CHSC_FLAG_SIGA_OUTPUT_NECESSARY;
3176 		irq_ptr->input_qs[i]->siga_sync_done_on_thinints=
3177 			irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS;
3178 		irq_ptr->input_qs[i]->hydra_gives_outbound_pcis=
3179 			irq_ptr->hydra_gives_outbound_pcis;
3180 		irq_ptr->input_qs[i]->siga_sync_done_on_outb_tis=
3181 			( (irq_ptr->qdioac&
3182 			   (CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS|
3183 			    CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS))==
3184 			  (CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS|
3185 			   CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS) );
3186 	}
3187 
3188 	for (i=0;i<init_data->no_output_qs;i++) {
3189 		irq_ptr->output_qs[i]->siga_sync=
3190 			irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_NECESSARY;
3191 		irq_ptr->output_qs[i]->siga_in=
3192 			irq_ptr->qdioac&CHSC_FLAG_SIGA_INPUT_NECESSARY;
3193 		irq_ptr->output_qs[i]->siga_out=
3194 			irq_ptr->qdioac&CHSC_FLAG_SIGA_OUTPUT_NECESSARY;
3195 		irq_ptr->output_qs[i]->siga_sync_done_on_thinints=
3196 			irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS;
3197 		irq_ptr->output_qs[i]->hydra_gives_outbound_pcis=
3198 			irq_ptr->hydra_gives_outbound_pcis;
3199 		irq_ptr->output_qs[i]->siga_sync_done_on_outb_tis=
3200 			( (irq_ptr->qdioac&
3201 			   (CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS|
3202 			    CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS))==
3203 			  (CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS|
3204 			   CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS) );
3205 	}
3206 
3207 	if (init_data->qib_param_field)
3208 		memcpy(init_data->qib_param_field,irq_ptr->qib.parm,
3209 		       QDIO_MAX_BUFFERS_PER_Q);
3210 
3211 	qdio_set_state(irq_ptr,QDIO_IRQ_STATE_ESTABLISHED);
3212 
3213 	if (irq_ptr) {
3214 		up(&irq_ptr->setting_up_lock);
3215 	}
3216  out:
3217 	up(&init_sema);
3218 
3219 	return result;
3220 }
3221 
qdio_activate(int irq,int flags)3222 int qdio_activate(int irq,int flags)
3223 {
3224 	qdio_irq_t *irq_ptr;
3225 	int i,result=0,result2;
3226 	unsigned long saveflags;
3227 	char dbf_text[20]; /* see qdio_initialize */
3228 
3229 	irq_ptr=qdio_get_irq_ptr(irq);
3230 	if (!irq_ptr) return -ENODEV;
3231 
3232 	down(&irq_ptr->setting_up_lock);
3233 	if (irq_ptr->state==QDIO_IRQ_STATE_INACTIVE) {
3234 		result=-EBUSY;
3235 		goto out;
3236 	}
3237 
3238 	sprintf(dbf_text,"qact%4x",irq);
3239 	QDIO_DBF_TEXT2(0,setup,dbf_text);
3240 	QDIO_DBF_TEXT2(0,trace,dbf_text);
3241 
3242 	/* activate q */
3243 	irq_ptr->ccw.cmd_code=irq_ptr->commands.aq;
3244 	irq_ptr->ccw.flags=CCW_FLAG_SLI;
3245 	irq_ptr->ccw.count=irq_ptr->commands.count_aq;
3246 	irq_ptr->ccw.cda=QDIO_GET_32BIT_ADDR(0); /* no QDIO_PFIX_GET_ADDR here,
3247 						    not needed */
3248 
3249 	s390irq_spin_lock_irqsave(irq_ptr->irq,saveflags);
3250 	atomic_set(&irq_ptr->interrupt_has_arrived,0);
3251 
3252 	result=do_IO(irq_ptr->irq,&irq_ptr->ccw,QDIO_DOING_ACTIVATE,
3253 		     0,DOIO_REPORT_ALL|DOIO_DENY_PREFETCH|
3254 		     ((irq_ptr->other_flags&QDIO_PFIX)?DOIO_USE_DIAG98:0));
3255 	if (result) {
3256 		result2=do_IO(irq_ptr->irq,&irq_ptr->ccw,
3257 			      QDIO_DOING_ACTIVATE,0,DOIO_REPORT_ALL|
3258 			      ((irq_ptr->other_flags&QDIO_PFIX) ?
3259 			       DOIO_USE_DIAG98:0));
3260 		sprintf(dbf_text,"aq:io%4x",result);
3261 		QDIO_DBF_TEXT2(1,setup,dbf_text);
3262 		if (result2) {
3263 			sprintf(dbf_text,"aq:io%4x",result);
3264 			QDIO_DBF_TEXT2(1,setup,dbf_text);
3265 		}
3266 		QDIO_PRINT_WARN("activate queues on irq %04x: do_IO " \
3267                            "returned %i, next try returned %i\n",
3268                            irq_ptr->irq,result,result2);
3269 		result=result2;
3270 	}
3271 
3272 	s390irq_spin_unlock_irqrestore(irq_ptr->irq,saveflags);
3273 	if (result) {
3274 		goto out;
3275 	}
3276 
3277 	if (!(flags&QDIO_FLAG_UNDER_INTERRUPT)) {
3278 		result=qdio_sleepon(&irq_ptr->interrupt_has_arrived,
3279 				    QDIO_ACTIVATE_TIMEOUT,irq_ptr);
3280 
3281 		if (result!=-ETIME) {
3282 			QDIO_DBF_TEXT2(1,setup,"aq:badio");
3283 			QDIO_DBF_HEX2(0,setup,&irq_ptr->io_result_dstat,
3284 				      sizeof(irq_ptr->io_result_dstat));
3285 			QDIO_DBF_HEX2(0,setup,&irq_ptr->io_result_cstat,
3286 				      sizeof(irq_ptr->io_result_cstat));
3287 			QDIO_DBF_HEX2(0,setup,&irq_ptr->io_result_flags,
3288 				      sizeof(irq_ptr->io_result_flags));
3289 			QDIO_PRINT_ERR("activate queues on irq %04x: got " \
3290 				       "the following devstat: dstat=%02x, " \
3291 				       "cstat=%02x, flags=%02x\n",
3292 				       irq_ptr->irq,irq_ptr->io_result_dstat,
3293 				       irq_ptr->io_result_cstat,
3294 				       irq_ptr->io_result_flags);
3295 			result=-EIO;
3296 			goto out;
3297 		} else { /* result is -ETIME, but timeout is ok for us */
3298 			result=0;
3299 		}
3300 	} else result=0;
3301 
3302 	for (i=0;i<irq_ptr->no_input_qs;i++) {
3303 		if (irq_ptr->is_thinint_irq) {
3304 			/* that way we know, that, if we will
3305 			 * get interrupted
3306 			 * by tiqdio_inbound_processing,
3307 			 * qdio_unmark_q will
3308 			 * not be called */
3309 			qdio_reserve_q(irq_ptr->input_qs[i]);
3310 			qdio_mark_tiq(irq_ptr->input_qs[i]);
3311 			qdio_release_q(irq_ptr->input_qs[i]);
3312 		}
3313 	}
3314 
3315 	if (flags&QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT) {
3316 		for (i=0;i<irq_ptr->no_input_qs;i++) {
3317 			irq_ptr->input_qs[i]->is_input_q|=
3318 				QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT;
3319 		}
3320 	}
3321 
3322 	qdio_wait_nonbusy(QDIO_ACTIVATE_DELAY);
3323 
3324 	qdio_set_state(irq_ptr,QDIO_IRQ_STATE_ACTIVE);
3325 
3326  out:
3327 	up(&irq_ptr->setting_up_lock);
3328 
3329 	return result;
3330 }
3331 
3332 /* buffers filled forwards again to make Rick happy */
qdio_do_qdio_fill_input(qdio_q_t * q,unsigned int qidx,unsigned int count,qdio_buffer_t * buffers)3333 static inline void qdio_do_qdio_fill_input(qdio_q_t *q,unsigned int qidx,
3334 	       				   unsigned int count,
3335 					   qdio_buffer_t *buffers)
3336 {
3337 	for (;;) {
3338 		if (!q->is_0copy_sbals_q) {
3339 			memcpy((void*)q->sbal[qidx],buffers,SBAL_SIZE);
3340 			q->qdio_buffers[qidx]=buffers;
3341 			buffers++;
3342 		}
3343 		set_slsb(&q->slsb.acc.val[qidx],SLSB_CU_INPUT_EMPTY);
3344 		count--;
3345 		if (!count) break;
3346 		qidx=(qidx+1)&(QDIO_MAX_BUFFERS_PER_Q-1);
3347 	}
3348 
3349 	/* not necessary, as the queues are synced during the SIGA read
3350 	SYNC_MEMORY;*/
3351 }
3352 
qdio_do_qdio_fill_output(qdio_q_t * q,unsigned int qidx,unsigned int count,qdio_buffer_t * buffers)3353 static inline void qdio_do_qdio_fill_output(qdio_q_t *q,unsigned int qidx,
3354 					    unsigned int count,
3355 					    qdio_buffer_t *buffers)
3356 {
3357 	for (;;) {
3358 		if (!q->is_0copy_sbals_q) {
3359 			memcpy((void*)q->sbal[qidx],buffers,SBAL_SIZE);
3360 			q->qdio_buffers[qidx]=buffers;
3361 			buffers++;
3362 		}
3363 		set_slsb(&q->slsb.acc.val[qidx],SLSB_CU_OUTPUT_PRIMED);
3364 		count--;
3365 		if (!count) break;
3366 		qidx=(qidx+1)&(QDIO_MAX_BUFFERS_PER_Q-1);
3367 	}
3368 
3369 	/* SIGA write will sync the queues
3370 	SYNC_MEMORY;*/
3371 }
3372 
3373 /* count must be 1 in iqdio */
do_QDIO(int irq,unsigned int callflags,unsigned int queue_number,unsigned int qidx,unsigned int count,qdio_buffer_t * buffers)3374 int do_QDIO(int irq,unsigned int callflags,unsigned int queue_number,
3375 	    unsigned int qidx,unsigned int count,qdio_buffer_t *buffers)
3376 {
3377 	qdio_q_t *q;
3378 	qdio_irq_t *irq_ptr;
3379 	int result;
3380 	int used_elements;
3381 
3382 #ifdef QDIO_DBF_LIKE_HELL
3383 	char dbf_text[20];
3384 
3385 	sprintf(dbf_text,"doQD%04x",irq);
3386 	QDIO_DBF_TEXT3(0,trace,dbf_text);
3387 #endif /* QDIO_DBF_LIKE_HELL */
3388 
3389 	if ( (qidx>QDIO_MAX_BUFFERS_PER_Q) ||
3390 	     (count>QDIO_MAX_BUFFERS_PER_Q) ||
3391 	     (queue_number>QDIO_MAX_QUEUES_PER_IRQ) )
3392 		return -EINVAL;
3393 
3394 	if (count==0) return 0;
3395 
3396 	irq_ptr=qdio_get_irq_ptr(irq);
3397 	if (!irq_ptr) return -ENODEV;
3398 
3399 #ifdef QDIO_DBF_LIKE_HELL
3400 	if (callflags&QDIO_FLAG_SYNC_INPUT)
3401 		QDIO_DBF_HEX3(0,trace,&irq_ptr->input_qs[queue_number],
3402 			      sizeof(void*));
3403 	else
3404 		QDIO_DBF_HEX3(0,trace,&irq_ptr->output_qs[queue_number],
3405 			      sizeof(void*));
3406 	sprintf(dbf_text,"flag%04x",callflags);
3407 	QDIO_DBF_TEXT3(0,trace,dbf_text);
3408 	sprintf(dbf_text,"qi%02xct%02x",qidx,count);
3409 	QDIO_DBF_TEXT3(0,trace,dbf_text);
3410 	if ( ((callflags&QDIO_FLAG_SYNC_INPUT)&&
3411 	      (!irq_ptr->input_qs[queue_number]->is_0copy_sbals_q)) ||
3412 	     ((callflags&QDIO_FLAG_SYNC_OUTPUT)&&
3413 	      (!irq_ptr->output_qs[queue_number]->is_0copy_sbals_q)) )
3414 		QDIO_DBF_HEX5(0,sbal,buffers,256);
3415 #endif /* QDIO_DBF_LIKE_HELL */
3416 
3417 	if (irq_ptr->state!=QDIO_IRQ_STATE_ACTIVE) {
3418 		return -EBUSY;
3419 	}
3420 
3421 	if (callflags&QDIO_FLAG_SYNC_INPUT) {
3422 		/* This is the inbound handling of queues */
3423 		q=irq_ptr->input_qs[queue_number];
3424 
3425 		used_elements=atomic_return_add(count,
3426 						&q->number_of_buffers_used);
3427 
3428 		qdio_do_qdio_fill_input(q,qidx,count,buffers);
3429 
3430 		if ((used_elements+count==QDIO_MAX_BUFFERS_PER_Q)&&
3431 		    (callflags&QDIO_FLAG_UNDER_INTERRUPT))
3432 			atomic_swap(&q->polling,0);
3433 
3434 		if (!used_elements) if (!(callflags&QDIO_FLAG_DONT_SIGA)) {
3435 			if (q->siga_in) {
3436 				result=qdio_siga_input(q);
3437 				if (result) {
3438 					if (q->siga_error)
3439 						q->error_status_flags|=
3440 							QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR;
3441 					q->error_status_flags|=
3442 						QDIO_STATUS_LOOK_FOR_ERROR;
3443 					q->siga_error=result;
3444 				}
3445 			}
3446 
3447 			qdio_mark_q(q);
3448 		}
3449 	} else if (callflags&QDIO_FLAG_SYNC_OUTPUT) {
3450 		/* This is the outbound handling of queues */
3451 #ifdef QDIO_PERFORMANCE_STATS
3452 		perf_stats.start_time_outbound=NOW;
3453 #endif /* QDIO_PERFORMANCE_STATS */
3454 		q=irq_ptr->output_qs[queue_number];
3455 
3456 		qdio_do_qdio_fill_output(q,qidx,count,buffers);
3457 
3458 		used_elements=atomic_return_add(count,
3459 						&q->number_of_buffers_used);
3460 
3461 		if (!(callflags&QDIO_FLAG_DONT_SIGA)) {
3462 			if (q->is_iqdio_q) {
3463 				/* one siga for every sbal */
3464 				while (count--) {
3465 					qdio_kick_outbound_q(q);
3466 				}
3467 
3468 				__qdio_outbound_processing(q);
3469 			} else {
3470 				/* under VM, we do a SIGA sync
3471 				 * unconditionally */
3472 				SYNC_MEMORY;
3473 				else {
3474 					/* w/o shadow queues (else branch of
3475 					 * SYNC_MEMORY :-/ ), we try to
3476 					 * fast-requeue buffers */
3477 					if (q->slsb.acc.val
3478 					    [(qidx+QDIO_MAX_BUFFERS_PER_Q-1)
3479 					    &(QDIO_MAX_BUFFERS_PER_Q-1)]!=
3480 					    SLSB_CU_OUTPUT_PRIMED) {
3481 						qdio_kick_outbound_q(q);
3482 					} else {
3483 #ifdef QDIO_DBF_LIKE_HELL
3484 						QDIO_DBF_TEXT3(0,trace,
3485 							       "fast-req");
3486 #endif /* QDIO_DBF_LIKE_HELL */
3487 #ifdef QDIO_PERFORMANCE_STATS
3488 						perf_stats.fast_reqs++;
3489 #endif /* QDIO_PERFORMANCE_STATS */
3490 					}
3491 				}
3492 				/* only marking the q could take
3493 				 * too long, the upper layer
3494 				 * module could do a lot of
3495 				 * traffic in that time */
3496 				__qdio_outbound_processing(q);
3497 			}
3498 		}
3499 
3500 #ifdef QDIO_PERFORMANCE_STATS
3501 		perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound;
3502 		perf_stats.outbound_cnt++;
3503 #endif /* QDIO_PERFORMANCE_STATS */
3504 	} else {
3505 		QDIO_DBF_TEXT3(1,trace,"doQD:inv");
3506 		return -EINVAL;
3507 	}
3508 	return 0;
3509 }
3510 
3511 #ifdef QDIO_PERFORMANCE_STATS
qdio_perf_procfile_read(char * buffer,char ** buffer_location,off_t offset,int buffer_length,int * eof,void * data)3512 static int qdio_perf_procfile_read(char *buffer,char **buffer_location,
3513        				   off_t offset,int buffer_length,int *eof,
3514 				   void *data)
3515 {
3516         int c=0,bucket;
3517 	qdio_irq_t *irq_ptr;
3518 
3519         /* we are always called with buffer_length=4k, so we all
3520            deliver on the first read */
3521         if (offset>0) return 0;
3522 
3523 #define _OUTP_IT(x...) c+=sprintf(buffer+c,x)
3524 	_OUTP_IT("i_p_nc/c=%lu/%lu\n",i_p_nc,i_p_c);
3525 	_OUTP_IT("ii_p_nc/c=%lu/%lu\n",ii_p_nc,ii_p_c);
3526 	_OUTP_IT("o_p_nc/c=%lu/%lu\n",o_p_nc,o_p_c);
3527 	_OUTP_IT("Number of tasklet runs (total)                  : %u\n",
3528 		 perf_stats.tl_runs);
3529 	_OUTP_IT("\n");
3530 	_OUTP_IT("Number of SIGA sync's issued                    : %u\n",
3531 		 perf_stats.siga_syncs);
3532 	_OUTP_IT("Number of SIGA in's issued                      : %u\n",
3533 		 perf_stats.siga_ins);
3534 	_OUTP_IT("Number of SIGA out's issued                     : %u\n",
3535 		 perf_stats.siga_outs);
3536 	_OUTP_IT("Number of PCIs caught                           : %u\n",
3537 		 perf_stats.pcis);
3538 	_OUTP_IT("Number of adapter interrupts caught             : %u\n",
3539 		 perf_stats.thinints);
3540 	_OUTP_IT("Number of fast requeues (outg. SBALs w/o SIGA)  : %u\n",
3541 		 perf_stats.fast_reqs);
3542 	_OUTP_IT("\n");
3543 	_OUTP_IT("Total time of all inbound actions (us) incl. UL : %u\n",
3544 		 perf_stats.inbound_time);
3545 	_OUTP_IT("Number of inbound transfers                     : %u\n",
3546 		 perf_stats.inbound_cnt);
3547 	_OUTP_IT("Total time of all outbound do_QDIOs (us)        : %u\n",
3548 		 perf_stats.outbound_time);
3549 	_OUTP_IT("Number of do_QDIOs outbound                     : %u\n",
3550 		 perf_stats.outbound_cnt);
3551 	_OUTP_IT("\n");
3552 
3553 	for (bucket=0;bucket<QDIO_IRQ_BUCKETS;bucket++) {
3554 		irq_ptr=first_irq[bucket];
3555 
3556 		while (irq_ptr) {
3557 			_OUTP_IT("Polling time on irq %4x" \
3558 				 "                        : %u\n",
3559 				 irq_ptr->irq,irq_ptr->input_qs[0]->
3560 				 timing.threshold);
3561 			irq_ptr=irq_ptr->next;
3562 		}
3563 	}
3564 
3565         return c;
3566 }
3567 
3568 static struct proc_dir_entry *qdio_perf_proc_file;
3569 #endif /* QDIO_PERFORMANCE_STATS */
3570 
qdio_add_procfs_entry(void)3571 static void qdio_add_procfs_entry(void)
3572 {
3573 #ifdef QDIO_PERFORMANCE_STATS
3574         proc_perf_file_registration=0;
3575 	qdio_perf_proc_file=create_proc_entry(QDIO_PERF,
3576 					      S_IFREG|0444,&proc_root);
3577 	if (qdio_perf_proc_file) {
3578 		qdio_perf_proc_file->read_proc=&qdio_perf_procfile_read;
3579 	} else proc_perf_file_registration=-1;
3580 
3581         if (proc_perf_file_registration)
3582                 QDIO_PRINT_WARN("was not able to register perf. " \
3583 				"proc-file (%i).\n",
3584 				proc_perf_file_registration);
3585 #endif /* QDIO_PERFORMANCE_STATS */
3586 }
3587 #ifdef MODULE
qdio_remove_procfs_entry(void)3588 static void qdio_remove_procfs_entry(void)
3589 {
3590 #ifdef QDIO_PERFORMANCE_STATS
3591 	perf_stats.tl_runs=0;
3592 
3593         if (!proc_perf_file_registration) /* means if it went ok earlier */
3594 		remove_proc_entry(QDIO_PERF,&proc_root);
3595 #endif /* QDIO_PERFORMANCE_STATS */
3596 }
3597 #endif /* MODULE */
3598 
tiqdio_register_thinints(void)3599 static void tiqdio_register_thinints(void)
3600 {
3601 	char dbf_text[20];
3602 	register_thinint_result=
3603 		s390_register_adapter_interrupt(&tiqdio_thinint_handler);
3604 	if (register_thinint_result) {
3605 		sprintf(dbf_text,"regthn%x",(register_thinint_result&0xff));
3606 		QDIO_DBF_TEXT0(0,setup,dbf_text);
3607 		QDIO_PRINT_ERR("failed to register adapter handler " \
3608 			       "(rc=%i).\nAdapter interrupts might " \
3609 			       "not work. Continuing.\n",
3610 			       register_thinint_result);
3611 	}
3612 }
3613 
3614 #ifdef MODULE
tiqdio_unregister_thinints(void)3615 static void tiqdio_unregister_thinints(void)
3616 {
3617 	if (!register_thinint_result)
3618 		s390_unregister_adapter_interrupt(&tiqdio_thinint_handler);
3619 }
3620 #endif /* MODULE */
3621 
qdio_get_qdio_memory(void)3622 static int qdio_get_qdio_memory(void)
3623 {
3624 	int i;
3625 	indicator_used[0]=1;
3626 
3627 	for (i=1;i<INDICATORS_PER_CACHELINE;i++)
3628 		indicator_used[i]=0;
3629 	indicators=(__u32*)kmalloc(sizeof(__u32)*(INDICATORS_PER_CACHELINE),
3630 				   GFP_KERNEL);
3631        	if (!indicators) return -ENOMEM;
3632 	memset(indicators,0,sizeof(__u32)*(INDICATORS_PER_CACHELINE));
3633 
3634 	chsc_area=(qdio_chsc_area_t *)
3635 		kmalloc(sizeof(qdio_chsc_area_t),GFP_KERNEL);
3636 	QDIO_DBF_TEXT3(0,trace,"chscarea"); \
3637 	QDIO_DBF_HEX3(0,trace,&chsc_area,sizeof(void*)); \
3638 	if (!chsc_area) {
3639 		/* ahem... let's call it data area */
3640 		QDIO_PRINT_ERR("not enough memory for data area. Cannot " \
3641 			       "initialize QDIO.\n");
3642 		kfree(indicators);
3643 		return -ENOMEM;
3644 	}
3645 	memset(chsc_area,0,sizeof(qdio_chsc_area_t));
3646 	return 0;
3647 }
3648 
3649 #ifdef MODULE
qdio_release_qdio_memory(void)3650 static void qdio_release_qdio_memory(void)
3651 {
3652 	kfree(chsc_area);
3653 	if (indicators) kfree(indicators);
3654 }
3655 #endif /* MODULE */
3656 
3657 int init_module(void); /* we want to use it in init_QDIO */
3658 
qdio_unregister_dbf_views(void)3659 static void qdio_unregister_dbf_views(void)
3660 {
3661 	if (qdio_dbf_setup)
3662 		debug_unregister(qdio_dbf_setup);
3663 	if (qdio_dbf_sbal)
3664 		debug_unregister(qdio_dbf_sbal);
3665 	if (qdio_dbf_sense)
3666 		debug_unregister(qdio_dbf_sense);
3667 	if (qdio_dbf_trace)
3668 		debug_unregister(qdio_dbf_trace);
3669 #ifdef QDIO_DBF_LIKE_HELL
3670         if (qdio_dbf_slsb_out)
3671                 debug_unregister(qdio_dbf_slsb_out);
3672         if (qdio_dbf_slsb_in)
3673                 debug_unregister(qdio_dbf_slsb_in);
3674 #endif /* QDIO_DBF_LIKE_HELL */
3675 }
3676 
3677 /* this is not __initfunc, as it is called from init_module */
init_QDIO(void)3678 int init_QDIO(void)
3679 {
3680 	char dbf_text[20];
3681 	int res;
3682 #if defined(MODULE)||defined(QDIO_PERFORMANCE_STATS)
3683 	void *ptr;
3684 #endif /* defined(MODULE)||defined(QDIO_PERFORMANCE_STATS) */
3685 
3686 	qdio_eyecatcher();
3687 
3688 	printk("qdio: loading %s\n",version);
3689 
3690 	res=qdio_get_qdio_memory();
3691 	if (res) return res;
3692 
3693 	sema_init(&init_sema,1);
3694 
3695 	qdio_dbf_setup=debug_register(QDIO_DBF_SETUP_NAME,
3696 				      QDIO_DBF_SETUP_INDEX,
3697 				      QDIO_DBF_SETUP_NR_AREAS,
3698 				      QDIO_DBF_SETUP_LEN);
3699 	if (!qdio_dbf_setup) goto oom;
3700 	debug_register_view(qdio_dbf_setup,&debug_hex_ascii_view);
3701 	debug_set_level(qdio_dbf_setup,QDIO_DBF_SETUP_LEVEL);
3702 
3703 	qdio_dbf_sbal=debug_register(QDIO_DBF_SBAL_NAME,
3704 				     QDIO_DBF_SBAL_INDEX,
3705 				     QDIO_DBF_SBAL_NR_AREAS,
3706 				     QDIO_DBF_SBAL_LEN);
3707 	if (!qdio_dbf_sbal) goto oom;
3708 
3709 	debug_register_view(qdio_dbf_sbal,&debug_hex_ascii_view);
3710 	debug_set_level(qdio_dbf_sbal,QDIO_DBF_SBAL_LEVEL);
3711 
3712 	qdio_dbf_sense=debug_register(QDIO_DBF_SENSE_NAME,
3713 				      QDIO_DBF_SENSE_INDEX,
3714 				      QDIO_DBF_SENSE_NR_AREAS,
3715 				      QDIO_DBF_SENSE_LEN);
3716 	if (!qdio_dbf_sense) goto oom;
3717 
3718 	debug_register_view(qdio_dbf_sense,&debug_hex_ascii_view);
3719 	debug_set_level(qdio_dbf_sense,QDIO_DBF_SENSE_LEVEL);
3720 
3721 	qdio_dbf_trace=debug_register(QDIO_DBF_TRACE_NAME,
3722 				      QDIO_DBF_TRACE_INDEX,
3723 				      QDIO_DBF_TRACE_NR_AREAS,
3724 				      QDIO_DBF_TRACE_LEN);
3725 	if (!qdio_dbf_trace) goto oom;
3726 
3727 	debug_register_view(qdio_dbf_trace,&debug_hex_ascii_view);
3728 	debug_set_level(qdio_dbf_trace,QDIO_DBF_TRACE_LEVEL);
3729 
3730 #ifdef QDIO_DBF_LIKE_HELL
3731         qdio_dbf_slsb_out=debug_register(QDIO_DBF_SLSB_OUT_NAME,
3732                                          QDIO_DBF_SLSB_OUT_INDEX,
3733                                          QDIO_DBF_SLSB_OUT_NR_AREAS,
3734                                          QDIO_DBF_SLSB_OUT_LEN);
3735         if (!qdio_dbf_slsb_out) goto oom;
3736         debug_register_view(qdio_dbf_slsb_out,&debug_hex_ascii_view);
3737         debug_set_level(qdio_dbf_slsb_out,QDIO_DBF_SLSB_OUT_LEVEL);
3738 
3739         qdio_dbf_slsb_in=debug_register(QDIO_DBF_SLSB_IN_NAME,
3740                                         QDIO_DBF_SLSB_IN_INDEX,
3741                                         QDIO_DBF_SLSB_IN_NR_AREAS,
3742                                         QDIO_DBF_SLSB_IN_LEN);
3743         if (!qdio_dbf_slsb_in) goto oom;
3744         debug_register_view(qdio_dbf_slsb_in,&debug_hex_ascii_view);
3745         debug_set_level(qdio_dbf_slsb_in,QDIO_DBF_SLSB_IN_LEVEL);
3746 #endif /* QDIO_DBF_LIKE_HELL */
3747 
3748 #ifdef QDIO_PERFORMANCE_STATS
3749        	memset((void*)&perf_stats,0,sizeof(perf_stats));
3750 	QDIO_DBF_TEXT0(0,setup,"perfstat");
3751 	ptr=&perf_stats;
3752 	QDIO_DBF_HEX0(0,setup,&ptr,sizeof(void*));
3753 #endif /* QDIO_PERFORMANCE_STATS */
3754 
3755 #ifdef MODULE
3756 	QDIO_DBF_TEXT0(0,setup,"initmodl");
3757 	ptr=&init_module;
3758 	QDIO_DBF_HEX0(0,setup,&ptr,sizeof(void*));
3759 #endif /* MODULE */
3760 
3761 	qdio_add_procfs_entry();
3762 
3763 	qdio_check_for_machine_features();
3764 
3765 	sprintf(dbf_text,"hydrati%1x",hydra_thinints);
3766 	QDIO_DBF_TEXT0(0,setup,dbf_text);
3767 	sprintf(dbf_text,"omitsvs%1x",omit_svs);
3768 	QDIO_DBF_TEXT0(0,setup,dbf_text);
3769 
3770 	tiqdio_register_thinints();
3771 
3772 	return 0;
3773  oom:
3774 	QDIO_PRINT_ERR("not enough memory for dbf.\n");
3775 	qdio_unregister_dbf_views();
3776 	return -ENOMEM;
3777 }
3778 
3779 #ifdef MODULE
init_module(void)3780 int init_module(void)
3781 {
3782 	return init_QDIO();
3783 }
3784 
cleanup_module(void)3785 void cleanup_module(void)
3786 {
3787 	tiqdio_unregister_thinints();
3788 
3789 	qdio_remove_procfs_entry();
3790 
3791 	qdio_release_qdio_memory();
3792 
3793 	qdio_unregister_dbf_views();
3794 
3795   	printk("qdio: %s: module removed\n",version);
3796 }
3797 #else /* MODULE */
initcall_QDIO(void)3798 static int __init initcall_QDIO(void)
3799 {
3800 	        return init_QDIO();
3801 }
3802 __initcall(initcall_QDIO);
3803 #endif /* MODULE */
3804 
3805 EXPORT_SYMBOL(qdio_initialize);
3806 EXPORT_SYMBOL(qdio_activate);
3807 EXPORT_SYMBOL(do_QDIO);
3808 EXPORT_SYMBOL(qdio_cleanup);
3809 EXPORT_SYMBOL(qdio_eyecatcher);
3810 EXPORT_SYMBOL(qdio_synchronize);
3811 
3812