+/*
+ * Helper function to send a nop ccw down a path.
+ */
+static int __ccw_device_do_nop(struct ccw_device *cdev)
+{
+ struct subchannel *sch;
+ struct ccw1 *ccw;
+ int ret;
+
+ sch = to_subchannel(cdev->dev.parent);
+
+ /* Setup nop channel program. */
+ ccw = cdev->private->iccws;
+ ccw->cmd_code = CCW_CMD_NOOP;
+ ccw->cda = 0;
+ ccw->count = 0;
+ ccw->flags = CCW_FLAG_SLI;
+
+ /* Reset device status. */
+ memset(&cdev->private->irb, 0, sizeof(struct irb));
+
+ /* Try multiple times. */
+ 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
+ * indication. */
+ if ((ret == 0) || (ret == -EBUSY))
+ return ret;
+ }
+ /* nop command failed on this path. */
+ CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel "
+ "0.%x.%04x, lpm %02X, became 'not operational'\n",
+ cdev->private->dev_id.devno, sch->schid.ssid,
+ sch->schid.sch_no, cdev->private->imask);
+ return ret;
+}
+
+