[S390] more workqueue fixes.
[powerpc.git] / drivers / s390 / cio / device_pgid.c
index 2975ce8..cb1879a 100644 (file)
@@ -71,6 +71,8 @@ __ccw_device_sense_pgid_start(struct ccw_device *cdev)
                ccw->cda = (__u32) __pa (&cdev->private->pgid[i]);
                if (cdev->private->iretry > 0) {
                        cdev->private->iretry--;
+                       /* Reset internal retry indication. */
+                       cdev->private->flags.intretry = 0;
                        ret = cio_start (sch, cdev->private->iccws, 
                                         cdev->private->imask);
                        /* ret is 0, -EBUSY, -EACCES or -ENODEV */
@@ -122,8 +124,14 @@ __ccw_device_check_sense_pgid(struct ccw_device *cdev)
 
        sch = to_subchannel(cdev->dev.parent);
        irb = &cdev->private->irb;
-       if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC))
+       if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
+               /* Retry Sense PGID if requested. */
+               if (cdev->private->flags.intretry) {
+                       cdev->private->flags.intretry = 0;
+                       return -EAGAIN;
+               }
                return -ETIME;
+       }
        if (irb->esw.esw0.erw.cons &&
            (irb->ecw[0]&(SNS0_CMD_REJECT|SNS0_INTERVENTION_REQ))) {
                /*
@@ -253,6 +261,8 @@ __ccw_device_do_pgid(struct ccw_device *cdev, __u8 func)
        ret = -EACCES;
        if (cdev->private->iretry > 0) {
                cdev->private->iretry--;
+               /* Reset internal retry indication. */
+               cdev->private->flags.intretry = 0;
                ret = cio_start (sch, cdev->private->iccws,
                                 cdev->private->imask);
                /* We expect an interrupt in case of success or busy
@@ -293,6 +303,8 @@ static int __ccw_device_do_nop(struct ccw_device *cdev)
        ret = -EACCES;
        if (cdev->private->iretry > 0) {
                cdev->private->iretry--;
+               /* Reset internal retry indication. */
+               cdev->private->flags.intretry = 0;
                ret = cio_start (sch, cdev->private->iccws,
                                 cdev->private->imask);
                /* We expect an interrupt in case of success or busy
@@ -321,8 +333,14 @@ __ccw_device_check_pgid(struct ccw_device *cdev)
 
        sch = to_subchannel(cdev->dev.parent);
        irb = &cdev->private->irb;
-       if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC))
+       if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
+               /* Retry Set PGID if requested. */
+               if (cdev->private->flags.intretry) {
+                       cdev->private->flags.intretry = 0;
+                       return -EAGAIN;
+               }
                return -ETIME;
+       }
        if (irb->esw.esw0.erw.cons) {
                if (irb->ecw[0] & SNS0_CMD_REJECT)
                        return -EOPNOTSUPP;
@@ -360,8 +378,14 @@ static int __ccw_device_check_nop(struct ccw_device *cdev)
 
        sch = to_subchannel(cdev->dev.parent);
        irb = &cdev->private->irb;
-       if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC))
+       if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
+               /* Retry NOP if requested. */
+               if (cdev->private->flags.intretry) {
+                       cdev->private->flags.intretry = 0;
+                       return -EAGAIN;
+               }
                return -ETIME;
+       }
        if (irb->scsw.cc == 3) {
                CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel 0.%x.%04x,"
                              " lpm %02X, became 'not operational'\n",