Merge branches 'release', 'misc' and 'misc-2.6.25' into release
[linux-2.6] / drivers / s390 / cio / io_sch.h
1 #ifndef S390_IO_SCH_H
2 #define S390_IO_SCH_H
3
4 #include "schid.h"
5
6 /*
7  * operation request block
8  */
9 struct orb {
10         u32 intparm;    /* interruption parameter */
11         u32 key  : 4;   /* flags, like key, suspend control, etc. */
12         u32 spnd : 1;   /* suspend control */
13         u32 res1 : 1;   /* reserved */
14         u32 mod  : 1;   /* modification control */
15         u32 sync : 1;   /* synchronize control */
16         u32 fmt  : 1;   /* format control */
17         u32 pfch : 1;   /* prefetch control */
18         u32 isic : 1;   /* initial-status-interruption control */
19         u32 alcc : 1;   /* address-limit-checking control */
20         u32 ssic : 1;   /* suppress-suspended-interr. control */
21         u32 res2 : 1;   /* reserved */
22         u32 c64  : 1;   /* IDAW/QDIO 64 bit control  */
23         u32 i2k  : 1;   /* IDAW 2/4kB block size control */
24         u32 lpm  : 8;   /* logical path mask */
25         u32 ils  : 1;   /* incorrect length */
26         u32 zero : 6;   /* reserved zeros */
27         u32 orbx : 1;   /* ORB extension control */
28         u32 cpa;        /* channel program address */
29 }  __attribute__ ((packed, aligned(4)));
30
31 struct io_subchannel_private {
32         struct orb orb;         /* operation request block */
33         struct ccw1 sense_ccw;  /* static ccw for sense command */
34 } __attribute__ ((aligned(8)));
35
36 #define to_io_private(n) ((struct io_subchannel_private *)n->private)
37 #define sch_get_cdev(n) (dev_get_drvdata(&n->dev))
38 #define sch_set_cdev(n, c) (dev_set_drvdata(&n->dev, c))
39
40 #define MAX_CIWS 8
41
42 /*
43  * sense-id response buffer layout
44  */
45 struct senseid {
46         /* common part */
47         u8  reserved;   /* always 0x'FF' */
48         u16 cu_type;    /* control unit type */
49         u8  cu_model;   /* control unit model */
50         u16 dev_type;   /* device type */
51         u8  dev_model;  /* device model */
52         u8  unused;     /* padding byte */
53         /* extended part */
54         struct ciw ciw[MAX_CIWS];       /* variable # of CIWs */
55 }  __attribute__ ((packed, aligned(4)));
56
57 struct ccw_device_private {
58         struct ccw_device *cdev;
59         struct subchannel *sch;
60         int state;              /* device state */
61         atomic_t onoff;
62         unsigned long registered;
63         struct ccw_dev_id dev_id;       /* device id */
64         struct subchannel_id schid;     /* subchannel number */
65         u8 imask;               /* lpm mask for SNID/SID/SPGID */
66         int iretry;             /* retry counter SNID/SID/SPGID */
67         struct {
68                 unsigned int fast:1;    /* post with "channel end" */
69                 unsigned int repall:1;  /* report every interrupt status */
70                 unsigned int pgroup:1;  /* do path grouping */
71                 unsigned int force:1;   /* allow forced online */
72         } __attribute__ ((packed)) options;
73         struct {
74                 unsigned int pgid_single:1; /* use single path for Set PGID */
75                 unsigned int esid:1;        /* Ext. SenseID supported by HW */
76                 unsigned int dosense:1;     /* delayed SENSE required */
77                 unsigned int doverify:1;    /* delayed path verification */
78                 unsigned int donotify:1;    /* call notify function */
79                 unsigned int recog_done:1;  /* dev. recog. complete */
80                 unsigned int fake_irb:1;    /* deliver faked irb */
81                 unsigned int intretry:1;    /* retry internal operation */
82         } __attribute__((packed)) flags;
83         unsigned long intparm;  /* user interruption parameter */
84         struct qdio_irq *qdio_data;
85         struct irb irb;         /* device status */
86         struct senseid senseid; /* SenseID info */
87         struct pgid pgid[8];    /* path group IDs per chpid*/
88         struct ccw1 iccws[2];   /* ccws for SNID/SID/SPGID commands */
89         struct work_struct kick_work;
90         wait_queue_head_t wait_q;
91         struct timer_list timer;
92         void *cmb;                      /* measurement information */
93         struct list_head cmb_list;      /* list of measured devices */
94         u64 cmb_start_time;             /* clock value of cmb reset */
95         void *cmb_wait;                 /* deferred cmb enable/disable */
96 };
97
98 static inline int ssch(struct subchannel_id schid, volatile struct orb *addr)
99 {
100         register struct subchannel_id reg1 asm("1") = schid;
101         int ccode;
102
103         asm volatile(
104                 "       ssch    0(%2)\n"
105                 "       ipm     %0\n"
106                 "       srl     %0,28"
107                 : "=d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc");
108         return ccode;
109 }
110
111 static inline int rsch(struct subchannel_id schid)
112 {
113         register struct subchannel_id reg1 asm("1") = schid;
114         int ccode;
115
116         asm volatile(
117                 "       rsch\n"
118                 "       ipm     %0\n"
119                 "       srl     %0,28"
120                 : "=d" (ccode) : "d" (reg1) : "cc");
121         return ccode;
122 }
123
124 static inline int csch(struct subchannel_id schid)
125 {
126         register struct subchannel_id reg1 asm("1") = schid;
127         int ccode;
128
129         asm volatile(
130                 "       csch\n"
131                 "       ipm     %0\n"
132                 "       srl     %0,28"
133                 : "=d" (ccode) : "d" (reg1) : "cc");
134         return ccode;
135 }
136
137 static inline int hsch(struct subchannel_id schid)
138 {
139         register struct subchannel_id reg1 asm("1") = schid;
140         int ccode;
141
142         asm volatile(
143                 "       hsch\n"
144                 "       ipm     %0\n"
145                 "       srl     %0,28"
146                 : "=d" (ccode) : "d" (reg1) : "cc");
147         return ccode;
148 }
149
150 static inline int xsch(struct subchannel_id schid)
151 {
152         register struct subchannel_id reg1 asm("1") = schid;
153         int ccode;
154
155         asm volatile(
156                 "       .insn   rre,0xb2760000,%1,0\n"
157                 "       ipm     %0\n"
158                 "       srl     %0,28"
159                 : "=d" (ccode) : "d" (reg1) : "cc");
160         return ccode;
161 }
162
163 #endif