3 * linux/drivers/s390/qdio.c
5 * Linux for S/390 QDIO base support, Hipersocket base support
8 * Copyright 2000,2002 IBM Corporation
9 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>
11 * Restriction: only 63 iqdio subchannels would have its own indicator,
12 * after that, subsequent subchannels share one indicator
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)
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.
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.
32 /* we want the eyecatcher to be at the top of the code */
33 void volatile qdio_eyecatcher(void)
38 #include <linux/config.h>
40 #include <linux/module.h>
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>
52 #include <asm/atomic.h>
53 #include <asm/semaphore.h>
56 #include <asm/debug.h>
60 #define VERSION_QDIO_C "$Revision: 1.145.4.9 $"
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");
70 /******************** HERE WE GO ***********************************/
72 static const char *version="QDIO base support version 2 ("
73 VERSION_QDIO_C "/" VERSION_QDIO_H ")";
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;
82 unsigned int siga_outs;
83 unsigned int siga_ins;
84 unsigned int siga_syncs;
86 unsigned int thinints;
87 unsigned int fast_reqs;
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;
97 #endif /* QDIO_PERFORMANCE_STATS */
99 static int hydra_thinints=0;
100 static int omit_svs=0;
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;
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 */
116 static qdio_irq_t *first_irq[QDIO_IRQ_BUCKETS]={
117 [0 ... (QDIO_IRQ_BUCKETS-1)] = NULL
119 static rwlock_t irq_list_lock[QDIO_IRQ_BUCKETS]={
120 [0 ... (QDIO_IRQ_BUCKETS-1)] = RW_LOCK_UNLOCKED
123 static struct semaphore init_sema;
125 static qdio_chsc_area_t *chsc_area;
126 static spinlock_t chsc_area_lock=SPIN_LOCK_UNLOCKED;
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);
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));
158 #define atomic_swap(a,b) xchg((int*)a.counter,b)
160 /* not a macro, as one of the arguments is atomic_read */
161 static inline int qdio_min(int a,int b)
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)
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)
182 #define MY_MODULE_STRING(x) #x
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 */
190 #define QDIO_PFIX_GET_ADDR(x) ((flags&QDIO_PFIX) ? \
191 pfix_get_addr(x):((unsigned long)x))
193 /***************** SCRUBBER HELPER ROUTINES **********************/
195 static inline volatile __u64 qdio_get_micros(void)
199 asm volatile ("STCK %0" : "=m" (time));
200 return time>>12; /* time>>12 is microseconds*/
202 static inline unsigned long qdio_get_millis(void)
204 return (unsigned long)(qdio_get_micros()>>10);
207 static __inline__ int atomic_return_add (int i, atomic_t *v)
210 __CS_LOOP(old, new, v, i, "ar");
214 static void qdio_wait_nonbusy(unsigned int timeout)
219 sprintf(dbf_text,"wtnb%4x",timeout);
220 QDIO_DBF_TEXT3(0,trace,dbf_text);
222 start=qdio_get_millis();
224 set_task_state(current,TASK_INTERRUPTIBLE);
225 if (qdio_get_millis()-start>timeout) {
228 schedule_timeout(((start+timeout-qdio_get_millis())>>10)*HZ);
231 set_task_state(current,TASK_RUNNING);
234 static int qdio_wait_for_no_use_count(atomic_t *use_count)
238 QDIO_DBF_TEXT3(0,trace,"wtnousec");
239 start=qdio_get_millis();
241 if (qdio_get_millis()-start>QDIO_NO_USE_COUNT_TIMEOUT) {
242 QDIO_DBF_TEXT1(1,trace,"WTNOUSTO");
245 if (!atomic_read(use_count)) {
246 QDIO_DBF_TEXT3(0,trace,"wtnoused");
249 qdio_wait_nonbusy(QDIO_NO_USE_COUNT_TIME);
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) */
257 static inline int qdio_reserve_q(qdio_q_t *q)
259 return atomic_return_add(1,&q->use_count);
262 static inline void qdio_release_q(qdio_q_t *q)
264 atomic_dec(&q->use_count);
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); \
272 QDIO_DBF_HEX2(0,slsb_out,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \
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); \
280 QDIO_DBF_HEX2(0,slsb_out,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \
283 #else /* QDIO_DBF_LIKE_HELL */
284 #define set_slsb(x,y) qdio_set_slsb(x,y)
285 #endif /* QDIO_DBF_LIKE_HELL */
286 static volatile inline void qdio_set_slsb(volatile char *slsb,
289 xchg((char*)slsb,value);
292 static inline int qdio_siga_sync(qdio_q_t *q,
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 */
305 #ifdef QDIO_PERFORMANCE_STATS
306 perf_stats.siga_syncs++;
307 #endif /* QDIO_PERFORMANCE_STATS */
319 : "d" (0x10000|q->irq), "d" (gpr2), "d" (gpr3)
320 : "cc", "0", "1", "2", "3"
322 #else /* QDIO_32_BIT */
332 : "d" (0x10000|q->irq), "d" (gpr2), "d" (gpr3)
333 : "cc", "0", "1", "2", "3"
335 #endif /* QDIO_32_BIT */
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*));
349 static inline int qdio_siga_sync_q(qdio_q_t *q)
352 return qdio_siga_sync(q,0,q->mask);
354 return qdio_siga_sync(q,q->mask,0);
358 /* returns QDIO_SIGA_ERROR_ACCESS_EXCEPTION as cc, when SIGA returns
359 an access exception */
360 static inline int qdio_siga_output(qdio_q_t *q)
366 #ifdef QDIO_PERFORMANCE_STATS
367 perf_stats.siga_outs++;
368 #endif /* QDIO_PERFORMANCE_STATS */
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 */
389 ".section .fixup,\"ax\"\n\t"
398 ".section __ex_table,\"a\"\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"
407 #else /* QDIO_32_BIT */
419 ".section .fixup,\"ax\"\n\t"
423 ".section __ex_table,\"a\"\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"
432 #endif /* QDIO_32_BIT */
434 //QDIO_PRINT_ERR("cc=%x, busy=%x\n",cc,busy_bit);
435 if ( (cc==2) && (busy_bit) &&
437 if (!start_time) start_time=NOW;
438 if ((NOW-start_time)>QDIO_BUSY_BIT_PATIENCE)
444 if ((cc==2) && (busy_bit)) cc|=QDIO_SIGA_ERROR_B_BIT_SET;
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*));
457 static inline int qdio_siga_input(qdio_q_t *q)
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 */
466 #ifdef QDIO_PERFORMANCE_STATS
467 perf_stats.siga_ins++;
468 #endif /* QDIO_PERFORMANCE_STATS */
479 : "d" (0x10000|q->irq), "d" (q->mask)
480 : "cc", "0", "1", "2", "memory"
482 #else /* QDIO_32_BIT */
491 : "d" (0x10000|q->irq), "d" (q->mask)
492 : "cc", "0", "1", "2", "memory"
494 #endif /* QDIO_32_BIT */
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*));
507 /* locked by the locks in qdio_activate and qdio_cleanup */
508 static __u32 * volatile qdio_get_indicator(void)
513 while (i<INDICATORS_PER_CACHELINE) {
514 if (!indicator_used[i]) {
525 atomic_inc(&spare_indicator_usecount);
526 return (__u32 * volatile) &spare_indicator;
530 /* locked by the locks in qdio_activate and qdio_cleanup */
531 static void qdio_put_indicator(__u32 *addr)
535 if ( (addr) && (addr!=&spare_indicator) ) {
539 if (addr==&spare_indicator) {
540 atomic_dec(&spare_indicator_usecount);
544 static inline volatile void tiqdio_clear_summary_bit(__u32 *location)
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 */
553 static inline volatile void tiqdio_set_summary_bit(__u32 *location)
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 */
562 static inline void tiqdio_sched_tl(void)
564 tasklet_hi_schedule(&tiqdio_tasklet);
567 static inline void qdio_mark_tiq(qdio_q_t *q)
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 */
575 spin_lock_irqsave(&ttiq_list_lock,flags);
576 if (unlikely(atomic_read(&q->is_in_shutdown))) goto out_unlock;
579 if ((q->list_prev) || (q->list_next)) goto out_unlock;
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;
591 spin_unlock_irqrestore(&ttiq_list_lock,flags);
593 tiqdio_set_summary_bit((__u32*)q->dev_st_chg_ind);
598 spin_unlock_irqrestore(&ttiq_list_lock,flags);
602 static inline void qdio_mark_q(qdio_q_t *q)
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 */
609 if (unlikely(atomic_read(&q->is_in_shutdown))) return;
611 tasklet_schedule(&q->tasklet);
614 static inline int qdio_stop_polling(qdio_q_t *q)
616 #ifdef QDIO_USE_PROCESSING_STATE
619 if (!atomic_swap(&q->polling,0)) return 1;
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 */
626 /* show the card that we are not polling anymore */
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.
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 */
640 tiqdio_set_summary_bit
641 ((__u32*)q->dev_st_chg_ind);
645 #endif /* QDIO_USE_PROCESSING_STATE */
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 :-) */
652 static inline void qdio_unmark_q(qdio_q_t *q)
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 */
661 if ((!q->list_prev)||(!q->list_next)) return;
663 if ((q->is_thinint_q)&&(q->is_input_q)) {
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))
671 if (q->list_next==q) {
672 /* q was the only interesting q */
677 q->list_next->list_prev=q->list_prev;
678 q->list_prev->list_next=q->list_next;
679 tiq_list=q->list_next;
684 spin_unlock_irqrestore(&ttiq_list_lock,flags);
688 static inline volatile unsigned long tiqdio_clear_global_summary(void)
692 #ifdef QDIO_DBF_LIKE_HELL
693 QDIO_DBF_TEXT5(0,trace,"clrglobl");
694 #endif /* QDIO_DBF_LIKE_HELL */
699 ".insn rre,0xb2650000,2,0 \n\t"
701 : "=d" (time) : : "cc", "1", "2", "3"
703 #else /* QDIO_32_BIT */
706 ".insn rre,0xb2650000,2,0 \n\t"
708 : "=d" (time) : : "cc", "1", "2", "3"
710 #endif /* QDIO_32_BIT */
712 #ifdef QDIO_DBF_LIKE_HELL
713 QDIO_DBF_HEX5(0,trace,&time,sizeof(unsigned long));
714 #endif /* QDIO_DBF_LIKE_HELL */
718 /************************* OUTBOUND ROUTINES *******************************/
720 static inline void qdio_translate_buffer_back(qdio_q_t *q,int bufno)
722 if (unlikely(!q->is_0copy_sbals_q))
723 memcpy(q->qdio_buffers[bufno],
724 (void*)q->sbal[bufno],SBAL_SIZE);
727 static inline int qdio_get_outbound_buffer_frontier(qdio_q_t *q)
731 int first_not_to_check;
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 */
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));
748 if ((!q->is_iqdio_q)&&(!q->hydra_gives_outbound_pcis)) {
753 if (f==first_not_to_check) goto out;
754 slsbyte=slsb[f_mod_no];
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 */
764 /* the card got it */
765 if (slsbyte==SLSB_P_OUTPUT_EMPTY) {
766 atomic_dec(&q->number_of_buffers_used);
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 */
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);
783 /* kind of process the buffer */
784 set_slsb(&q->slsb.acc.val[f_mod_no],
785 SLSB_P_OUTPUT_NOT_INIT);
787 qdio_translate_buffer_back(q,f_mod_no);
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);
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;
804 #ifdef QDIO_DBF_LIKE_HELL
805 QDIO_DBF_TEXT5(0,trace,"outpni");
806 #endif /* QDIO_DBF_LIKE_HELL */
810 return (q->first_to_check=f_mod_no);
813 /* all buffers are processed */
814 static inline int qdio_is_outbound_q_done(qdio_q_t *q)
817 #ifdef QDIO_DBF_LIKE_HELL
819 #endif /* QDIO_DBF_LIKE_HELL */
821 no_used=atomic_read(&q->number_of_buffers_used);
823 #ifdef QDIO_DBF_LIKE_HELL
825 sprintf(dbf_text,"oqisnt%02x",no_used);
826 QDIO_DBF_TEXT4(0,trace,dbf_text);
828 QDIO_DBF_TEXT4(0,trace,"oqisdone");
830 QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
831 #endif /* QDIO_DBF_LIKE_HELL */
835 static inline int qdio_has_outbound_q_moved(qdio_q_t *q)
839 i=qdio_get_outbound_buffer_frontier(q);
841 if ( (i!=GET_SAVED_FRONTIER(q)) ||
842 (q->error_status_flags&QDIO_STATUS_LOOK_FOR_ERROR) ) {
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 */
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 */
858 static inline void qdio_kick_outbound_q(qdio_q_t *q)
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 */
867 if (!q->siga_out) return;
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).
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
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.
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.
896 result=qdio_siga_output(q);
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;
907 case (2|QDIO_SIGA_ERROR_B_BIT_SET):
908 /* cc=2 and busy bit: */
909 atomic_inc(&q->busy_siga_counter);
911 /* if the last siga was successful, save
913 if (!q->timing.busy_start)
914 q->timing.busy_start=NOW;
916 /* if we're in time, don't touch error_status_flags
918 if (NOW-q->timing.busy_start<QDIO_BUSY_BIT_GIVE_UP) {
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 */
928 /* for plain cc=1, 2 or 3: */
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;
938 static inline void qdio_kick_outbound_handler(qdio_q_t *q)
940 #ifdef QDIO_DBF_LIKE_HELL
942 #endif /* QDIO_DBF_LIKE_HELL */
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);
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 */
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 */
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,
968 /* for the next time: */
969 q->first_element_to_kick=real_end;
972 q->error_status_flags=0;
975 static inline void __qdio_outbound_processing(qdio_q_t *q)
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 */
983 if (unlikely(qdio_reserve_q(q))) {
985 #ifdef QDIO_PERFORMANCE_STATS
987 #endif /* QDIO_PERFORMANCE_STATS */
988 /* as we're sissies, we'll check next time */
989 if (likely(!atomic_read(&q->is_in_shutdown))) {
991 #ifdef QDIO_DBF_LIKE_HELL
992 QDIO_DBF_TEXT4(0,trace,"busy,agn");
993 #endif /* QDIO_DBF_LIKE_HELL */
997 #ifdef QDIO_PERFORMANCE_STATS
999 #endif /* QDIO_PERFORMANCE_STATS */
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);
1009 #ifdef QDIO_PERFORMANCE_STATS
1010 perf_stats.tl_runs++;
1011 #endif /* QDIO_PERFORMANCE_STATS */
1013 if (qdio_has_outbound_q_moved(q)) {
1014 qdio_kick_outbound_handler(q);
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) {
1025 } else if (!q->hydra_gives_outbound_pcis) {
1026 if (!qdio_is_outbound_q_done(q)) {
1034 static void qdio_outbound_processing(qdio_q_t *q)
1036 __qdio_outbound_processing(q);
1039 /************************* INBOUND ROUTINES *******************************/
1042 static inline int qdio_get_inbound_buffer_frontier(qdio_q_t *q)
1045 volatile char *slsb;
1047 int first_not_to_check;
1049 #ifdef QDIO_USE_PROCESSING_STATE
1050 int last_position=-1;
1051 #endif /* QDIO_USE_PROCESSING_STATE */
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 */
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
1062 first_not_to_check=f+qdio_min(atomic_read(&q->number_of_buffers_used),
1063 (QDIO_MAX_BUFFERS_PER_Q-1));
1065 /* we don't use this one, as a PCI or we after a thin interrupt
1066 * will sync the queues
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];
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 */
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 */
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 */
1092 set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_NOT_INIT);
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;
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
1110 atomic_dec(&q->number_of_buffers_used);
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 */
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);
1128 /* kind of process the buffer */
1129 set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_NOT_INIT);
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;
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);
1142 #ifdef QDIO_USE_PROCESSING_STATE
1144 #endif /* QDIO_USE_PROCESSING_STATE */
1149 /* everything else means frontier not changed (HALTED or so) */
1151 q->first_to_check=f_mod_no;
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 */
1158 #ifdef QDIO_DBF_LIKE_HELL
1159 QDIO_DBF_HEX4(0,trace,&q->first_to_check,sizeof(int));
1160 #endif /* QDIO_DBF_LIKE_HELL */
1162 return q->first_to_check;
1165 static inline int qdio_has_inbound_q_moved(qdio_q_t *q)
1169 #ifdef QDIO_PERFORMANCE_STATS
1170 static int old_pcis=0;
1171 static int old_thinints=0;
1173 if ((old_pcis==perf_stats.pcis)&&(old_thinints==perf_stats.thinints))
1174 perf_stats.start_time_inbound=NOW;
1176 old_pcis=perf_stats.pcis;
1177 #endif /* QDIO_PERFORMANCE_STATS */
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) ) {
1183 if ((!q->siga_sync)&&(!q->hydra_gives_outbound_pcis)) {
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 */
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 */
1201 /* means, no more buffers to be filled */
1202 static inline int iqdio_is_inbound_q_done(qdio_q_t *q)
1205 #ifdef QDIO_DBF_LIKE_HELL
1207 #endif /* QDIO_DBF_LIKE_HELL */
1209 no_used=atomic_read(&q->number_of_buffers_used);
1211 /* propagate the change from 82 to 80 through VM */
1214 #ifdef QDIO_DBF_LIKE_HELL
1216 sprintf(dbf_text,"iqisnt%02x",no_used);
1217 QDIO_DBF_TEXT4(0,trace,dbf_text);
1219 QDIO_DBF_TEXT4(0,trace,"iniqisdo");
1221 QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
1222 #endif /* QDIO_DBF_LIKE_HELL */
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
1234 * we will return 0 below, as there is nothing to
1235 * do, except of scheduling ourselves for the next
1237 tiqdio_set_summary_bit((__u32*)q->dev_st_chg_ind);
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 */
1248 /* we'll check for more primed buffers
1249 * in qeth_stop_polling */
1255 static inline int qdio_is_inbound_q_done(qdio_q_t *q)
1258 #ifdef QDIO_DBF_LIKE_HELL
1260 #endif /* QDIO_DBF_LIKE_HELL */
1262 no_used=atomic_read(&q->number_of_buffers_used);
1264 /* we need that one for synchronization with the OSA/FCP card, as it
1265 * does a kind of PCI avoidance */
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 */
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 */
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;
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 */
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 */
1311 static inline void qdio_kick_inbound_handler(qdio_q_t *q)
1314 int start,end,real_end,i;
1315 #ifdef QDIO_DBF_LIKE_HELL
1318 QDIO_DBF_TEXT4(0,trace,"kickinh");
1319 QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
1320 #endif /* QDIO_DBF_LIKE_HELL */
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);
1329 qdio_translate_buffer_back(q,i);
1331 i=(i+1)&(QDIO_MAX_BUFFERS_PER_Q-1);
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 */
1339 if (likely(q->state==QDIO_IRQ_STATE_ACTIVE))
1341 QDIO_STATUS_INBOUND_INT|q->error_status_flags,
1342 q->qdio_error,q->siga_error,q->q_no,start,count,
1345 /* for the next time: */
1346 q->first_element_to_kick=real_end;
1349 q->error_status_flags=0;
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 */
1357 static inline void __tiqdio_inbound_processing(qdio_q_t *q,
1358 int spare_ind_was_set)
1360 qdio_irq_t *irq_ptr;
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 */
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
1372 if (unlikely(qdio_reserve_q(q))) {
1374 #ifdef QDIO_PERFORMANCE_STATS
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 */
1382 #ifdef QDIO_PERFORMANCE_STATS
1384 #endif /* QDIO_PERFORMANCE_STATS */
1385 if (unlikely(atomic_read(&q->is_in_shutdown))) {
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);
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);
1403 if (q->hydra_gives_outbound_pcis) {
1404 if (!q->siga_sync_done_on_thinints) {
1406 } else if ((!q->siga_sync_done_on_outb_tis)&&
1407 (q->hydra_gives_outbound_pcis)) {
1408 SYNC_MEMORY_ALL_OUTB;
1414 /* maybe we have to do work on our outbound queues... at least
1415 * we have to check for outbound-int-capable thinint-capable
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);
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);
1448 static void tiqdio_inbound_processing(qdio_q_t *q)
1450 __tiqdio_inbound_processing(q,atomic_read(&spare_indicator_usecount));
1453 static inline void __qdio_inbound_processing(qdio_q_t *q)
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 */
1462 if (unlikely(qdio_reserve_q(q))) {
1464 #ifdef QDIO_PERFORMANCE_STATS
1466 #endif /* QDIO_PERFORMANCE_STATS */
1467 /* as we're sissies, we'll check next time */
1468 if (likely(!atomic_read(&q->is_in_shutdown))) {
1470 #ifdef QDIO_DBF_LIKE_HELL
1471 QDIO_DBF_TEXT4(0,trace,"busy,agn");
1472 #endif /* QDIO_DBF_LIKE_HELL */
1476 #ifdef QDIO_PERFORMANCE_STATS
1478 perf_stats.tl_runs++;
1479 #endif /* QDIO_PERFORMANCE_STATS */
1482 if (qdio_has_inbound_q_moved(q)) {
1483 qdio_kick_inbound_handler(q);
1484 if (!qdio_stop_polling(q)) {
1486 if (q_laps<QDIO_Q_LAPS) goto again;
1490 if (!qdio_is_inbound_q_done(q)) /* means poll time is
1498 static void qdio_inbound_processing(qdio_q_t *q)
1500 __qdio_inbound_processing(q);
1503 /************************* MAIN ROUTINES *******************************/
1505 static inline void tiqdio_inbound_checks(void)
1508 int spare_ind_was_set=0;
1509 #ifdef QDIO_USE_PROCESSING_STATE
1511 #endif /* QDIO_USE_PROCESSING_STATE */
1513 #ifdef QDIO_DBF_LIKE_HELL
1516 QDIO_DBF_TEXT4(0,trace,"iqdinbck");
1517 #endif /* QDIO_DBF_LIKE_HELL */
1519 #ifdef QDIO_DBF_LIKE_HELL
1520 QDIO_DBF_TEXT5(0,trace,"iqlocsum");
1521 #endif /* QDIO_DBF_LIKE_HELL */
1523 #ifdef QDIO_USE_PROCESSING_STATE
1525 #endif /* QDIO_USE_PROCESSING_STATE */
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);
1533 q=(qdio_q_t*)tiq_list;
1534 /* switch all active queues to processing state */
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);
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;
1550 /* under VM, we have not used the PROCESSING state, so no
1551 * need to stop polling */
1553 q=(qdio_q_t*)q->list_next;
1557 if (unlikely(qdio_reserve_q(q))) {
1559 #ifdef QDIO_PERFORMANCE_STATS
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 */
1565 /* sanity -- we'd get here without setting the
1567 tiqdio_set_summary_bit((__u32*)q->dev_st_chg_ind);
1571 if (!qdio_stop_polling(q)) {
1573 if (q_laps<QDIO_Q_LAPS) {
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*)
1586 q=(qdio_q_t*)q->list_next;
1587 } while (q!=(qdio_q_t*)tiq_list);
1588 #endif /* QDIO_USE_PROCESSING_STATE */
1591 static void tiqdio_tl(unsigned long data)
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 */
1600 tiqdio_inbound_checks();
1603 /********************* GENERAL HELPER_ROUTINES ***********************/
1605 static qdio_irq_t *qdio_get_irq_ptr(int irq)
1607 qdio_irq_t *irq_ptr;
1608 int bucket=irq&(QDIO_IRQ_BUCKETS-1);
1610 read_lock(&irq_list_lock[bucket]);
1611 irq_ptr=first_irq[bucket];
1613 if (irq_ptr->irq==irq) break;
1614 irq_ptr=irq_ptr->next;
1616 read_unlock(&irq_list_lock[bucket]);
1620 static qdio_irq_t *qdio_get_irq_ptr_wolock(int irq)
1622 qdio_irq_t *irq_ptr=first_irq[irq&(QDIO_IRQ_BUCKETS-1)];
1625 if (irq_ptr->irq==irq) break;
1626 irq_ptr=irq_ptr->next;
1631 /* irq_ptr->irq should be set already! */
1632 static void qdio_insert_irq_ptr(qdio_irq_t *irq_ptr)
1637 if (!irq_ptr) return;
1640 bucket=irq&(QDIO_IRQ_BUCKETS-1);
1642 write_lock(&irq_list_lock[bucket]);
1644 if (irq_ptr==qdio_get_irq_ptr_wolock(irq)) goto out;
1646 if (!first_irq[bucket]) {
1647 first_irq[bucket]=irq_ptr;
1649 i_p=first_irq[bucket];
1656 write_unlock(&irq_list_lock[bucket]);
1659 static void qdio_remove_irq_ptr(qdio_irq_t *irq_ptr)
1664 if (!irq_ptr) return;
1667 bucket=irq&(QDIO_IRQ_BUCKETS-1);
1669 write_lock(&irq_list_lock[bucket]);
1671 if (!qdio_get_irq_ptr_wolock(irq)) goto out;
1673 if (first_irq[irq&(QDIO_IRQ_BUCKETS-1)]==irq_ptr) {
1674 first_irq[irq&(QDIO_IRQ_BUCKETS-1)]=irq_ptr->next;
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;
1682 write_unlock(&irq_list_lock[bucket]);
1685 static void qdio_release_irq_memory(qdio_irq_t *irq_ptr)
1690 for (i=0;i<QDIO_MAX_QUEUES_PER_IRQ;i++) {
1691 if (!irq_ptr->input_qs[i]) goto next;
1693 if (!irq_ptr->input_qs[i]->is_0copy_sbals_q)
1694 for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) {
1696 if (irq_ptr->input_qs[i]->sbal[j])
1697 kfree((void*)irq_ptr->
1698 input_qs[i]->sbal[j]);
1699 available=PAGE_SIZE;
1701 available-=sizeof(sbal_t);
1703 if (irq_ptr->input_qs[i]->slib)
1704 kfree(irq_ptr->input_qs[i]->slib);
1705 kfree(irq_ptr->input_qs[i]);
1708 if (!irq_ptr->output_qs[i]) continue;
1710 if (!irq_ptr->output_qs[i]->is_0copy_sbals_q)
1711 for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) {
1713 if (irq_ptr->output_qs[i]->sbal[j])
1714 kfree((void*)irq_ptr->
1715 output_qs[i]->sbal[j]);
1716 available=PAGE_SIZE;
1718 available-=sizeof(sbal_t);
1720 if (irq_ptr->output_qs[i]->slib)
1721 kfree(irq_ptr->output_qs[i]->slib);
1722 kfree(irq_ptr->output_qs[i]);
1725 kfree(irq_ptr->qdr);
1729 static inline void qdio_wakeup(atomic_t *var,qdio_irq_t *irq_ptr)
1731 wait_queue_head_t *wait_q;
1733 #ifdef QDIO_DBF_LIKE_HELL
1735 sprintf(dbf_text,"qwkp%4x",irq_ptr->irq);
1736 QDIO_DBF_TEXT3(0,trace,dbf_text);
1737 #endif /* QDIO_DBF_LIKE_HELL */
1740 if ((wait_q=&irq_ptr->wait_q))
1744 static int qdio_sleepon(atomic_t *var,int timeout,qdio_irq_t *irq_ptr)
1748 DECLARE_WAITQUEUE (current_wait_q,current);
1750 #ifdef QDIO_DBF_LIKE_HELL
1752 sprintf(dbf_text,"qslp%4x",irq_ptr->irq);
1753 QDIO_DBF_TEXT3(0,trace,dbf_text);
1754 #endif /* QDIO_DBF_LIKE_HELL */
1756 add_wait_queue(&irq_ptr->wait_q,¤t_wait_q);
1757 stop=(qdio_get_micros()>>10)+timeout;
1759 set_task_state(current,TASK_INTERRUPTIBLE);
1760 if (atomic_read(var)) {
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 */
1773 schedule_timeout(((stop-(qdio_get_micros()>>10))>>10)*HZ);
1776 set_task_state(current,TASK_RUNNING);
1777 remove_wait_queue(&irq_ptr->wait_q,¤t_wait_q);
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)
1793 if (!irq_ptr) return;
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);
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];
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];
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)
1828 char dbf_text[20]; /* see qdio_initialize */
1832 for (i=0;i<no_input_qs;i++) {
1833 q=kmalloc(sizeof(qdio_q_t),GFP_KERNEL);
1836 QDIO_PRINT_ERR("kmalloc of q failed!\n");
1839 memset(q,0,sizeof(qdio_q_t));
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*));
1845 q->slib=kmalloc(PAGE_SIZE,GFP_KERNEL);
1847 QDIO_PRINT_ERR("kmalloc of slib failed!\n");
1850 memset(q->slib,0,PAGE_SIZE);
1851 q->sl=(sl_t*)(((char*)q->slib)+PAGE_SIZE/2);
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++);
1858 } else for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) {
1860 q->sbal[j]=kmalloc(PAGE_SIZE,GFP_KERNEL);
1864 available=PAGE_SIZE;
1865 memset((void*)q->sbal[j],0,PAGE_SIZE);
1867 q->sbal[j]=(volatile sbal_t *)
1868 (((char*)q->sbal[j-1])+sizeof(sbal_t));
1870 available-=sizeof(sbal_t);
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;
1881 q->is_0copy_sbals_q=flags&QDIO_INBOUND_0COPY_SBALS;
1882 q->first_to_check=0;
1884 q->handler=input_handler;
1885 q->dev_st_chg_ind=irq_ptr->dev_st_chg_ind;
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);
1894 /* actually this is not used for inbound queues. yet. */
1895 atomic_set(&q->busy_siga_counter,0);
1896 q->timing.busy_start=0;
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;
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]);
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]);
1915 QDIO_DBF_TEXT2(0,setup,"sl-sb-b0");
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*));
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;
1932 for (i=0;i<no_output_qs;i++) {
1933 q=kmalloc(sizeof(qdio_q_t),GFP_KERNEL);
1938 memset(q,0,sizeof(qdio_q_t));
1940 sprintf(dbf_text,"outq%4x",i);
1941 QDIO_DBF_TEXT0(0,setup,dbf_text);
1942 QDIO_DBF_HEX0(0,setup,&q,sizeof(void*));
1944 q->slib=kmalloc(PAGE_SIZE,GFP_KERNEL);
1946 QDIO_PRINT_ERR("kmalloc of slib failed!\n");
1949 memset(q->slib,0,PAGE_SIZE);
1950 q->sl=(sl_t*)(((char*)q->slib)+PAGE_SIZE/2);
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++);
1957 } else for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) {
1959 q->sbal[j]=kmalloc(PAGE_SIZE,GFP_KERNEL);
1963 available=PAGE_SIZE;
1964 memset((void*)q->sbal[j],0,PAGE_SIZE);
1966 q->sbal[j]=(volatile sbal_t *)
1967 (((char*)q->sbal[j-1])+sizeof(sbal_t));
1969 available-=sizeof(sbal_t);
1972 q->queue_type=q_format;
1973 q->int_parm=int_parm;
1974 irq_ptr->output_qs[i]=q;
1976 q->is_0copy_sbals_q=flags&QDIO_OUTBOUND_0COPY_SBALS;
1977 q->irq=irq_ptr->irq;
1981 q->first_to_check=0;
1983 q->handler=output_handler;
1985 q->tasklet.data=(unsigned long)q;
1986 q->tasklet.func=(void(*)(unsigned long))
1987 &qdio_outbound_processing;
1989 atomic_set(&q->busy_siga_counter,0);
1990 q->timing.busy_start=0;
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]);
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]);
2003 QDIO_DBF_TEXT2(0,setup,"sl-sb-b0");
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*));
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;
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)
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)/
2045 qdio_use_thresholds(q,QDIO_STATS_CLASSES/2);*/
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)/
2056 qdio_use_thresholds(q,QDIO_STATS_CLASSES/2);*/
2060 static int tiqdio_thinint_handler(__u32 intparm)
2062 #ifdef QDIO_DBF_LIKE_HELL
2063 QDIO_DBF_TEXT4(0,trace,"thin_int");
2064 #endif /* QDIO_DBF_LIKE_HELL */
2066 #ifdef QDIO_PERFORMANCE_STATS
2067 perf_stats.thinints++;
2068 perf_stats.start_time_inbound=NOW;
2069 #endif /* QDIO_PERFORMANCE_STATS */
2071 /* SVS only when needed:
2072 * issue SVS to benefit from iqdio interrupt avoidance
2073 * (SVS clears AISOI)*/
2075 tiqdio_clear_global_summary();
2078 tiqdio_inbound_checks();
2082 static void qdio_set_state(qdio_irq_t *irq_ptr,int state)
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);
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;
2099 static void qdio_handler(int irq,devstat_t *devstat,struct pt_regs *p)
2101 qdio_irq_t *irq_ptr;
2106 char dbf_text[15]="qintXXXX";
2108 cstat = devstat->cstat;
2109 dstat = devstat->dstat;
2110 rqparam=devstat->intparm;
2112 *((int*)(&dbf_text[4]))=irq;
2113 QDIO_DBF_HEX4(0,trace,dbf_text,QDIO_DBF_TRACE_LEN);
2116 QDIO_PRINT_STUPID("got unsolicited interrupt in qdio " \
2117 "handler, irq 0x%x\n",irq);
2121 irq_ptr=qdio_get_irq_ptr(irq);
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",
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);
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]);
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;
2144 if ( (rqparam==QDIO_DOING_ACTIVATE) &&
2145 (cstat & SCHN_STAT_PCI) ) {
2146 #ifdef QDIO_PERFORMANCE_STATS
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)
2155 #ifdef QDIO_PERFORMANCE_STATS
2156 perf_stats.tl_runs--;
2157 #endif /* QDIO_PERFORMANCE_STATS */
2158 __qdio_inbound_processing(q);
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) {
2171 __qdio_outbound_processing(q);
2178 if ( (rqparam==QDIO_DOING_ACTIVATE) &&
2181 rqparam=QDIO_DOING_CLEANUP;
2184 if ( (rqparam==QDIO_DOING_ESTABLISH) &&
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",
2195 qdio_set_state(irq_ptr,QDIO_IRQ_STATE_STOPPED);
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);
2206 if ( (rqparam==QDIO_DOING_ACTIVATE) &&
2207 ( (cstat & ~SCHN_STAT_PCI) ||
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",
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];
2222 QDIO_PRINT_ERR("oops... no queue registered on irq " \
2224 goto omit_handler_call;
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);
2230 qdio_set_state(irq_ptr,QDIO_IRQ_STATE_STOPPED);
2234 qdio_wakeup(&irq_ptr->interrupt_has_arrived,irq_ptr);
2237 /* this is for mp3 */
2238 int qdio_synchronize(int irq,unsigned int flags,
2239 unsigned int queue_number)
2241 unsigned int gpr2,gpr3;
2244 qdio_irq_t *irq_ptr;
2245 char dbf_text[15]="SyncXXXX";
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);
2254 irq_ptr=qdio_get_irq_ptr(irq);
2255 if (!irq_ptr) return -ENODEV;
2257 if (flags&QDIO_FLAG_SYNC_INPUT) {
2258 q=irq_ptr->input_qs[queue_number];
2259 if (!q) return -EINVAL;
2263 } else if (flags&QDIO_FLAG_SYNC_OUTPUT) {
2264 q=irq_ptr->output_qs[queue_number];
2265 if (!q) return -EINVAL;
2269 } else return -EINVAL;
2281 : "d" (0x10000|q->irq), "d" (gpr2), "d" (gpr3)
2282 : "cc", "0", "1", "2", "3"
2284 #else /* QDIO_32_BIT */
2294 : "d" (0x10000|q->irq), "d" (gpr2), "d" (gpr3)
2295 : "cc", "0", "1", "2", "3"
2297 #endif /* QDIO_32_BIT */
2300 if (cc) QDIO_DBF_HEX3(0,trace,&ptr,sizeof(int));
2305 unsigned char qdio_get_slsb_state(int irq,unsigned int flag,
2306 unsigned int queue_number,
2309 qdio_irq_t *irq_ptr;
2312 irq_ptr=qdio_get_irq_ptr(irq);
2313 if (!irq_ptr) return SLSB_ERROR_DURING_LOOKUP;
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;
2321 return q->slsb.acc.val[qidx&(QDIO_MAX_BUFFERS_PER_Q-1)];
2324 static int qdio_chsc(qdio_chsc_area_t *chsc_area)
2330 ".insn rre,0xb25f0000,%1,0 \n\t"
2333 : "=d" (cc) : "d" (chsc_area) : "cc"
2335 #else /* QDIO_32_BIT */
2337 ".insn rre,0xb25f0000,%1,0 \n\t"
2340 : "=d" (cc) : "d" (chsc_area) : "cc"
2342 #endif /* QDIO_32_BIT */
2347 static unsigned char qdio_check_siga_needs(int sch)
2349 int resp_code,result;
2350 unsigned long flags;
2352 spin_lock_irqsave(&chsc_area_lock,flags);
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;
2360 result=qdio_chsc(chsc_area);
2363 QDIO_PRINT_WARN("CHSC returned cc %i. Using all " \
2364 "SIGAs for sch x%x.\n",
2366 result=-1; /* all flags set */
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",
2376 result=-1; /* all flags set */
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)
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 */
2395 result=chsc_area->request_block.operation_data_area.
2396 store_qdio_data_response.qdioac;
2398 spin_unlock_irqrestore(&chsc_area_lock,flags);
2402 static void qdio_check_for_machine_features(void)
2405 unsigned long flags;
2407 spin_lock_irqsave(&chsc_area_lock,flags);
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);
2415 QDIO_PRINT_WARN("CHSC returned cc %i. Won't use adapter " \
2416 "interrupts for any QDIO device.\n",result);
2421 i=chsc_area->request_block.operation_data_area.
2422 store_qdio_data_response.response_code;
2424 QDIO_PRINT_WARN("Was not able to determine general " \
2425 "characteristics of all QDIO devices " \
2434 /* check for bit 67 */
2435 if ( (*(((unsigned int*)(chsc_area))+4+2+2)&0x10000000)!=0x10000000) {
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) {
2449 spin_unlock_irqrestore(&chsc_area_lock,flags);
2452 /* the chsc_area is locked by the lock in qdio_activate */
2453 static unsigned int tiqdio_check_chsc_availability(void) {
2456 unsigned long flags;
2458 spin_lock_irqsave(&chsc_area_lock,flags);
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);
2465 QDIO_PRINT_WARN("Was not able to determine " \
2466 "available CHSCs, cc=%i.\n",
2472 i=chsc_area->request_block.operation_data_area.
2473 store_qdio_data_response.response_code;
2475 QDIO_PRINT_WARN("Was not able to determine " \
2476 "available CHSCs.\n");
2483 /* check for bit 41 */
2484 if ( (*(((unsigned int*)(chsc_area))+4+2+1)&0x00400000)!=0x00400000) {
2485 QDIO_PRINT_WARN("Adapter interruption facility not " \
2490 /* check for bits 107 and 108 */
2491 if ( (*(((unsigned int*)(chsc_area))+4+512+3)&0x00180000)!=
2493 QDIO_PRINT_WARN("Set Chan Subsys. Char. & Fast-CHSCs " \
2494 "not available.\n");
2499 spin_unlock_irqrestore(&chsc_area_lock,flags);
2503 /* the chsc_area is locked by the lock in qdio_activate */
2504 static unsigned int tiqdio_set_subchannel_ind(qdio_irq_t *irq_ptr,
2507 unsigned long real_addr_local_summary_bit;
2508 unsigned long real_addr_dev_st_chg_ind;
2510 unsigned long flags;
2513 unsigned int resp_code;
2516 if (!irq_ptr->is_thinint_irq) return -ENODEV;
2518 if (reset_to_zero) {
2519 real_addr_local_summary_bit=0;
2520 real_addr_dev_st_chg_ind=0;
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);
2528 spin_lock_irqsave(&chsc_area_lock,flags);
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;
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;
2549 result=qdio_chsc(chsc_area);
2551 QDIO_PRINT_WARN("could not set indicators on irq x%x, " \
2552 "cc=%i.\n",irq_ptr->irq,result);
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);
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));
2576 spin_unlock_irqrestore(&chsc_area_lock,flags);
2580 /* chsc_area would have to be locked if called from outside qdio_activate */
2581 static unsigned int tiqdio_set_delay_target(qdio_irq_t *irq_ptr,
2582 unsigned long delay_target)
2584 unsigned int resp_code;
2587 unsigned long flags;
2590 if (!irq_ptr->is_thinint_irq) return -ENODEV;
2592 spin_lock_irqsave(&chsc_area_lock,flags);
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;
2600 result=qdio_chsc(chsc_area);
2602 QDIO_PRINT_WARN("could not set delay target on irq x%x, " \
2603 "cc=%i. Continuing.\n",irq_ptr->irq,result);
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);
2618 QDIO_DBF_TEXT2(0,trace,"delytrgt");
2619 QDIO_DBF_HEX2(0,trace,&delay_target,sizeof(unsigned long));
2622 spin_unlock_irqrestore(&chsc_area_lock,flags);
2626 int qdio_cleanup(int irq,int how)
2628 qdio_irq_t *irq_ptr;
2630 int do_an_irqrestore=0;
2631 unsigned long flags;
2636 sprintf(dbf_text,"qcln%4x",irq);
2637 QDIO_DBF_TEXT1(0,trace,dbf_text);
2638 QDIO_DBF_TEXT0(0,setup,dbf_text);
2640 irq_ptr=qdio_get_irq_ptr(irq);
2641 if (!irq_ptr) return -ENODEV;
2643 down(&irq_ptr->setting_up_lock);
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);
2649 for (i=0;i<irq_ptr->no_output_qs;i++) {
2650 atomic_set(&irq_ptr->output_qs[i]->is_in_shutdown,1);
2653 tasklet_kill(&tiqdio_tasklet);
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]->
2660 result=-EINPROGRESS;
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]->
2667 result=-EINPROGRESS;
2670 atomic_set(&irq_ptr->interrupt_has_been_cleaned,0);
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;
2684 s390irq_spin_unlock_irqrestore(irq,flags);
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, " \
2691 (how==QDIO_FLAG_CLEANUP_USING_CLEAR)?
2692 "clear":"halt",irq);
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 */
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; */
2710 qdio_set_state(irq_ptr,QDIO_IRQ_STATE_INACTIVE);
2712 if (do_an_irqrestore)
2713 s390irq_spin_unlock_irqrestore(irq,flags);
2715 up(&irq_ptr->setting_up_lock);
2717 qdio_remove_irq_ptr(irq_ptr);
2718 qdio_release_irq_memory(irq_ptr);
2720 QDIO_DBF_TEXT3(0,setup,"MOD_DEC_");
2726 unsigned long qdio_get_characteristics(int irq)
2728 qdio_irq_t *irq_ptr;
2731 irq_ptr=qdio_get_irq_ptr(irq);
2732 if (!irq_ptr) return -ENODEV;
2734 if (irq_ptr->state!=QDIO_IRQ_STATE_ACTIVE) {
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;
2748 if (irq_ptr->hydra_gives_outbound_pcis)
2749 result|=QDIO_STATE_MUST_USE_OUTB_PCI;
2754 int qdio_initialize(qdio_initialize_t *init_data)
2757 unsigned long saveflags;
2758 qdio_irq_t *irq_ptr=NULL;
2761 unsigned long flags;
2762 char dbf_text[20]; /* if a printf printed out more than 8 chars */
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;
2798 if (qdio_get_irq_ptr(init_data->irq)) {
2803 if (ioinfo[init_data->irq]==INVALID_STORAGE_AREA) {
2808 if (!ioinfo[init_data->irq]) {
2809 QDIO_PRINT_WARN("ioinfo[%i] is NULL!\n",init_data->irq);
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",
2818 ioinfo[init_data->irq]->devstat.flag);
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)) ) {
2831 if ( (init_data->flags&QDIO_INBOUND_0COPY_SBALS)&&
2832 (!init_data->input_sbal_addr_array) ) {
2836 if ( (init_data->flags&QDIO_OUTBOUND_0COPY_SBALS)&&
2837 (!init_data->output_sbal_addr_array) ) {
2843 irq_ptr=kmalloc(sizeof(qdio_irq_t),GFP_DMA);
2845 QDIO_DBF_TEXT0(0,setup,"irq_ptr:");
2846 QDIO_DBF_HEX0(0,setup,&irq_ptr,sizeof(void*));
2849 QDIO_PRINT_ERR("kmalloc of irq_ptr failed!\n");
2854 memset(irq_ptr,0,sizeof(qdio_irq_t)); /* wipes qib.ac,
2855 required by ar7063 */
2857 irq_ptr->qdr=kmalloc(sizeof(qdr_t),GFP_DMA);
2858 if (!(irq_ptr->qdr)) {
2860 QDIO_PRINT_ERR("kmalloc of irq_ptr->qdr failed!\n");
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*));
2868 init_waitqueue_head(&irq_ptr->wait_q);
2870 irq_ptr->int_parm=init_data->int_parm;
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;
2876 if (init_data->q_format==QDIO_IQDIO_QFMT) {
2877 irq_ptr->is_iqdio_irq=1;
2878 irq_ptr->is_thinint_irq=1;
2880 irq_ptr->is_iqdio_irq=0;
2881 irq_ptr->is_thinint_irq=hydra_thinints;
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);
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);
2899 if (flags&QDIO_PFIX)
2900 irq_ptr->other_flags |= QDIO_PFIX;
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;
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);
2920 qdio_set_state(irq_ptr,QDIO_IRQ_STATE_INACTIVE);
2922 sema_init(&irq_ptr->setting_up_lock,1);
2925 QDIO_DBF_TEXT3(0,setup,"MOD_INC_");
2927 down(&irq_ptr->setting_up_lock);
2929 qdio_insert_irq_ptr(irq_ptr);
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);
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;
2945 irq_ptr->qdr->qiba=QDIO_PFIX_GET_ADDR(&irq_ptr->qib);
2946 irq_ptr->qdr->qkey=QDIO_STORAGE_ACC_KEY;
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);
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);
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;
2969 irq_ptr->qdr->qdf0[i].sliba=
2970 QDIO_PFIX_GET_ADDR(irq_ptr->input_qs[i]->slib);
2972 irq_ptr->qdr->qdf0[i].sla=
2973 QDIO_PFIX_GET_ADDR(irq_ptr->input_qs[i]->sl);
2975 irq_ptr->qdr->qdf0[i].slsba=
2977 ((void *)&irq_ptr->input_qs[i]->slsb.acc.val[0]);
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;
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;
2990 irq_ptr->qdr->qdf0[i+init_data->no_input_qs].sliba=
2991 QDIO_PFIX_GET_ADDR(irq_ptr->output_qs[i]->slib);
2993 irq_ptr->qdr->qdf0[i+init_data->no_input_qs].sla=
2994 QDIO_PFIX_GET_ADDR(irq_ptr->output_qs[i]->sl);
2996 irq_ptr->qdr->qdf0[i+init_data->no_input_qs].slsba=
2998 ((void *)&irq_ptr->output_qs[i]->slsb.acc.val[0]);
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;
3009 /* qdr, qib, sls, slsbs, slibs, sbales filled. */
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;
3015 /* insert qdio int handler */
3016 ioinfo[irq_ptr->irq]->irq_desc.handler=(void*)qdio_handler;
3018 s390irq_spin_unlock_irqrestore(irq_ptr->irq,saveflags);
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 */
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;
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) )
3038 QDIO_DBF_TEXT2(1,setup,"no ciws");
3039 QDIO_PRINT_INFO("No CIWs found for QDIO commands. Trying to " \
3043 /* the thinint CHSC stuff */
3044 if (irq_ptr->is_thinint_irq) {
3045 /* iqdio_enable_adapter_int_facility(irq_ptr);*/
3047 if (tiqdio_check_chsc_availability()) {
3048 QDIO_PRINT_ERR("Not all CHSCs supported. " \
3051 result=tiqdio_set_subchannel_ind(irq_ptr,0);
3053 up(&irq_ptr->setting_up_lock);
3054 qdio_cleanup(irq_ptr->irq,
3055 QDIO_FLAG_CLEANUP_USING_CLEAR);
3058 tiqdio_set_delay_target(irq_ptr,TIQDIO_DELAY_TARGET);
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));
3067 s390irq_spin_lock_irqsave(irq_ptr->irq,saveflags);
3068 atomic_set(&irq_ptr->interrupt_has_arrived,0);
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));
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);
3080 sprintf(dbf_text,"eq:io%4x",result);
3081 QDIO_DBF_TEXT2(1,setup,dbf_text);
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);
3089 s390irq_spin_unlock_irqrestore(irq_ptr->irq,saveflags);
3092 up(&irq_ptr->setting_up_lock);
3093 qdio_cleanup(irq_ptr->irq,QDIO_FLAG_CLEANUP_USING_CLEAR);
3097 result=qdio_sleepon(&irq_ptr->interrupt_has_arrived,
3098 QDIO_ESTABLISH_TIMEOUT,irq_ptr);
3101 QDIO_PRINT_ERR("establish queues on irq %04x: timed out\n",
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);
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, " \
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);
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);
3144 up(&irq_ptr->setting_up_lock);
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);
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) {
3157 sprintf(dbf_text,"qib ac%2x",irq_ptr->qib.ac);
3158 QDIO_DBF_TEXT2(0,setup,dbf_text);
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;
3164 irq_ptr->hydra_gives_outbound_pcis=0;
3166 irq_ptr->sync_done_on_outb_pcis=
3167 irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS;
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=
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) );
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=
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) );
3207 if (init_data->qib_param_field)
3208 memcpy(init_data->qib_param_field,irq_ptr->qib.parm,
3209 QDIO_MAX_BUFFERS_PER_Q);
3211 qdio_set_state(irq_ptr,QDIO_IRQ_STATE_ESTABLISHED);
3214 up(&irq_ptr->setting_up_lock);
3222 int qdio_activate(int irq,int flags)
3224 qdio_irq_t *irq_ptr;
3225 int i,result=0,result2;
3226 unsigned long saveflags;
3227 char dbf_text[20]; /* see qdio_initialize */
3229 irq_ptr=qdio_get_irq_ptr(irq);
3230 if (!irq_ptr) return -ENODEV;
3232 down(&irq_ptr->setting_up_lock);
3233 if (irq_ptr->state==QDIO_IRQ_STATE_INACTIVE) {
3238 sprintf(dbf_text,"qact%4x",irq);
3239 QDIO_DBF_TEXT2(0,setup,dbf_text);
3240 QDIO_DBF_TEXT2(0,trace,dbf_text);
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,
3249 s390irq_spin_lock_irqsave(irq_ptr->irq,saveflags);
3250 atomic_set(&irq_ptr->interrupt_has_arrived,0);
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));
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);
3263 sprintf(dbf_text,"aq:io%4x",result);
3264 QDIO_DBF_TEXT2(1,setup,dbf_text);
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);
3272 s390irq_spin_unlock_irqrestore(irq_ptr->irq,saveflags);
3277 if (!(flags&QDIO_FLAG_UNDER_INTERRUPT)) {
3278 result=qdio_sleepon(&irq_ptr->interrupt_has_arrived,
3279 QDIO_ACTIVATE_TIMEOUT,irq_ptr);
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);
3297 } else { /* result is -ETIME, but timeout is ok for us */
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
3306 * by tiqdio_inbound_processing,
3307 * qdio_unmark_q will
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]);
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;
3322 qdio_wait_nonbusy(QDIO_ACTIVATE_DELAY);
3324 qdio_set_state(irq_ptr,QDIO_IRQ_STATE_ACTIVE);
3327 up(&irq_ptr->setting_up_lock);
3332 /* buffers filled forwards again to make Rick happy */
3333 static inline void qdio_do_qdio_fill_input(qdio_q_t *q,unsigned int qidx,
3335 qdio_buffer_t *buffers)
3338 if (!q->is_0copy_sbals_q) {
3339 memcpy((void*)q->sbal[qidx],buffers,SBAL_SIZE);
3340 q->qdio_buffers[qidx]=buffers;
3343 set_slsb(&q->slsb.acc.val[qidx],SLSB_CU_INPUT_EMPTY);
3346 qidx=(qidx+1)&(QDIO_MAX_BUFFERS_PER_Q-1);
3349 /* not necessary, as the queues are synced during the SIGA read
3353 static inline void qdio_do_qdio_fill_output(qdio_q_t *q,unsigned int qidx,
3355 qdio_buffer_t *buffers)
3358 if (!q->is_0copy_sbals_q) {
3359 memcpy((void*)q->sbal[qidx],buffers,SBAL_SIZE);
3360 q->qdio_buffers[qidx]=buffers;
3363 set_slsb(&q->slsb.acc.val[qidx],SLSB_CU_OUTPUT_PRIMED);
3366 qidx=(qidx+1)&(QDIO_MAX_BUFFERS_PER_Q-1);
3369 /* SIGA write will sync the queues
3373 /* count must be 1 in iqdio */
3374 int do_QDIO(int irq,unsigned int callflags,unsigned int queue_number,
3375 unsigned int qidx,unsigned int count,qdio_buffer_t *buffers)
3378 qdio_irq_t *irq_ptr;
3382 #ifdef QDIO_DBF_LIKE_HELL
3385 sprintf(dbf_text,"doQD%04x",irq);
3386 QDIO_DBF_TEXT3(0,trace,dbf_text);
3387 #endif /* QDIO_DBF_LIKE_HELL */
3389 if ( (qidx>QDIO_MAX_BUFFERS_PER_Q) ||
3390 (count>QDIO_MAX_BUFFERS_PER_Q) ||
3391 (queue_number>QDIO_MAX_QUEUES_PER_IRQ) )
3394 if (count==0) return 0;
3396 irq_ptr=qdio_get_irq_ptr(irq);
3397 if (!irq_ptr) return -ENODEV;
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],
3404 QDIO_DBF_HEX3(0,trace,&irq_ptr->output_qs[queue_number],
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 */
3417 if (irq_ptr->state!=QDIO_IRQ_STATE_ACTIVE) {
3421 if (callflags&QDIO_FLAG_SYNC_INPUT) {
3422 /* This is the inbound handling of queues */
3423 q=irq_ptr->input_qs[queue_number];
3425 used_elements=atomic_return_add(count,
3426 &q->number_of_buffers_used);
3428 qdio_do_qdio_fill_input(q,qidx,count,buffers);
3430 if ((used_elements+count==QDIO_MAX_BUFFERS_PER_Q)&&
3431 (callflags&QDIO_FLAG_UNDER_INTERRUPT))
3432 atomic_swap(&q->polling,0);
3434 if (!used_elements) if (!(callflags&QDIO_FLAG_DONT_SIGA)) {
3436 result=qdio_siga_input(q);
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;
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];
3456 qdio_do_qdio_fill_output(q,qidx,count,buffers);
3458 used_elements=atomic_return_add(count,
3459 &q->number_of_buffers_used);
3461 if (!(callflags&QDIO_FLAG_DONT_SIGA)) {
3462 if (q->is_iqdio_q) {
3463 /* one siga for every sbal */
3465 qdio_kick_outbound_q(q);
3468 __qdio_outbound_processing(q);
3470 /* under VM, we do a SIGA sync
3471 * unconditionally */
3474 /* w/o shadow queues (else branch of
3475 * SYNC_MEMORY :-/ ), we try to
3476 * fast-requeue buffers */
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);
3483 #ifdef QDIO_DBF_LIKE_HELL
3484 QDIO_DBF_TEXT3(0,trace,
3486 #endif /* QDIO_DBF_LIKE_HELL */
3487 #ifdef QDIO_PERFORMANCE_STATS
3488 perf_stats.fast_reqs++;
3489 #endif /* QDIO_PERFORMANCE_STATS */
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);
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 */
3505 QDIO_DBF_TEXT3(1,trace,"doQD:inv");
3511 #ifdef QDIO_PERFORMANCE_STATS
3512 static int qdio_perf_procfile_read(char *buffer,char **buffer_location,
3513 off_t offset,int buffer_length,int *eof,
3517 qdio_irq_t *irq_ptr;
3519 /* we are always called with buffer_length=4k, so we all
3520 deliver on the first read */
3521 if (offset>0) return 0;
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);
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",
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);
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);
3553 for (bucket=0;bucket<QDIO_IRQ_BUCKETS;bucket++) {
3554 irq_ptr=first_irq[bucket];
3557 _OUTP_IT("Polling time on irq %4x" \
3559 irq_ptr->irq,irq_ptr->input_qs[0]->
3561 irq_ptr=irq_ptr->next;
3568 static struct proc_dir_entry *qdio_perf_proc_file;
3569 #endif /* QDIO_PERFORMANCE_STATS */
3571 static void qdio_add_procfs_entry(void)
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;
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 */
3588 static void qdio_remove_procfs_entry(void)
3590 #ifdef QDIO_PERFORMANCE_STATS
3591 perf_stats.tl_runs=0;
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 */
3599 static void tiqdio_register_thinints(void)
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);
3615 static void tiqdio_unregister_thinints(void)
3617 if (!register_thinint_result)
3618 s390_unregister_adapter_interrupt(&tiqdio_thinint_handler);
3622 static int qdio_get_qdio_memory(void)
3625 indicator_used[0]=1;
3627 for (i=1;i<INDICATORS_PER_CACHELINE;i++)
3628 indicator_used[i]=0;
3629 indicators=(__u32*)kmalloc(sizeof(__u32)*(INDICATORS_PER_CACHELINE),
3631 if (!indicators) return -ENOMEM;
3632 memset(indicators,0,sizeof(__u32)*(INDICATORS_PER_CACHELINE));
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*)); \
3639 /* ahem... let's call it data area */
3640 QDIO_PRINT_ERR("not enough memory for data area. Cannot " \
3641 "initialize QDIO.\n");
3645 memset(chsc_area,0,sizeof(qdio_chsc_area_t));
3650 static void qdio_release_qdio_memory(void)
3653 if (indicators) kfree(indicators);
3657 int init_module(void); /* we want to use it in init_QDIO */
3659 static void qdio_unregister_dbf_views(void)
3662 debug_unregister(qdio_dbf_setup);
3664 debug_unregister(qdio_dbf_sbal);
3666 debug_unregister(qdio_dbf_sense);
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 */
3677 /* this is not __initfunc, as it is called from init_module */
3682 #if defined(MODULE)||defined(QDIO_PERFORMANCE_STATS)
3684 #endif /* defined(MODULE)||defined(QDIO_PERFORMANCE_STATS) */
3688 printk("qdio: loading %s\n",version);
3690 res=qdio_get_qdio_memory();
3691 if (res) return res;
3693 sema_init(&init_sema,1);
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);
3703 qdio_dbf_sbal=debug_register(QDIO_DBF_SBAL_NAME,
3704 QDIO_DBF_SBAL_INDEX,
3705 QDIO_DBF_SBAL_NR_AREAS,
3707 if (!qdio_dbf_sbal) goto oom;
3709 debug_register_view(qdio_dbf_sbal,&debug_hex_ascii_view);
3710 debug_set_level(qdio_dbf_sbal,QDIO_DBF_SBAL_LEVEL);
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;
3718 debug_register_view(qdio_dbf_sense,&debug_hex_ascii_view);
3719 debug_set_level(qdio_dbf_sense,QDIO_DBF_SENSE_LEVEL);
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;
3727 debug_register_view(qdio_dbf_trace,&debug_hex_ascii_view);
3728 debug_set_level(qdio_dbf_trace,QDIO_DBF_TRACE_LEVEL);
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);
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 */
3748 #ifdef QDIO_PERFORMANCE_STATS
3749 memset((void*)&perf_stats,0,sizeof(perf_stats));
3750 QDIO_DBF_TEXT0(0,setup,"perfstat");
3752 QDIO_DBF_HEX0(0,setup,&ptr,sizeof(void*));
3753 #endif /* QDIO_PERFORMANCE_STATS */
3756 QDIO_DBF_TEXT0(0,setup,"initmodl");
3758 QDIO_DBF_HEX0(0,setup,&ptr,sizeof(void*));
3761 qdio_add_procfs_entry();
3763 qdio_check_for_machine_features();
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);
3770 tiqdio_register_thinints();
3774 QDIO_PRINT_ERR("not enough memory for dbf.\n");
3775 qdio_unregister_dbf_views();
3780 int init_module(void)
3785 void cleanup_module(void)
3787 tiqdio_unregister_thinints();
3789 qdio_remove_procfs_entry();
3791 qdio_release_qdio_memory();
3793 qdio_unregister_dbf_views();
3795 printk("qdio: %s: module removed\n",version);
3798 static int __init initcall_QDIO(void)
3802 __initcall(initcall_QDIO);
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);