From: Hans-Joachim Picht <hpicht@redhat.com> Date: Fri, 28 Aug 2009 16:02:29 +0200 Subject: [s390] cio: set correct number of internal I/O retries Message-id: 20090828140229.GD7396@blc4eb509856389.ibm.com O-Subject: [RHEL5 U5 PATCH 1/1] s390 - cio: set correct number of internal I/O retries Bugzilla: 519814 RH-Acked-by: Pete Zaitcev <zaitcev@redhat.com> Description ============ If a device has n paths and the device is not path-grouped and an internal I/O command fails, then the control unit presents the error sense n times on each different path. cio does only 5 retries, i.e. devices with 5 or more paths run out of retries before their functional status can actually be determined. As result, devices might be untruly considered nonfunctional. The solution is to increase the number of retries to 10 (for handling up to 8 paths). Bugzilla ========= BZ 519814 https://bugzilla.redhat.com/show_bug.cgi?id=519814 Upstream status of the patch: ============================= The patch is applicable to RHEL5 U5 only. Test status: ============ The patch has been tested and fixes the problem. The fix has been verified by the IBM test department. Please ACK. With best regards, --Hans diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c index 890c4a2..787aeac 100644 --- a/drivers/s390/cio/device_id.c +++ b/drivers/s390/cio/device_id.c @@ -162,7 +162,7 @@ __ccw_device_sense_id_start(struct ccw_device *cdev) return ret; } cdev->private->imask >>= 1; - cdev->private->iretry = 5; + cdev->private->iretry = 10; } return ret; } @@ -174,7 +174,7 @@ ccw_device_sense_id_start(struct ccw_device *cdev) memset (&cdev->private->senseid, 0, sizeof (struct senseid)); cdev->private->imask = 0x80; - cdev->private->iretry = 5; + cdev->private->iretry = 10; ret = __ccw_device_sense_id_start(cdev); if (ret && ret != -EBUSY) ccw_device_sense_id_done(cdev, ret); @@ -293,7 +293,7 @@ ccw_device_sense_id_irq(struct ccw_device *cdev, enum dev_event dev_event) case -EACCES: /* channel is not operational. */ sch->lpm &= ~cdev->private->imask; cdev->private->imask >>= 1; - cdev->private->iretry = 5; + cdev->private->iretry = 10; /* fall through. */ case -EAGAIN: /* try again. */ ret = __ccw_device_sense_id_start(cdev); diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c index 341d6f6..170aa4a 100644 --- a/drivers/s390/cio/device_pgid.c +++ b/drivers/s390/cio/device_pgid.c @@ -86,7 +86,7 @@ __ccw_device_sense_pgid_start(struct ccw_device *cdev) } cdev->private->imask >>= 1; - cdev->private->iretry = 5; + cdev->private->iretry = 10; i++; } @@ -103,7 +103,7 @@ ccw_device_sense_pgid_start(struct ccw_device *cdev) cdev->private->state = DEV_STATE_SENSE_PGID; cdev->private->imask = 0x80; - cdev->private->iretry = 5; + cdev->private->iretry = 10; memset (&cdev->private->pgid, 0, sizeof (cdev->private->pgid)); ret = __ccw_device_sense_pgid_start(cdev); if (ret && ret != -EBUSY) @@ -209,7 +209,7 @@ ccw_device_sense_pgid_irq(struct ccw_device *cdev, enum dev_event dev_event) /* Fall through. */ case 0: /* Sense Path Group ID successful. */ cdev->private->imask >>= 1; - cdev->private->iretry = 5; + cdev->private->iretry = 10; /* Fall through. */ case -EAGAIN: /* Try again. */ ret = __ccw_device_sense_pgid_start(cdev); @@ -397,7 +397,7 @@ __ccw_device_verify_start(struct ccw_device *cdev) sch = to_subchannel(cdev->dev.parent); /* Repeat for all paths. */ for (; cdev->private->imask; cdev->private->imask >>= 1, - cdev->private->iretry = 5) { + cdev->private->iretry = 10) { if ((cdev->private->imask & sch->schib.pmcw.pam) == 0) /* Path not available, try next. */ continue; @@ -453,7 +453,7 @@ ccw_device_verify_irq(struct ccw_device *cdev, enum dev_event dev_event) sch->vpm |= sch->opm & cdev->private->imask; /* Go on with next path. */ cdev->private->imask >>= 1; - cdev->private->iretry = 5; + cdev->private->iretry = 10; __ccw_device_verify_start(cdev); break; case -EOPNOTSUPP: @@ -468,7 +468,7 @@ ccw_device_verify_irq(struct ccw_device *cdev, enum dev_event dev_event) /* Retry */ sch->vpm = 0; cdev->private->imask = 0x80; - cdev->private->iretry = 5; + cdev->private->iretry = 10; /* fall through. */ case -EAGAIN: /* Try again. */ __ccw_device_verify_start(cdev); @@ -478,7 +478,7 @@ ccw_device_verify_irq(struct ccw_device *cdev, enum dev_event dev_event) break; case -EACCES: /* channel is not operational. */ cdev->private->imask >>= 1; - cdev->private->iretry = 5; + cdev->private->iretry = 10; __ccw_device_verify_start(cdev); break; } @@ -491,7 +491,7 @@ ccw_device_verify_start(struct ccw_device *cdev) cdev->private->flags.pgid_single = 0; cdev->private->imask = 0x80; - cdev->private->iretry = 5; + cdev->private->iretry = 10; /* Start with empty vpm. */ sch->vpm = 0; @@ -519,7 +519,7 @@ __ccw_device_disband_start(struct ccw_device *cdev) if (ret == 0) return; } - cdev->private->iretry = 5; + cdev->private->iretry = 10; cdev->private->imask >>= 1; } ccw_device_disband_done(cdev, (sch->lpm != 0) ? 0 : -ENODEV); @@ -568,7 +568,7 @@ ccw_device_disband_irq(struct ccw_device *cdev, enum dev_event dev_event) break; case -EACCES: /* channel is not operational. */ cdev->private->imask >>= 1; - cdev->private->iretry = 5; + cdev->private->iretry = 10; __ccw_device_disband_start(cdev); break; } @@ -581,7 +581,7 @@ ccw_device_disband_start(struct ccw_device *cdev) ccw_device_set_timeout(cdev, 60*HZ); cdev->private->flags.pgid_single = 0; - cdev->private->iretry = 5; + cdev->private->iretry = 10; cdev->private->imask = 0x80; __ccw_device_disband_start(cdev); }