]> rtime.felk.cvut.cz Git - mcf548x/linux.git/blob - drivers/s390/cio/io_sch.h
Initial 2.6.37
[mcf548x/linux.git] / drivers / s390 / cio / io_sch.h
1 #ifndef S390_IO_SCH_H
2 #define S390_IO_SCH_H
3
4 #include <linux/types.h>
5 #include <asm/schid.h>
6 #include <asm/ccwdev.h>
7 #include "css.h"
8
9 /*
10  * command-mode operation request block
11  */
12 struct cmd_orb {
13         u32 intparm;    /* interruption parameter */
14         u32 key  : 4;   /* flags, like key, suspend control, etc. */
15         u32 spnd : 1;   /* suspend control */
16         u32 res1 : 1;   /* reserved */
17         u32 mod  : 1;   /* modification control */
18         u32 sync : 1;   /* synchronize control */
19         u32 fmt  : 1;   /* format control */
20         u32 pfch : 1;   /* prefetch control */
21         u32 isic : 1;   /* initial-status-interruption control */
22         u32 alcc : 1;   /* address-limit-checking control */
23         u32 ssic : 1;   /* suppress-suspended-interr. control */
24         u32 res2 : 1;   /* reserved */
25         u32 c64  : 1;   /* IDAW/QDIO 64 bit control  */
26         u32 i2k  : 1;   /* IDAW 2/4kB block size control */
27         u32 lpm  : 8;   /* logical path mask */
28         u32 ils  : 1;   /* incorrect length */
29         u32 zero : 6;   /* reserved zeros */
30         u32 orbx : 1;   /* ORB extension control */
31         u32 cpa;        /* channel program address */
32 }  __attribute__ ((packed, aligned(4)));
33
34 /*
35  * transport-mode operation request block
36  */
37 struct tm_orb {
38         u32 intparm;
39         u32 key:4;
40         u32 :9;
41         u32 b:1;
42         u32 :2;
43         u32 lpm:8;
44         u32 :7;
45         u32 x:1;
46         u32 tcw;
47         u32 prio:8;
48         u32 :8;
49         u32 rsvpgm:8;
50         u32 :8;
51         u32 :32;
52         u32 :32;
53         u32 :32;
54         u32 :32;
55 }  __attribute__ ((packed, aligned(4)));
56
57 union orb {
58         struct cmd_orb cmd;
59         struct tm_orb tm;
60 }  __attribute__ ((packed, aligned(4)));
61
62 struct io_subchannel_private {
63         union orb orb;          /* operation request block */
64         struct ccw1 sense_ccw;  /* static ccw for sense command */
65 } __attribute__ ((aligned(8)));
66
67 #define to_io_private(n) ((struct io_subchannel_private *)n->private)
68 #define sch_get_cdev(n) (dev_get_drvdata(&n->dev))
69 #define sch_set_cdev(n, c) (dev_set_drvdata(&n->dev, c))
70
71 #define MAX_CIWS 8
72
73 /*
74  * Possible status values for a CCW request's I/O.
75  */
76 enum io_status {
77         IO_DONE,
78         IO_RUNNING,
79         IO_STATUS_ERROR,
80         IO_PATH_ERROR,
81         IO_REJECTED,
82         IO_KILLED
83 };
84
85 /**
86  * ccw_request - Internal CCW request.
87  * @cp: channel program to start
88  * @timeout: maximum allowable time in jiffies between start I/O and interrupt
89  * @maxretries: number of retries per I/O operation and path
90  * @lpm: mask of paths to use
91  * @check: optional callback that determines if results are final
92  * @filter: optional callback to adjust request status based on IRB data
93  * @callback: final callback
94  * @data: user-defined pointer passed to all callbacks
95  * @singlepath: if set, use only one path from @lpm per start I/O
96  * @cancel: non-zero if request was cancelled
97  * @done: non-zero if request was finished
98  * @mask: current path mask
99  * @retries: current number of retries
100  * @drc: delayed return code
101  */
102 struct ccw_request {
103         struct ccw1 *cp;
104         unsigned long timeout;
105         u16 maxretries;
106         u8 lpm;
107         int (*check)(struct ccw_device *, void *);
108         enum io_status (*filter)(struct ccw_device *, void *, struct irb *,
109                                  enum io_status);
110         void (*callback)(struct ccw_device *, void *, int);
111         void *data;
112         unsigned int singlepath:1;
113         /* These fields are used internally. */
114         unsigned int cancel:1;
115         unsigned int done:1;
116         u16 mask;
117         u16 retries;
118         int drc;
119 } __attribute__((packed));
120
121 /*
122  * sense-id response buffer layout
123  */
124 struct senseid {
125         /* common part */
126         u8  reserved;   /* always 0x'FF' */
127         u16 cu_type;    /* control unit type */
128         u8  cu_model;   /* control unit model */
129         u16 dev_type;   /* device type */
130         u8  dev_model;  /* device model */
131         u8  unused;     /* padding byte */
132         /* extended part */
133         struct ciw ciw[MAX_CIWS];       /* variable # of CIWs */
134 }  __attribute__ ((packed, aligned(4)));
135
136 enum cdev_todo {
137         CDEV_TODO_NOTHING,
138         CDEV_TODO_ENABLE_CMF,
139         CDEV_TODO_REBIND,
140         CDEV_TODO_REGISTER,
141         CDEV_TODO_UNREG,
142         CDEV_TODO_UNREG_EVAL,
143 };
144
145 struct ccw_device_private {
146         struct ccw_device *cdev;
147         struct subchannel *sch;
148         int state;              /* device state */
149         atomic_t onoff;
150         struct ccw_dev_id dev_id;       /* device id */
151         struct subchannel_id schid;     /* subchannel number */
152         struct ccw_request req;         /* internal I/O request */
153         int iretry;
154         u8 pgid_valid_mask;     /* mask of valid PGIDs */
155         u8 pgid_todo_mask;      /* mask of PGIDs to be adjusted */
156         u8 pgid_reset_mask;     /* mask of PGIDs which were reset */
157         u8 path_gone_mask;      /* mask of paths, that became unavailable */
158         u8 path_new_mask;       /* mask of paths, that became available */
159         struct {
160                 unsigned int fast:1;    /* post with "channel end" */
161                 unsigned int repall:1;  /* report every interrupt status */
162                 unsigned int pgroup:1;  /* do path grouping */
163                 unsigned int force:1;   /* allow forced online */
164                 unsigned int mpath:1;   /* do multipathing */
165         } __attribute__ ((packed)) options;
166         struct {
167                 unsigned int esid:1;        /* Ext. SenseID supported by HW */
168                 unsigned int dosense:1;     /* delayed SENSE required */
169                 unsigned int doverify:1;    /* delayed path verification */
170                 unsigned int donotify:1;    /* call notify function */
171                 unsigned int recog_done:1;  /* dev. recog. complete */
172                 unsigned int fake_irb:1;    /* deliver faked irb */
173                 unsigned int resuming:1;    /* recognition while resume */
174                 unsigned int pgroup:1;      /* pathgroup is set up */
175                 unsigned int mpath:1;       /* multipathing is set up */
176                 unsigned int initialized:1; /* set if initial reference held */
177         } __attribute__((packed)) flags;
178         unsigned long intparm;  /* user interruption parameter */
179         struct qdio_irq *qdio_data;
180         struct irb irb;         /* device status */
181         struct senseid senseid; /* SenseID info */
182         struct pgid pgid[8];    /* path group IDs per chpid*/
183         struct ccw1 iccws[2];   /* ccws for SNID/SID/SPGID commands */
184         struct work_struct todo_work;
185         enum cdev_todo todo;
186         wait_queue_head_t wait_q;
187         struct timer_list timer;
188         void *cmb;                      /* measurement information */
189         struct list_head cmb_list;      /* list of measured devices */
190         u64 cmb_start_time;             /* clock value of cmb reset */
191         void *cmb_wait;                 /* deferred cmb enable/disable */
192 };
193
194 static inline int ssch(struct subchannel_id schid, union orb *addr)
195 {
196         register struct subchannel_id reg1 asm("1") = schid;
197         int ccode = -EIO;
198
199         asm volatile(
200                 "       ssch    0(%2)\n"
201                 "0:     ipm     %0\n"
202                 "       srl     %0,28\n"
203                 "1:\n"
204                 EX_TABLE(0b, 1b)
205                 : "+d" (ccode)
206                 : "d" (reg1), "a" (addr), "m" (*addr)
207                 : "cc", "memory");
208         return ccode;
209 }
210
211 static inline int rsch(struct subchannel_id schid)
212 {
213         register struct subchannel_id reg1 asm("1") = schid;
214         int ccode;
215
216         asm volatile(
217                 "       rsch\n"
218                 "       ipm     %0\n"
219                 "       srl     %0,28"
220                 : "=d" (ccode)
221                 : "d" (reg1)
222                 : "cc", "memory");
223         return ccode;
224 }
225
226 static inline int csch(struct subchannel_id schid)
227 {
228         register struct subchannel_id reg1 asm("1") = schid;
229         int ccode;
230
231         asm volatile(
232                 "       csch\n"
233                 "       ipm     %0\n"
234                 "       srl     %0,28"
235                 : "=d" (ccode)
236                 : "d" (reg1)
237                 : "cc");
238         return ccode;
239 }
240
241 static inline int hsch(struct subchannel_id schid)
242 {
243         register struct subchannel_id reg1 asm("1") = schid;
244         int ccode;
245
246         asm volatile(
247                 "       hsch\n"
248                 "       ipm     %0\n"
249                 "       srl     %0,28"
250                 : "=d" (ccode)
251                 : "d" (reg1)
252                 : "cc");
253         return ccode;
254 }
255
256 static inline int xsch(struct subchannel_id schid)
257 {
258         register struct subchannel_id reg1 asm("1") = schid;
259         int ccode;
260
261         asm volatile(
262                 "       .insn   rre,0xb2760000,%1,0\n"
263                 "       ipm     %0\n"
264                 "       srl     %0,28"
265                 : "=d" (ccode)
266                 : "d" (reg1)
267                 : "cc");
268         return ccode;
269 }
270
271 #endif