|
@@ -342,8 +342,9 @@ static int cio_check_config(struct subchannel *sch, struct schib *schib)
|
|
*/
|
|
*/
|
|
int cio_commit_config(struct subchannel *sch)
|
|
int cio_commit_config(struct subchannel *sch)
|
|
{
|
|
{
|
|
- struct schib schib;
|
|
|
|
int ccode, retry, ret = 0;
|
|
int ccode, retry, ret = 0;
|
|
|
|
+ struct schib schib;
|
|
|
|
+ struct irb irb;
|
|
|
|
|
|
if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib))
|
|
if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib))
|
|
return -ENODEV;
|
|
return -ENODEV;
|
|
@@ -367,7 +368,10 @@ int cio_commit_config(struct subchannel *sch)
|
|
ret = -EAGAIN;
|
|
ret = -EAGAIN;
|
|
break;
|
|
break;
|
|
case 1: /* status pending */
|
|
case 1: /* status pending */
|
|
- return -EBUSY;
|
|
|
|
|
|
+ ret = -EBUSY;
|
|
|
|
+ if (tsch(sch->schid, &irb))
|
|
|
|
+ return ret;
|
|
|
|
+ break;
|
|
case 2: /* busy */
|
|
case 2: /* busy */
|
|
udelay(100); /* allow for recovery */
|
|
udelay(100); /* allow for recovery */
|
|
ret = -EBUSY;
|
|
ret = -EBUSY;
|
|
@@ -403,7 +407,6 @@ EXPORT_SYMBOL_GPL(cio_update_schib);
|
|
*/
|
|
*/
|
|
int cio_enable_subchannel(struct subchannel *sch, u32 intparm)
|
|
int cio_enable_subchannel(struct subchannel *sch, u32 intparm)
|
|
{
|
|
{
|
|
- int retry;
|
|
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
CIO_TRACE_EVENT(2, "ensch");
|
|
CIO_TRACE_EVENT(2, "ensch");
|
|
@@ -418,20 +421,14 @@ int cio_enable_subchannel(struct subchannel *sch, u32 intparm)
|
|
sch->config.isc = sch->isc;
|
|
sch->config.isc = sch->isc;
|
|
sch->config.intparm = intparm;
|
|
sch->config.intparm = intparm;
|
|
|
|
|
|
- for (retry = 0; retry < 3; retry++) {
|
|
|
|
|
|
+ ret = cio_commit_config(sch);
|
|
|
|
+ if (ret == -EIO) {
|
|
|
|
+ /*
|
|
|
|
+ * Got a program check in msch. Try without
|
|
|
|
+ * the concurrent sense bit the next time.
|
|
|
|
+ */
|
|
|
|
+ sch->config.csense = 0;
|
|
ret = cio_commit_config(sch);
|
|
ret = cio_commit_config(sch);
|
|
- if (ret == -EIO) {
|
|
|
|
- /*
|
|
|
|
- * Got a program check in msch. Try without
|
|
|
|
- * the concurrent sense bit the next time.
|
|
|
|
- */
|
|
|
|
- sch->config.csense = 0;
|
|
|
|
- } else if (ret == -EBUSY) {
|
|
|
|
- struct irb irb;
|
|
|
|
- if (tsch(sch->schid, &irb) != 0)
|
|
|
|
- break;
|
|
|
|
- } else
|
|
|
|
- break;
|
|
|
|
}
|
|
}
|
|
CIO_HEX_EVENT(2, &ret, sizeof(ret));
|
|
CIO_HEX_EVENT(2, &ret, sizeof(ret));
|
|
return ret;
|
|
return ret;
|
|
@@ -444,7 +441,6 @@ EXPORT_SYMBOL_GPL(cio_enable_subchannel);
|
|
*/
|
|
*/
|
|
int cio_disable_subchannel(struct subchannel *sch)
|
|
int cio_disable_subchannel(struct subchannel *sch)
|
|
{
|
|
{
|
|
- int retry;
|
|
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
CIO_TRACE_EVENT(2, "dissch");
|
|
CIO_TRACE_EVENT(2, "dissch");
|
|
@@ -456,16 +452,8 @@ int cio_disable_subchannel(struct subchannel *sch)
|
|
return -ENODEV;
|
|
return -ENODEV;
|
|
|
|
|
|
sch->config.ena = 0;
|
|
sch->config.ena = 0;
|
|
|
|
+ ret = cio_commit_config(sch);
|
|
|
|
|
|
- for (retry = 0; retry < 3; retry++) {
|
|
|
|
- ret = cio_commit_config(sch);
|
|
|
|
- if (ret == -EBUSY) {
|
|
|
|
- struct irb irb;
|
|
|
|
- if (tsch(sch->schid, &irb) != 0)
|
|
|
|
- break;
|
|
|
|
- } else
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
CIO_HEX_EVENT(2, &ret, sizeof(ret));
|
|
CIO_HEX_EVENT(2, &ret, sizeof(ret));
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|