These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / s390 / cio / device_fsm.c
index 83da53c..92e03b4 100644 (file)
@@ -730,6 +730,44 @@ static void ccw_device_boxed_verify(struct ccw_device *cdev,
                css_schedule_eval(sch->schid);
 }
 
+/*
+ * Pass interrupt to device driver.
+ */
+static int ccw_device_call_handler(struct ccw_device *cdev)
+{
+       unsigned int stctl;
+       int ending_status;
+
+       /*
+        * we allow for the device action handler if .
+        *  - we received ending status
+        *  - the action handler requested to see all interrupts
+        *  - we received an intermediate status
+        *  - fast notification was requested (primary status)
+        *  - unsolicited interrupts
+        */
+       stctl = scsw_stctl(&cdev->private->irb.scsw);
+       ending_status = (stctl & SCSW_STCTL_SEC_STATUS) ||
+               (stctl == (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)) ||
+               (stctl == SCSW_STCTL_STATUS_PEND);
+       if (!ending_status &&
+           !cdev->private->options.repall &&
+           !(stctl & SCSW_STCTL_INTER_STATUS) &&
+           !(cdev->private->options.fast &&
+             (stctl & SCSW_STCTL_PRIM_STATUS)))
+               return 0;
+
+       if (ending_status)
+               ccw_device_set_timeout(cdev, 0);
+
+       if (cdev->handler)
+               cdev->handler(cdev, cdev->private->intparm,
+                             &cdev->private->irb);
+
+       memset(&cdev->private->irb, 0, sizeof(struct irb));
+       return 1;
+}
+
 /*
  * Got an interrupt for a normal io (state online).
  */