Merge master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6 into next
[linux-2.6] / drivers / s390 / cio / io_sch.h
1 #ifndef S390_IO_SCH_H
2 #define S390_IO_SCH_H
3
4 #include <asm/schid.h>
5
6 /*
7  * command-mode operation request block
8  */
9 struct cmd_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 /*
32  * transport-mode operation request block
33  */
34 struct tm_orb {
35         u32 intparm;
36         u32 key:4;
37         u32 :9;
38         u32 b:1;
39         u32 :2;
40         u32 lpm:8;
41         u32 :7;
42         u32 x:1;
43         u32 tcw;
44         u32 prio:8;
45         u32 :8;
46         u32 rsvpgm:8;
47         u32 :8;
48         u32 :32;
49         u32 :32;
50         u32 :32;
51         u32 :32;
52 }  __attribute__ ((packed, aligned(4)));
53
54 union orb {
55         struct cmd_orb cmd;
56         struct tm_orb tm;
57 }  __attribute__ ((packed, aligned(4)));
58
59 struct io_subchannel_private {
60         union orb orb;          /* operation request block */
61         struct ccw1 sense_ccw;  /* static ccw for sense command */
62 } __attribute__ ((aligned(8)));
63
64 #define to_io_private(n) ((struct io_subchannel_private *)n->private)
65 #define sch_get_cdev(n) (dev_get_drvdata(&n->dev))
66 #define sch_set_cdev(n, c) (dev_set_drvdata(&n->dev, c))
67
68 #define MAX_CIWS 8
69
70 /*
71  * sense-id response buffer layout
72  */
73 struct senseid {
74         /* common part */
75         u8  reserved;   /* always 0x'FF' */
76         u16 cu_type;    /* control unit type */
77         u8  cu_model;   /* control unit model */
78         u16 dev_type;   /* device type */
79         u8  dev_model;  /* device model */
80         u8  unused;     /* padding byte */
81         /* extended part */
82         struct ciw ciw[MAX_CIWS];       /* variable # of CIWs */
83 }  __attribute__ ((packed, aligned(4)));
84
85 struct ccw_device_private {
86         struct ccw_device *cdev;
87         struct subchannel *sch;
88         int state;              /* device state */
89         atomic_t onoff;
90         unsigned long registered;
91         struct ccw_dev_id dev_id;       /* device id */
92         struct subchannel_id schid;     /* subchannel number */
93         u8 imask;               /* lpm mask for SNID/SID/SPGID */
94         int iretry;             /* retry counter SNID/SID/SPGID */
95         struct {
96                 unsigned int fast:1;    /* post with "channel end" */
97                 unsigned int repall:1;  /* report every interrupt status */
98                 unsigned int pgroup:1;  /* do path grouping */
99                 unsigned int force:1;   /* allow forced online */
100         } __attribute__ ((packed)) options;
101         struct {
102                 unsigned int pgid_single:1; /* use single path for Set PGID */
103                 unsigned int esid:1;        /* Ext. SenseID supported by HW */
104                 unsigned int dosense:1;     /* delayed SENSE required */
105                 unsigned int doverify:1;    /* delayed path verification */
106                 unsigned int donotify:1;    /* call notify function */
107                 unsigned int recog_done:1;  /* dev. recog. complete */
108                 unsigned int fake_irb:1;    /* deliver faked irb */
109                 unsigned int intretry:1;    /* retry internal operation */
110         } __attribute__((packed)) flags;
111         unsigned long intparm;  /* user interruption parameter */
112         struct qdio_irq *qdio_data;
113         struct irb irb;         /* device status */
114         struct senseid senseid; /* SenseID info */
115         struct pgid pgid[8];    /* path group IDs per chpid*/
116         struct ccw1 iccws[2];   /* ccws for SNID/SID/SPGID commands */
117         struct work_struct kick_work;
118         wait_queue_head_t wait_q;
119         struct timer_list timer;
120         void *cmb;                      /* measurement information */
121         struct list_head cmb_list;      /* list of measured devices */
122         u64 cmb_start_time;             /* clock value of cmb reset */
123         void *cmb_wait;                 /* deferred cmb enable/disable */
124 };
125
126 static inline int ssch(struct subchannel_id schid, volatile union orb *addr)
127 {
128         register struct subchannel_id reg1 asm("1") = schid;
129         int ccode = -EIO;
130
131         asm volatile(
132                 "       ssch    0(%2)\n"
133                 "0:     ipm     %0\n"
134                 "       srl     %0,28\n"
135                 "1:\n"
136                 EX_TABLE(0b, 1b)
137                 : "+d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc");
138         return ccode;
139 }
140
141 static inline int rsch(struct subchannel_id schid)
142 {
143         register struct subchannel_id reg1 asm("1") = schid;
144         int ccode;
145
146         asm volatile(
147                 "       rsch\n"
148                 "       ipm     %0\n"
149                 "       srl     %0,28"
150                 : "=d" (ccode) : "d" (reg1) : "cc");
151         return ccode;
152 }
153
154 static inline int csch(struct subchannel_id schid)
155 {
156         register struct subchannel_id reg1 asm("1") = schid;
157         int ccode;
158
159         asm volatile(
160                 "       csch\n"
161                 "       ipm     %0\n"
162                 "       srl     %0,28"
163                 : "=d" (ccode) : "d" (reg1) : "cc");
164         return ccode;
165 }
166
167 static inline int hsch(struct subchannel_id schid)
168 {
169         register struct subchannel_id reg1 asm("1") = schid;
170         int ccode;
171
172         asm volatile(
173                 "       hsch\n"
174                 "       ipm     %0\n"
175                 "       srl     %0,28"
176                 : "=d" (ccode) : "d" (reg1) : "cc");
177         return ccode;
178 }
179
180 static inline int xsch(struct subchannel_id schid)
181 {
182         register struct subchannel_id reg1 asm("1") = schid;
183         int ccode;
184
185         asm volatile(
186                 "       .insn   rre,0xb2760000,%1,0\n"
187                 "       ipm     %0\n"
188                 "       srl     %0,28"
189                 : "=d" (ccode) : "d" (reg1) : "cc");
190         return ccode;
191 }
192
193 #endif