aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/cmf.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/cio/cmf.c')
-rw-r--r--drivers/s390/cio/cmf.c55
1 files changed, 8 insertions, 47 deletions
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c
index 288482b21048..6ddd02308e14 100644
--- a/drivers/s390/cio/cmf.c
+++ b/drivers/s390/cio/cmf.c
@@ -185,58 +185,19 @@ static inline void cmf_activate(void *area, unsigned int onoff)
185static int set_schib(struct ccw_device *cdev, u32 mme, int mbfc, 185static int set_schib(struct ccw_device *cdev, u32 mme, int mbfc,
186 unsigned long address) 186 unsigned long address)
187{ 187{
188 int ret;
189 int retry;
190 struct subchannel *sch; 188 struct subchannel *sch;
191 struct schib *schib;
192 189
193 sch = to_subchannel(cdev->dev.parent); 190 sch = to_subchannel(cdev->dev.parent);
194 schib = &sch->schib;
195 /* msch can silently fail, so do it again if necessary */
196 for (retry = 0; retry < 3; retry++) {
197 /* prepare schib */
198 if (cio_update_schib(sch))
199 return -ENODEV;
200 schib->pmcw.mme = mme;
201 schib->pmcw.mbfc = mbfc;
202 /* address can be either a block address or a block index */
203 if (mbfc)
204 schib->mba = address;
205 else
206 schib->pmcw.mbi = address;
207
208 /* try to submit it */
209 switch(ret = msch_err(sch->schid, schib)) {
210 case 0:
211 break;
212 case 1:
213 case 2: /* in I/O or status pending */
214 ret = -EBUSY;
215 break;
216 case 3: /* subchannel is no longer valid */
217 ret = -ENODEV;
218 break;
219 default: /* msch caught an exception */
220 ret = -EINVAL;
221 break;
222 }
223 if (cio_update_schib(sch))
224 return -ENODEV;
225
226 if (ret)
227 break;
228 191
229 /* check if it worked */ 192 sch->config.mme = mme;
230 if (schib->pmcw.mme == mme && 193 sch->config.mbfc = mbfc;
231 schib->pmcw.mbfc == mbfc && 194 /* address can be either a block address or a block index */
232 (mbfc ? (schib->mba == address) 195 if (mbfc)
233 : (schib->pmcw.mbi == address))) 196 sch->config.mba = address;
234 return 0; 197 else
198 sch->config.mbi = address;
235 199
236 ret = -EINVAL; 200 return cio_commit_config(sch);
237 }
238
239 return ret;
240} 201}
241 202
242struct set_schib_struct { 203struct set_schib_struct {