|
@@ -59,18 +59,6 @@ device_set_disconnected(struct subchannel *sch)
|
|
|
cdev->private->state = DEV_STATE_DISCONNECTED;
|
|
|
}
|
|
|
|
|
|
-void
|
|
|
-device_set_waiting(struct subchannel *sch)
|
|
|
-{
|
|
|
- struct ccw_device *cdev;
|
|
|
-
|
|
|
- if (!sch->dev.driver_data)
|
|
|
- return;
|
|
|
- cdev = sch->dev.driver_data;
|
|
|
- ccw_device_set_timeout(cdev, 10*HZ);
|
|
|
- cdev->private->state = DEV_STATE_WAIT4IO;
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* Timeout function. It just triggers a DEV_EVENT_TIMEOUT.
|
|
|
*/
|
|
@@ -183,9 +171,9 @@ ccw_device_handle_oper(struct ccw_device *cdev)
|
|
|
cdev->id.cu_model != cdev->private->senseid.cu_model ||
|
|
|
cdev->id.dev_type != cdev->private->senseid.dev_type ||
|
|
|
cdev->id.dev_model != cdev->private->senseid.dev_model ||
|
|
|
- cdev->private->devno != sch->schib.pmcw.dev) {
|
|
|
+ cdev->private->dev_id.devno != sch->schib.pmcw.dev) {
|
|
|
PREPARE_WORK(&cdev->private->kick_work,
|
|
|
- ccw_device_do_unreg_rereg, (void *)cdev);
|
|
|
+ ccw_device_do_unreg_rereg, cdev);
|
|
|
queue_work(ccw_device_work, &cdev->private->kick_work);
|
|
|
return 0;
|
|
|
}
|
|
@@ -255,7 +243,7 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
|
|
|
case DEV_STATE_NOT_OPER:
|
|
|
CIO_DEBUG(KERN_WARNING, 2,
|
|
|
"SenseID : unknown device %04x on subchannel "
|
|
|
- "0.%x.%04x\n", cdev->private->devno,
|
|
|
+ "0.%x.%04x\n", cdev->private->dev_id.devno,
|
|
|
sch->schid.ssid, sch->schid.sch_no);
|
|
|
break;
|
|
|
case DEV_STATE_OFFLINE:
|
|
@@ -282,14 +270,15 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
|
|
|
CIO_DEBUG(KERN_INFO, 2, "SenseID : device 0.%x.%04x reports: "
|
|
|
"CU Type/Mod = %04X/%02X, Dev Type/Mod = "
|
|
|
"%04X/%02X\n",
|
|
|
- cdev->private->ssid, cdev->private->devno,
|
|
|
+ cdev->private->dev_id.ssid,
|
|
|
+ cdev->private->dev_id.devno,
|
|
|
cdev->id.cu_type, cdev->id.cu_model,
|
|
|
cdev->id.dev_type, cdev->id.dev_model);
|
|
|
break;
|
|
|
case DEV_STATE_BOXED:
|
|
|
CIO_DEBUG(KERN_WARNING, 2,
|
|
|
"SenseID : boxed device %04x on subchannel "
|
|
|
- "0.%x.%04x\n", cdev->private->devno,
|
|
|
+ "0.%x.%04x\n", cdev->private->dev_id.devno,
|
|
|
sch->schid.ssid, sch->schid.sch_no);
|
|
|
break;
|
|
|
}
|
|
@@ -325,13 +314,13 @@ ccw_device_oper_notify(void *data)
|
|
|
struct subchannel *sch;
|
|
|
int ret;
|
|
|
|
|
|
- cdev = (struct ccw_device *)data;
|
|
|
+ cdev = data;
|
|
|
sch = to_subchannel(cdev->dev.parent);
|
|
|
ret = (sch->driver && sch->driver->notify) ?
|
|
|
sch->driver->notify(&sch->dev, CIO_OPER) : 0;
|
|
|
if (!ret)
|
|
|
/* Driver doesn't want device back. */
|
|
|
- ccw_device_do_unreg_rereg((void *)cdev);
|
|
|
+ ccw_device_do_unreg_rereg(cdev);
|
|
|
else {
|
|
|
/* Reenable channel measurements, if needed. */
|
|
|
cmf_reenable(cdev);
|
|
@@ -363,12 +352,12 @@ ccw_device_done(struct ccw_device *cdev, int state)
|
|
|
if (state == DEV_STATE_BOXED)
|
|
|
CIO_DEBUG(KERN_WARNING, 2,
|
|
|
"Boxed device %04x on subchannel %04x\n",
|
|
|
- cdev->private->devno, sch->schid.sch_no);
|
|
|
+ cdev->private->dev_id.devno, sch->schid.sch_no);
|
|
|
|
|
|
if (cdev->private->flags.donotify) {
|
|
|
cdev->private->flags.donotify = 0;
|
|
|
PREPARE_WORK(&cdev->private->kick_work, ccw_device_oper_notify,
|
|
|
- (void *)cdev);
|
|
|
+ cdev);
|
|
|
queue_work(ccw_device_notify_work, &cdev->private->kick_work);
|
|
|
}
|
|
|
wake_up(&cdev->private->wait_q);
|
|
@@ -412,7 +401,8 @@ static void __ccw_device_get_common_pgid(struct ccw_device *cdev)
|
|
|
/* PGID mismatch, can't pathgroup. */
|
|
|
CIO_MSG_EVENT(0, "SNID - pgid mismatch for device "
|
|
|
"0.%x.%04x, can't pathgroup\n",
|
|
|
- cdev->private->ssid, cdev->private->devno);
|
|
|
+ cdev->private->dev_id.ssid,
|
|
|
+ cdev->private->dev_id.devno);
|
|
|
cdev->private->options.pgroup = 0;
|
|
|
return;
|
|
|
}
|
|
@@ -523,7 +513,7 @@ ccw_device_nopath_notify(void *data)
|
|
|
struct subchannel *sch;
|
|
|
int ret;
|
|
|
|
|
|
- cdev = (struct ccw_device *)data;
|
|
|
+ cdev = data;
|
|
|
sch = to_subchannel(cdev->dev.parent);
|
|
|
/* Extra sanity. */
|
|
|
if (sch->lpm)
|
|
@@ -537,7 +527,7 @@ ccw_device_nopath_notify(void *data)
|
|
|
if (get_device(&cdev->dev)) {
|
|
|
PREPARE_WORK(&cdev->private->kick_work,
|
|
|
ccw_device_call_sch_unregister,
|
|
|
- (void *)cdev);
|
|
|
+ cdev);
|
|
|
queue_work(ccw_device_work,
|
|
|
&cdev->private->kick_work);
|
|
|
} else
|
|
@@ -592,7 +582,7 @@ ccw_device_verify_done(struct ccw_device *cdev, int err)
|
|
|
break;
|
|
|
default:
|
|
|
PREPARE_WORK(&cdev->private->kick_work,
|
|
|
- ccw_device_nopath_notify, (void *)cdev);
|
|
|
+ ccw_device_nopath_notify, cdev);
|
|
|
queue_work(ccw_device_notify_work, &cdev->private->kick_work);
|
|
|
ccw_device_done(cdev, DEV_STATE_NOT_OPER);
|
|
|
break;
|
|
@@ -723,7 +713,7 @@ ccw_device_offline_notoper(struct ccw_device *cdev, enum dev_event dev_event)
|
|
|
sch = to_subchannel(cdev->dev.parent);
|
|
|
if (get_device(&cdev->dev)) {
|
|
|
PREPARE_WORK(&cdev->private->kick_work,
|
|
|
- ccw_device_call_sch_unregister, (void *)cdev);
|
|
|
+ ccw_device_call_sch_unregister, cdev);
|
|
|
queue_work(ccw_device_work, &cdev->private->kick_work);
|
|
|
}
|
|
|
wake_up(&cdev->private->wait_q);
|
|
@@ -754,7 +744,7 @@ ccw_device_online_notoper(struct ccw_device *cdev, enum dev_event dev_event)
|
|
|
}
|
|
|
if (get_device(&cdev->dev)) {
|
|
|
PREPARE_WORK(&cdev->private->kick_work,
|
|
|
- ccw_device_call_sch_unregister, (void *)cdev);
|
|
|
+ ccw_device_call_sch_unregister, cdev);
|
|
|
queue_work(ccw_device_work, &cdev->private->kick_work);
|
|
|
}
|
|
|
wake_up(&cdev->private->wait_q);
|
|
@@ -859,7 +849,7 @@ ccw_device_online_timeout(struct ccw_device *cdev, enum dev_event dev_event)
|
|
|
sch = to_subchannel(cdev->dev.parent);
|
|
|
if (!sch->lpm) {
|
|
|
PREPARE_WORK(&cdev->private->kick_work,
|
|
|
- ccw_device_nopath_notify, (void *)cdev);
|
|
|
+ ccw_device_nopath_notify, cdev);
|
|
|
queue_work(ccw_device_notify_work,
|
|
|
&cdev->private->kick_work);
|
|
|
} else
|
|
@@ -885,7 +875,8 @@ ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event)
|
|
|
/* Basic sense hasn't started. Try again. */
|
|
|
ccw_device_do_sense(cdev, irb);
|
|
|
else {
|
|
|
- printk("Huh? %s(%s): unsolicited interrupt...\n",
|
|
|
+ printk(KERN_INFO "Huh? %s(%s): unsolicited "
|
|
|
+ "interrupt...\n",
|
|
|
__FUNCTION__, cdev->dev.bus_id);
|
|
|
if (cdev->handler)
|
|
|
cdev->handler (cdev, 0, irb);
|
|
@@ -944,10 +935,10 @@ ccw_device_killing_irq(struct ccw_device *cdev, enum dev_event dev_event)
|
|
|
cdev->private->state = DEV_STATE_ONLINE;
|
|
|
if (cdev->handler)
|
|
|
cdev->handler(cdev, cdev->private->intparm,
|
|
|
- ERR_PTR(-ETIMEDOUT));
|
|
|
+ ERR_PTR(-EIO));
|
|
|
if (!sch->lpm) {
|
|
|
PREPARE_WORK(&cdev->private->kick_work,
|
|
|
- ccw_device_nopath_notify, (void *)cdev);
|
|
|
+ ccw_device_nopath_notify, cdev);
|
|
|
queue_work(ccw_device_notify_work, &cdev->private->kick_work);
|
|
|
} else if (cdev->private->flags.doverify)
|
|
|
/* Start delayed path verification. */
|
|
@@ -970,7 +961,7 @@ ccw_device_killing_timeout(struct ccw_device *cdev, enum dev_event dev_event)
|
|
|
sch = to_subchannel(cdev->dev.parent);
|
|
|
if (!sch->lpm) {
|
|
|
PREPARE_WORK(&cdev->private->kick_work,
|
|
|
- ccw_device_nopath_notify, (void *)cdev);
|
|
|
+ ccw_device_nopath_notify, cdev);
|
|
|
queue_work(ccw_device_notify_work,
|
|
|
&cdev->private->kick_work);
|
|
|
} else
|
|
@@ -981,51 +972,15 @@ ccw_device_killing_timeout(struct ccw_device *cdev, enum dev_event dev_event)
|
|
|
cdev->private->state = DEV_STATE_ONLINE;
|
|
|
if (cdev->handler)
|
|
|
cdev->handler(cdev, cdev->private->intparm,
|
|
|
- ERR_PTR(-ETIMEDOUT));
|
|
|
-}
|
|
|
-
|
|
|
-static void
|
|
|
-ccw_device_wait4io_irq(struct ccw_device *cdev, enum dev_event dev_event)
|
|
|
-{
|
|
|
- struct irb *irb;
|
|
|
- struct subchannel *sch;
|
|
|
-
|
|
|
- irb = (struct irb *) __LC_IRB;
|
|
|
- /*
|
|
|
- * Accumulate status and find out if a basic sense is needed.
|
|
|
- * This is fine since we have already adapted the lpm.
|
|
|
- */
|
|
|
- ccw_device_accumulate_irb(cdev, irb);
|
|
|
- if (cdev->private->flags.dosense) {
|
|
|
- if (ccw_device_do_sense(cdev, irb) == 0) {
|
|
|
- cdev->private->state = DEV_STATE_W4SENSE;
|
|
|
- }
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- /* Iff device is idle, reset timeout. */
|
|
|
- sch = to_subchannel(cdev->dev.parent);
|
|
|
- if (!stsch(sch->schid, &sch->schib))
|
|
|
- if (sch->schib.scsw.actl == 0)
|
|
|
- ccw_device_set_timeout(cdev, 0);
|
|
|
- /* Call the handler. */
|
|
|
- ccw_device_call_handler(cdev);
|
|
|
- if (!sch->lpm) {
|
|
|
- PREPARE_WORK(&cdev->private->kick_work,
|
|
|
- ccw_device_nopath_notify, (void *)cdev);
|
|
|
- queue_work(ccw_device_notify_work, &cdev->private->kick_work);
|
|
|
- } else if (cdev->private->flags.doverify)
|
|
|
- ccw_device_online_verify(cdev, 0);
|
|
|
+ ERR_PTR(-EIO));
|
|
|
}
|
|
|
|
|
|
-static void
|
|
|
-ccw_device_wait4io_timeout(struct ccw_device *cdev, enum dev_event dev_event)
|
|
|
+void device_kill_io(struct subchannel *sch)
|
|
|
{
|
|
|
int ret;
|
|
|
- struct subchannel *sch;
|
|
|
+ struct ccw_device *cdev;
|
|
|
|
|
|
- sch = to_subchannel(cdev->dev.parent);
|
|
|
- ccw_device_set_timeout(cdev, 0);
|
|
|
+ cdev = sch->dev.driver_data;
|
|
|
ret = ccw_device_cancel_halt_clear(cdev);
|
|
|
if (ret == -EBUSY) {
|
|
|
ccw_device_set_timeout(cdev, 3*HZ);
|
|
@@ -1035,7 +990,7 @@ ccw_device_wait4io_timeout(struct ccw_device *cdev, enum dev_event dev_event)
|
|
|
if (ret == -ENODEV) {
|
|
|
if (!sch->lpm) {
|
|
|
PREPARE_WORK(&cdev->private->kick_work,
|
|
|
- ccw_device_nopath_notify, (void *)cdev);
|
|
|
+ ccw_device_nopath_notify, cdev);
|
|
|
queue_work(ccw_device_notify_work,
|
|
|
&cdev->private->kick_work);
|
|
|
} else
|
|
@@ -1044,12 +999,12 @@ ccw_device_wait4io_timeout(struct ccw_device *cdev, enum dev_event dev_event)
|
|
|
}
|
|
|
if (cdev->handler)
|
|
|
cdev->handler(cdev, cdev->private->intparm,
|
|
|
- ERR_PTR(-ETIMEDOUT));
|
|
|
+ ERR_PTR(-EIO));
|
|
|
if (!sch->lpm) {
|
|
|
PREPARE_WORK(&cdev->private->kick_work,
|
|
|
- ccw_device_nopath_notify, (void *)cdev);
|
|
|
+ ccw_device_nopath_notify, cdev);
|
|
|
queue_work(ccw_device_notify_work, &cdev->private->kick_work);
|
|
|
- } else if (cdev->private->flags.doverify)
|
|
|
+ } else
|
|
|
/* Start delayed path verification. */
|
|
|
ccw_device_online_verify(cdev, 0);
|
|
|
}
|
|
@@ -1286,12 +1241,6 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = {
|
|
|
[DEV_EVENT_TIMEOUT] = ccw_device_killing_timeout,
|
|
|
[DEV_EVENT_VERIFY] = ccw_device_nop, //FIXME
|
|
|
},
|
|
|
- [DEV_STATE_WAIT4IO] = {
|
|
|
- [DEV_EVENT_NOTOPER] = ccw_device_online_notoper,
|
|
|
- [DEV_EVENT_INTERRUPT] = ccw_device_wait4io_irq,
|
|
|
- [DEV_EVENT_TIMEOUT] = ccw_device_wait4io_timeout,
|
|
|
- [DEV_EVENT_VERIFY] = ccw_device_delay_verify,
|
|
|
- },
|
|
|
[DEV_STATE_QUIESCE] = {
|
|
|
[DEV_EVENT_NOTOPER] = ccw_device_quiesce_done,
|
|
|
[DEV_EVENT_INTERRUPT] = ccw_device_quiesce_done,
|