add_timer(&cdev->private->timer);
}
+/* Kill any pending timers after machine check. */
+void
+device_kill_pending_timer(struct subchannel *sch)
+{
+ struct ccw_device *cdev;
+
+ if (!sch->dev.driver_data)
+ return;
+ cdev = sch->dev.driver_data;
+ ccw_device_set_timeout(cdev, 0);
+}
+
/*
* Cancel running i/o. This is called repeatedly since halt/clear are
* asynchronous operations. We do one try with cio_cancel, two tries
panic("Can't stop i/o on subchannel.\n");
}
-static void
+static int
ccw_device_handle_oper(struct ccw_device *cdev)
{
struct subchannel *sch;
PREPARE_WORK(&cdev->private->kick_work,
ccw_device_do_unreg_rereg, (void *)cdev);
queue_work(ccw_device_work, &cdev->private->kick_work);
- return;
+ return 0;
}
cdev->private->flags.donotify = 1;
+ return 1;
}
/*
ccw_device_recog_done(struct ccw_device *cdev, int state)
{
struct subchannel *sch;
- int notify, old_lpm;
+ int notify, old_lpm, same_dev;
sch = to_subchannel(cdev->dev.parent);
/* Boxed devices don't need extra treatment. */
}
notify = 0;
+ same_dev = 0; /* Keep the compiler quiet... */
switch (state) {
case DEV_STATE_NOT_OPER:
CIO_DEBUG(KERN_WARNING, 2,
break;
case DEV_STATE_OFFLINE:
if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) {
- ccw_device_handle_oper(cdev);
+ same_dev = ccw_device_handle_oper(cdev);
notify = 1;
}
/* fill out sense information */
.dev_model = cdev->private->senseid.dev_model,
};
if (notify) {
- /* Get device online again. */
cdev->private->state = DEV_STATE_OFFLINE;
- ccw_device_online(cdev);
- wake_up(&cdev->private->wait_q);
+ if (same_dev) {
+ /* Get device online again. */
+ ccw_device_online(cdev);
+ wake_up(&cdev->private->wait_q);
+ }
return;
}
/* Issue device info message. */
(void *)cdev);
queue_work(ccw_device_work,
&cdev->private->kick_work);
- }
+ } else
+ put_device(&sch->dev);
}
} else {
cio_disable_subchannel(sch);
CIO_TRACE_EVENT (3, "IRQ");
CIO_TRACE_EVENT (3, pdev->bus_id);
-
- dev_fsm_event(cdev, DEV_EVENT_INTERRUPT);
+ if (cdev)
+ dev_fsm_event(cdev, DEV_EVENT_INTERRUPT);
}
EXPORT_SYMBOL_GPL(ccw_device_set_timeout);