diff options
author | Cornelia Huck <cornelia.huck@de.ibm.com> | 2008-01-26 08:10:43 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2008-01-26 08:10:59 -0500 |
commit | cd6b4f27b9bb2a6a5ec82b96b87c85421257be6c (patch) | |
tree | bf5ac3d351242de6438ab1453a7f1b007f24c29f /drivers/s390/cio/io_sch.h | |
parent | bc698bcf8897363732226dc9ecba044771679996 (diff) |
[S390] cio: Introduce subchannel->private.
Introduce a private pointer in struct subchannel to store
per-subchannel type data (cannot use dev->priv since this
is already used for something else).
Create a new header io_sch.h for I/O subchannel specific structures
and instructions.
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/io_sch.h')
-rw-r--r-- | drivers/s390/cio/io_sch.h | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/drivers/s390/cio/io_sch.h b/drivers/s390/cio/io_sch.h new file mode 100644 index 000000000000..d49e5a77a6bf --- /dev/null +++ b/drivers/s390/cio/io_sch.h | |||
@@ -0,0 +1,161 @@ | |||
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 | |||
38 | #define MAX_CIWS 8 | ||
39 | |||
40 | /* | ||
41 | * sense-id response buffer layout | ||
42 | */ | ||
43 | struct senseid { | ||
44 | /* common part */ | ||
45 | u8 reserved; /* always 0x'FF' */ | ||
46 | u16 cu_type; /* control unit type */ | ||
47 | u8 cu_model; /* control unit model */ | ||
48 | u16 dev_type; /* device type */ | ||
49 | u8 dev_model; /* device model */ | ||
50 | u8 unused; /* padding byte */ | ||
51 | /* extended part */ | ||
52 | struct ciw ciw[MAX_CIWS]; /* variable # of CIWs */ | ||
53 | } __attribute__ ((packed, aligned(4))); | ||
54 | |||
55 | struct ccw_device_private { | ||
56 | struct ccw_device *cdev; | ||
57 | struct subchannel *sch; | ||
58 | int state; /* device state */ | ||
59 | atomic_t onoff; | ||
60 | unsigned long registered; | ||
61 | struct ccw_dev_id dev_id; /* device id */ | ||
62 | struct subchannel_id schid; /* subchannel number */ | ||
63 | u8 imask; /* lpm mask for SNID/SID/SPGID */ | ||
64 | int iretry; /* retry counter SNID/SID/SPGID */ | ||
65 | struct { | ||
66 | unsigned int fast:1; /* post with "channel end" */ | ||
67 | unsigned int repall:1; /* report every interrupt status */ | ||
68 | unsigned int pgroup:1; /* do path grouping */ | ||
69 | unsigned int force:1; /* allow forced online */ | ||
70 | } __attribute__ ((packed)) options; | ||
71 | struct { | ||
72 | unsigned int pgid_single:1; /* use single path for Set PGID */ | ||
73 | unsigned int esid:1; /* Ext. SenseID supported by HW */ | ||
74 | unsigned int dosense:1; /* delayed SENSE required */ | ||
75 | unsigned int doverify:1; /* delayed path verification */ | ||
76 | unsigned int donotify:1; /* call notify function */ | ||
77 | unsigned int recog_done:1; /* dev. recog. complete */ | ||
78 | unsigned int fake_irb:1; /* deliver faked irb */ | ||
79 | unsigned int intretry:1; /* retry internal operation */ | ||
80 | } __attribute__((packed)) flags; | ||
81 | unsigned long intparm; /* user interruption parameter */ | ||
82 | struct qdio_irq *qdio_data; | ||
83 | struct irb irb; /* device status */ | ||
84 | struct senseid senseid; /* SenseID info */ | ||
85 | struct pgid pgid[8]; /* path group IDs per chpid*/ | ||
86 | struct ccw1 iccws[2]; /* ccws for SNID/SID/SPGID commands */ | ||
87 | struct work_struct kick_work; | ||
88 | wait_queue_head_t wait_q; | ||
89 | struct timer_list timer; | ||
90 | void *cmb; /* measurement information */ | ||
91 | struct list_head cmb_list; /* list of measured devices */ | ||
92 | u64 cmb_start_time; /* clock value of cmb reset */ | ||
93 | void *cmb_wait; /* deferred cmb enable/disable */ | ||
94 | }; | ||
95 | |||
96 | static inline int ssch(struct subchannel_id schid, volatile struct orb *addr) | ||
97 | { | ||
98 | register struct subchannel_id reg1 asm("1") = schid; | ||
99 | int ccode; | ||
100 | |||
101 | asm volatile( | ||
102 | " ssch 0(%2)\n" | ||
103 | " ipm %0\n" | ||
104 | " srl %0,28" | ||
105 | : "=d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc"); | ||
106 | return ccode; | ||
107 | } | ||
108 | |||
109 | static inline int rsch(struct subchannel_id schid) | ||
110 | { | ||
111 | register struct subchannel_id reg1 asm("1") = schid; | ||
112 | int ccode; | ||
113 | |||
114 | asm volatile( | ||
115 | " rsch\n" | ||
116 | " ipm %0\n" | ||
117 | " srl %0,28" | ||
118 | : "=d" (ccode) : "d" (reg1) : "cc"); | ||
119 | return ccode; | ||
120 | } | ||
121 | |||
122 | static inline int csch(struct subchannel_id schid) | ||
123 | { | ||
124 | register struct subchannel_id reg1 asm("1") = schid; | ||
125 | int ccode; | ||
126 | |||
127 | asm volatile( | ||
128 | " csch\n" | ||
129 | " ipm %0\n" | ||
130 | " srl %0,28" | ||
131 | : "=d" (ccode) : "d" (reg1) : "cc"); | ||
132 | return ccode; | ||
133 | } | ||
134 | |||
135 | static inline int hsch(struct subchannel_id schid) | ||
136 | { | ||
137 | register struct subchannel_id reg1 asm("1") = schid; | ||
138 | int ccode; | ||
139 | |||
140 | asm volatile( | ||
141 | " hsch\n" | ||
142 | " ipm %0\n" | ||
143 | " srl %0,28" | ||
144 | : "=d" (ccode) : "d" (reg1) : "cc"); | ||
145 | return ccode; | ||
146 | } | ||
147 | |||
148 | static inline int xsch(struct subchannel_id schid) | ||
149 | { | ||
150 | register struct subchannel_id reg1 asm("1") = schid; | ||
151 | int ccode; | ||
152 | |||
153 | asm volatile( | ||
154 | " .insn rre,0xb2760000,%1,0\n" | ||
155 | " ipm %0\n" | ||
156 | " srl %0,28" | ||
157 | : "=d" (ccode) : "d" (reg1) : "cc"); | ||
158 | return ccode; | ||
159 | } | ||
160 | |||
161 | #endif | ||