From d7b5a4c94f49131811112526f7d404a50f0b5ca7 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Fri, 8 Dec 2006 15:54:28 +0100 Subject: [S390] Support for disconnected devices reappearing on another subchannel. - create a 'pseudo_subchannel' per channel subsystem (the 'orphanage') - use the orphanage as a shelter for ccw_devices that can't remain on the same subchannel Signed-off-by: Cornelia Huck Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/device_fsm.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'drivers/s390/cio/device_fsm.c') diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index a487fb0e7d3..eed14572fc3 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c @@ -186,13 +186,12 @@ ccw_device_handle_oper(struct ccw_device *cdev) /* * Check if cu type and device type still match. If * not, it is certainly another device and we have to - * de- and re-register. Also check here for non-matching devno. + * de- and re-register. */ if (cdev->id.cu_type != cdev->private->senseid.cu_type || 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->dev_id.devno != sch->schib.pmcw.dev) { + cdev->id.dev_model != cdev->private->senseid.dev_model) { PREPARE_WORK(&cdev->private->kick_work, ccw_device_do_unreg_rereg); queue_work(ccw_device_work, &cdev->private->kick_work); @@ -676,6 +675,10 @@ ccw_device_offline(struct ccw_device *cdev) { struct subchannel *sch; + if (ccw_device_is_orphan(cdev)) { + ccw_device_done(cdev, DEV_STATE_OFFLINE); + return 0; + } sch = to_subchannel(cdev->dev.parent); if (stsch(sch->schid, &sch->schib) || !sch->schib.pmcw.dnv) return -ENODEV; @@ -1121,7 +1124,13 @@ device_trigger_reprobe(struct subchannel *sch) sch->schib.pmcw.mp = 1; sch->schib.pmcw.intparm = (__u32)(unsigned long)sch; /* We should also udate ssd info, but this has to wait. */ - ccw_device_start_id(cdev, 0); + /* Check if this is another device which appeared on the same sch. */ + if (sch->schib.pmcw.dev != cdev->private->dev_id.devno) { + PREPARE_WORK(&cdev->private->kick_work, + ccw_device_move_to_orphanage); + queue_work(ccw_device_work, &cdev->private->kick_work); + } else + ccw_device_start_id(cdev, 0); } static void -- cgit v1.2.3