📄 qdio.h
字号:
"srl %0,28 \n\t" : "=d" (cc) : "d" (0x10000|irq), "d" (mask) : "cc", "0", "1", "2", "memory" );#endif /* CONFIG_ARCH_S390X */ return cc;}static inline intdo_siga_output(unsigned long irq, unsigned long mask, __u32 *bb){ int cc; __u32 busy_bit;#ifndef CONFIG_ARCH_S390X asm volatile ( "lhi 0,0 \n\t" "lr 1,%2 \n\t" "lr 2,%3 \n\t" "siga 0 \n\t" "0:" "ipm %0 \n\t" "srl %0,28 \n\t" "srl 0,31 \n\t" "lr %1,0 \n\t" "1: \n\t" ".section .fixup,\"ax\"\n\t" "2: \n\t" "lhi %0,%4 \n\t" "bras 1,3f \n\t" ".long 1b \n\t" "3: \n\t" "l 1,0(1) \n\t" "br 1 \n\t" ".previous \n\t" ".section __ex_table,\"a\"\n\t" ".align 4 \n\t" ".long 0b,2b \n\t" ".previous \n\t" : "=d" (cc), "=d" (busy_bit) : "d" (0x10000|irq), "d" (mask), "i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION) : "cc", "0", "1", "2", "memory" );#else /* CONFIG_ARCH_S390X */ asm volatile ( "lghi 0,0 \n\t" "llgfr 1,%2 \n\t" "llgfr 2,%3 \n\t" "siga 0 \n\t" "0:" "ipm %0 \n\t" "srl %0,28 \n\t" "srl 0,31 \n\t" "llgfr %1,0 \n\t" "1: \n\t" ".section .fixup,\"ax\"\n\t" "lghi %0,%4 \n\t" "jg 1b \n\t" ".previous\n\t" ".section __ex_table,\"a\"\n\t" ".align 8 \n\t" ".quad 0b,1b \n\t" ".previous \n\t" : "=d" (cc), "=d" (busy_bit) : "d" (0x10000|irq), "d" (mask), "i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION) : "cc", "0", "1", "2", "memory" );#endif /* CONFIG_ARCH_S390X */ (*bb) = busy_bit; return cc;}static inline unsigned longdo_clear_global_summary(void){ unsigned long time;#ifndef CONFIG_ARCH_S390X asm volatile ( "lhi 1,3 \n\t" ".insn rre,0xb2650000,2,0 \n\t" "lr %0,3 \n\t" : "=d" (time) : : "cc", "1", "2", "3" );#else /* CONFIG_ARCH_S390X */ asm volatile ( "lghi 1,3 \n\t" ".insn rre,0xb2650000,2,0 \n\t" "lgr %0,3 \n\t" : "=d" (time) : : "cc", "1", "2", "3" );#endif /* CONFIG_ARCH_S390X */ return time;} /* * QDIO device commands returned by extended Sense-ID */#define DEFAULT_ESTABLISH_QS_CMD 0x1b#define DEFAULT_ESTABLISH_QS_COUNT 0x1000#define DEFAULT_ACTIVATE_QS_CMD 0x1f#define DEFAULT_ACTIVATE_QS_COUNT 0/* * additional CIWs returned by extended Sense-ID */#define CIW_TYPE_EQUEUE 0x3 /* establish QDIO queues */#define CIW_TYPE_AQUEUE 0x4 /* activate QDIO queues */#define QDIO_CHSC_RESPONSE_CODE_OK 1/* flags for st qdio sch data */#define CHSC_FLAG_QDIO_CAPABILITY 0x80#define CHSC_FLAG_VALIDITY 0x40#define CHSC_FLAG_SIGA_INPUT_NECESSARY 0x40#define CHSC_FLAG_SIGA_OUTPUT_NECESSARY 0x20#define CHSC_FLAG_SIGA_SYNC_NECESSARY 0x10#define CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS 0x08#define CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS 0x04#ifdef QDIO_PERFORMANCE_STATSstruct qdio_perf_stats { unsigned int tl_runs; unsigned int siga_outs; unsigned int siga_ins; unsigned int siga_syncs; unsigned int pcis; unsigned int thinints; unsigned int fast_reqs; __u64 start_time_outbound; unsigned int outbound_cnt; unsigned int outbound_time; __u64 start_time_inbound; unsigned int inbound_cnt; unsigned int inbound_time;};#endif /* QDIO_PERFORMANCE_STATS */#define atomic_swap(a,b) xchg((int*)a.counter,b)/* unlikely as the later the better */#define SYNC_MEMORY if (unlikely(q->siga_sync)) qdio_siga_sync_q(q)#define SYNC_MEMORY_ALL if (unlikely(q->siga_sync)) \ qdio_siga_sync(q,~0U,~0U)#define SYNC_MEMORY_ALL_OUTB if (unlikely(q->siga_sync)) \ qdio_siga_sync(q,~0U,0)#define NOW qdio_get_micros()#define SAVE_TIMESTAMP(q) q->timing.last_transfer_time=NOW#define GET_SAVED_TIMESTAMP(q) (q->timing.last_transfer_time)#define SAVE_FRONTIER(q,val) q->last_move_ftc=val#define GET_SAVED_FRONTIER(q) (q->last_move_ftc)#define MY_MODULE_STRING(x) #x#ifdef CONFIG_ARCH_S390X#define QDIO_GET_ADDR(x) ((__u32)(unsigned long)x)#else /* CONFIG_ARCH_S390X */#define QDIO_GET_ADDR(x) ((__u32)(long)x)#endif /* CONFIG_ARCH_S390X */#ifdef CONFIG_QDIO_DEBUG#define set_slsb(x,y) \ if(q->queue_type==QDIO_TRACE_QTYPE) { \ if(q->is_input_q) { \ QDIO_DBF_HEX2(0,slsb_in,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \ } else { \ QDIO_DBF_HEX2(0,slsb_out,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \ } \ } \ qdio_set_slsb(x,y); \ if(q->queue_type==QDIO_TRACE_QTYPE) { \ if(q->is_input_q) { \ QDIO_DBF_HEX2(0,slsb_in,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \ } else { \ QDIO_DBF_HEX2(0,slsb_out,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \ } \ }#else /* CONFIG_QDIO_DEBUG */#define set_slsb(x,y) qdio_set_slsb(x,y)#endif /* CONFIG_QDIO_DEBUG */struct qdio_q { volatile struct slsb slsb; char unused[QDIO_MAX_BUFFERS_PER_Q]; __u32 * volatile dev_st_chg_ind; int is_input_q; int irq; struct ccw_device *cdev; unsigned int is_iqdio_q; unsigned int is_thinint_q; /* bit 0 means queue 0, bit 1 means queue 1, ... */ unsigned int mask; unsigned int q_no; qdio_handler_t (*handler); /* points to the next buffer to be checked for having * been processed by the card (outbound) * or to the next buffer the program should check for (inbound) */ volatile int first_to_check; /* and the last time it was: */ volatile int last_move_ftc; atomic_t number_of_buffers_used; atomic_t polling; unsigned int siga_in; unsigned int siga_out; unsigned int siga_sync; unsigned int siga_sync_done_on_thinints; unsigned int siga_sync_done_on_outb_tis; unsigned int hydra_gives_outbound_pcis; /* used to save beginning position when calling dd_handlers */ int first_element_to_kick; atomic_t use_count; atomic_t is_in_shutdown; void *irq_ptr;#ifdef QDIO_USE_TIMERS_FOR_POLLING struct timer_list timer; atomic_t timer_already_set; spinlock_t timer_lock;#else /* QDIO_USE_TIMERS_FOR_POLLING */ struct tasklet_struct tasklet;#endif /* QDIO_USE_TIMERS_FOR_POLLING */ enum qdio_irq_states state; /* used to store the error condition during a data transfer */ unsigned int qdio_error; unsigned int siga_error; unsigned int error_status_flags; /* list of interesting queues */ volatile struct qdio_q *list_next; volatile struct qdio_q *list_prev; struct sl *sl; volatile struct sbal *sbal[QDIO_MAX_BUFFERS_PER_Q]; struct qdio_buffer *qdio_buffers[QDIO_MAX_BUFFERS_PER_Q]; unsigned long int_parm; /*struct { int in_bh_check_limit; int threshold; } threshold_classes[QDIO_STATS_CLASSES];*/ struct { /* inbound: the time to stop polling outbound: the time to kick peer */ int threshold; /* the real value */ /* outbound: last time of do_QDIO inbound: last time of noticing incoming data */ /*__u64 last_transfer_times[QDIO_STATS_NUMBER]; int last_transfer_index; */ __u64 last_transfer_time; __u64 busy_start; } timing; atomic_t busy_siga_counter; unsigned int queue_type; /* leave this member at the end. won't be cleared in qdio_fill_qs */ struct slib *slib; /* a page is allocated under this pointer, sl points into this page, offset PAGE_SIZE/2 (after slib) */} __attribute__ ((aligned(256)));struct qdio_irq { __u32 * volatile dev_st_chg_ind; unsigned long int_parm; int irq; unsigned int is_iqdio_irq; unsigned int is_thinint_irq; unsigned int hydra_gives_outbound_pcis; unsigned int sync_done_on_outb_pcis; enum qdio_irq_states state; unsigned int no_input_qs; unsigned int no_output_qs; unsigned char qdioac; struct ccw1 ccw; struct ciw equeue; struct ciw aqueue; struct qib qib; void (*original_int_handler) (struct ccw_device *, unsigned long, struct irb *); /* leave these four members together at the end. won't be cleared in qdio_fill_irq */ struct qdr *qdr; struct qdio_q *input_qs[QDIO_MAX_QUEUES_PER_IRQ]; struct qdio_q *output_qs[QDIO_MAX_QUEUES_PER_IRQ]; struct semaphore setting_up_sema;};#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -