Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / s390 / cio / qdio.h
index b6daada..ceb3ab3 100644 (file)
@@ -3,14 +3,13 @@
 
 #include <asm/page.h>
 
-#define VERSION_CIO_QDIO_H "$Revision: 1.32 $"
+#include "schid.h"
 
 #ifdef CONFIG_QDIO_DEBUG
 #define QDIO_VERBOSE_LEVEL 9
 #else /* CONFIG_QDIO_DEBUG */
 #define QDIO_VERBOSE_LEVEL 5
 #endif /* CONFIG_QDIO_DEBUG */
-
 #define QDIO_USE_PROCESSING_STATE
 
 #ifdef CONFIG_QDIO_PERF_STATS
@@ -132,7 +131,7 @@ enum qdio_irq_states {
 
 #define QDIO_DBF_SETUP_NAME "qdio_setup"
 #define QDIO_DBF_SETUP_LEN 8
-#define QDIO_DBF_SETUP_INDEX 2
+#define QDIO_DBF_SETUP_PAGES 4
 #define QDIO_DBF_SETUP_NR_AREAS 1
 #ifdef CONFIG_QDIO_DEBUG
 #define QDIO_DBF_SETUP_LEVEL 6
@@ -142,7 +141,7 @@ enum qdio_irq_states {
 
 #define QDIO_DBF_SBAL_NAME "qdio_labs" /* sbal */
 #define QDIO_DBF_SBAL_LEN 256
-#define QDIO_DBF_SBAL_INDEX 2
+#define QDIO_DBF_SBAL_PAGES 4
 #define QDIO_DBF_SBAL_NR_AREAS 2
 #ifdef CONFIG_QDIO_DEBUG
 #define QDIO_DBF_SBAL_LEVEL 6
@@ -154,16 +153,16 @@ enum qdio_irq_states {
 #define QDIO_DBF_TRACE_LEN 8
 #define QDIO_DBF_TRACE_NR_AREAS 2
 #ifdef CONFIG_QDIO_DEBUG
-#define QDIO_DBF_TRACE_INDEX 4
+#define QDIO_DBF_TRACE_PAGES 16
 #define QDIO_DBF_TRACE_LEVEL 4 /* -------- could be even more verbose here */
 #else /* CONFIG_QDIO_DEBUG */
-#define QDIO_DBF_TRACE_INDEX 2
+#define QDIO_DBF_TRACE_PAGES 4
 #define QDIO_DBF_TRACE_LEVEL 2
 #endif /* CONFIG_QDIO_DEBUG */
 
 #define QDIO_DBF_SENSE_NAME "qdio_sense"
 #define QDIO_DBF_SENSE_LEN 64
-#define QDIO_DBF_SENSE_INDEX 1
+#define QDIO_DBF_SENSE_PAGES 2
 #define QDIO_DBF_SENSE_NR_AREAS 1
 #ifdef CONFIG_QDIO_DEBUG
 #define QDIO_DBF_SENSE_LEVEL 6
@@ -176,13 +175,13 @@ enum qdio_irq_states {
 
 #define QDIO_DBF_SLSB_OUT_NAME "qdio_slsb_out"
 #define QDIO_DBF_SLSB_OUT_LEN QDIO_MAX_BUFFERS_PER_Q
-#define QDIO_DBF_SLSB_OUT_INDEX 8
+#define QDIO_DBF_SLSB_OUT_PAGES 256
 #define QDIO_DBF_SLSB_OUT_NR_AREAS 1
 #define QDIO_DBF_SLSB_OUT_LEVEL 6
 
 #define QDIO_DBF_SLSB_IN_NAME "qdio_slsb_in"
 #define QDIO_DBF_SLSB_IN_LEN QDIO_MAX_BUFFERS_PER_Q
-#define QDIO_DBF_SLSB_IN_INDEX 8
+#define QDIO_DBF_SLSB_IN_PAGES 256
 #define QDIO_DBF_SLSB_IN_NR_AREAS 1
 #define QDIO_DBF_SLSB_IN_LEVEL 6
 #endif /* CONFIG_QDIO_DEBUG */
@@ -265,12 +264,64 @@ QDIO_PRINT_##importance(header "%02x %02x %02x %02x  %02x %02x %02x %02x  " \
 /*
  * Some instructions as assembly
  */
-extern __inline__ int 
-do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2)
+
+static inline int
+do_sqbs(unsigned long sch, unsigned char state, int queue,
+       unsigned int *start, unsigned int *count)
+{
+#ifdef CONFIG_64BIT
+       register unsigned long _ccq asm ("0") = *count;
+       register unsigned long _sch asm ("1") = sch;
+       unsigned long _queuestart = ((unsigned long)queue << 32) | *start;
+
+       asm volatile (
+              " .insn rsy,0xeb000000008A,%1,0,0(%2)\n\t"
+              : "+d" (_ccq), "+d" (_queuestart)
+              : "d" ((unsigned long)state), "d" (_sch)
+              : "memory", "cc"
+       );
+       *count = _ccq & 0xff;
+       *start = _queuestart & 0xff;
+
+       return (_ccq >> 32) & 0xff;
+#else
+       return 0;
+#endif
+}
+
+static inline int
+do_eqbs(unsigned long sch, unsigned char *state, int queue,
+       unsigned int *start, unsigned int *count)
+{
+#ifdef CONFIG_64BIT
+       register unsigned long _ccq asm ("0") = *count;
+       register unsigned long _sch asm ("1") = sch;
+       unsigned long _queuestart = ((unsigned long)queue << 32) | *start;
+       unsigned long _state = 0;
+
+       asm volatile (
+             " .insn rrf,0xB99c0000,%1,%2,0,0  \n\t"
+             : "+d" (_ccq), "+d" (_queuestart), "+d" (_state)
+             : "d" (_sch)
+             : "memory", "cc"
+       );
+       *count = _ccq & 0xff;
+       *start = _queuestart & 0xff;
+       *state = _state & 0xff;
+
+       return (_ccq >> 32) & 0xff;
+#else
+       return 0;
+#endif
+}
+
+
+static inline int
+do_siga_sync(struct subchannel_id schid, unsigned int mask1, unsigned int mask2)
 {
        int cc;
 
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
        asm volatile (
                "lhi    0,2     \n\t"
                "lr     1,%1    \n\t"
@@ -280,10 +331,10 @@ do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2)
                "ipm    %0      \n\t"
                "srl    %0,28   \n\t"
                : "=d" (cc)
-               : "d" (0x10000|irq), "d" (mask1), "d" (mask2)
+               : "d" (schid), "d" (mask1), "d" (mask2)
                : "cc", "0", "1", "2", "3"
                );
-#else /* CONFIG_ARCH_S390X */
+#else /* CONFIG_64BIT */
        asm volatile (
                "lghi   0,2     \n\t"
                "llgfr  1,%1    \n\t"
@@ -293,19 +344,19 @@ do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2)
                "ipm    %0      \n\t"
                "srl    %0,28   \n\t"
                : "=d" (cc)
-               : "d" (0x10000|irq), "d" (mask1), "d" (mask2)
+               : "d" (schid), "d" (mask1), "d" (mask2)
                : "cc", "0", "1", "2", "3"
                );
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
        return cc;
 }
 
-extern __inline__ int
-do_siga_input(unsigned int irq, unsigned int mask)
+static inline int
+do_siga_input(struct subchannel_id schid, unsigned int mask)
 {
        int cc;
 
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
        asm volatile (
                "lhi    0,1     \n\t"
                "lr     1,%1    \n\t"
@@ -314,10 +365,10 @@ do_siga_input(unsigned int irq, unsigned int mask)
                "ipm    %0      \n\t"
                "srl    %0,28   \n\t"
                : "=d" (cc)
-               : "d" (0x10000|irq), "d" (mask)
+               : "d" (schid), "d" (mask)
                : "cc", "0", "1", "2", "memory"
                );
-#else /* CONFIG_ARCH_S390X */
+#else /* CONFIG_64BIT */
        asm volatile (
                "lghi   0,1     \n\t"
                "llgfr  1,%1    \n\t"
@@ -326,21 +377,22 @@ do_siga_input(unsigned int irq, unsigned int mask)
                "ipm    %0      \n\t"
                "srl    %0,28   \n\t"
                : "=d" (cc)
-               : "d" (0x10000|irq), "d" (mask)
+               : "d" (schid), "d" (mask)
                : "cc", "0", "1", "2", "memory"
                );
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
        
        return cc;
 }
 
-extern __inline__ int
-do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb)
+static inline int
+do_siga_output(unsigned long schid, unsigned long mask, __u32 *bb,
+              unsigned int fc)
 {
        int cc;
        __u32 busy_bit;
 
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
        asm volatile (
                "lhi    0,0     \n\t"
                "lr     1,%2    \n\t"
@@ -366,14 +418,14 @@ do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb)
                ".long  0b,2b   \n\t"
                ".previous      \n\t"
                : "=d" (cc), "=d" (busy_bit)
-               : "d" (0x10000|irq), "d" (mask),
+               : "d" (schid), "d" (mask),
                "i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION)
                : "cc", "0", "1", "2", "memory"
                );
-#else /* CONFIG_ARCH_S390X */
+#else /* CONFIG_64BIT */
        asm volatile (
-               "lghi   0,0     \n\t"
-               "llgfr  1,%2    \n\t"
+               "llgfr  0,%5    \n\t"
+                "lgr    1,%2    \n\t"
                "llgfr  2,%3    \n\t"
                "siga   0       \n\t"
                "0:"
@@ -391,37 +443,37 @@ do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb)
                ".quad  0b,1b   \n\t"
                ".previous      \n\t"
                : "=d" (cc), "=d" (busy_bit)
-               : "d" (0x10000|irq), "d" (mask),
-               "i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION)
+               : "d" (schid), "d" (mask),
+               "i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION), "d" (fc)
                : "cc", "0", "1", "2", "memory"
                );
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
        
        (*bb) = busy_bit;
        return cc;
 }
 
-extern __inline__ unsigned long
+static inline unsigned long
 do_clear_global_summary(void)
 {
 
        unsigned long time;
 
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
        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 */
+#else /* CONFIG_64BIT */
        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 */
+#endif /* CONFIG_64BIT */
        
        return time;
 }
@@ -488,42 +540,21 @@ struct qdio_perf_stats {
 
 #define MY_MODULE_STRING(x) #x
 
-#ifdef CONFIG_ARCH_S390X
+#ifdef CONFIG_64BIT
 #define QDIO_GET_ADDR(x) ((__u32)(unsigned long)x)
-#else /* CONFIG_ARCH_S390X */
+#else /* CONFIG_64BIT */
 #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 */
+#endif /* CONFIG_64BIT */
 
 struct qdio_q {
        volatile struct slsb slsb;
 
        char unused[QDIO_MAX_BUFFERS_PER_Q];
 
-       __u32 * volatile dev_st_chg_ind;
+       __u32 * dev_st_chg_ind;
 
        int is_input_q;
-       int irq;
+       struct subchannel_id schid;
        struct ccw_device *cdev;
 
        unsigned int is_iqdio_q;
@@ -568,6 +599,7 @@ struct qdio_q {
        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 */
@@ -617,13 +649,17 @@ struct qdio_irq {
        __u32 * volatile dev_st_chg_ind;
 
        unsigned long int_parm;
-       int irq;
+       struct subchannel_id schid;
 
        unsigned int is_iqdio_irq;
        unsigned int is_thinint_irq;
        unsigned int hydra_gives_outbound_pcis;
        unsigned int sync_done_on_outb_pcis;
 
+       /* QEBSM facility */
+       unsigned int is_qebsm;
+       unsigned long sch_token;
+
        enum qdio_irq_states state;
 
        unsigned int no_input_qs;