mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] s390 (2/6): common i/o layer.
@ 2004-04-28 16:49 Martin Schwidefsky
  0 siblings, 0 replies; 2+ messages in thread
From: Martin Schwidefsky @ 2004-04-28 16:49 UTC (permalink / raw)
  To: akpm, linux-kernel

[PATCH] s390: common i/o layer.

From: Martin Schwidefsky <schwidefsky@de.ibm.com>

Common i/o layer changes:
 - Don't use bus ids in crw debug feature.
 - Use cio_oper for oper notification to disconnected devices.
 - Remove __get_subchannel_by_stsch.
 - Make cio workqueue a single threaded workqueue.
 - Introduce addiotnal cio_notify workqueue for device driver notification.
 - Switch off path in vpm if cio_start returned -ENODEV.
 - Fix rescan for new subchannels after a logical vary on.

diffstat:
 drivers/s390/cio/chsc.c        |   13 ++++++-------
 drivers/s390/cio/css.c         |   28 ++--------------------------
 drivers/s390/cio/device.c      |   34 +++++++++++++++++++++++++---------
 drivers/s390/cio/device.h      |    3 ++-
 drivers/s390/cio/device_fsm.c  |   32 +++++++++++++++++++-------------
 drivers/s390/cio/device_pgid.c |    2 +-
 6 files changed, 55 insertions(+), 57 deletions(-)

diff -urN linux-2.6/drivers/s390/cio/chsc.c linux-2.6-s390/drivers/s390/cio/chsc.c
--- linux-2.6/drivers/s390/cio/chsc.c	Wed Apr 28 17:51:15 2004
+++ linux-2.6-s390/drivers/s390/cio/chsc.c	Wed Apr 28 17:51:38 2004
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/chsc.c
  *   S/390 common I/O routines -- channel subsystem call
- *   $Revision: 1.107 $
+ *   $Revision: 1.110 $
  *
  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
  *			      IBM Corporation
@@ -148,7 +148,7 @@
 	 */
 	if (ssd_area->st > 3) { /* uhm, that looks strange... */
 		CIO_CRW_EVENT(0, "Strange subchannel type %d"
-			      " for sch %s\n", ssd_area->st, sch->dev.bus_id);
+			      " for sch %04x\n", ssd_area->st, sch->irq);
 		/*
 		 * There may have been a new subchannel type defined in the
 		 * time since this code was written; since we don't know which
@@ -157,8 +157,8 @@
 		return 0;
 	} else {
 		const char *type[4] = {"I/O", "chsc", "message", "ADM"};
-		CIO_CRW_EVENT(6, "ssd: sch %s is %s subchannel\n",
-			      sch->dev.bus_id, type[ssd_area->st]);
+		CIO_CRW_EVENT(6, "ssd: sch %04x is %s subchannel\n",
+			      sch->irq, type[ssd_area->st]);
 
 		sch->ssd_info.valid = 1;
 		sch->ssd_info.type = ssd_area->st;
@@ -818,6 +818,8 @@
 	for (irq = 0; irq < __MAX_SUBCHANNELS; irq++) {
 		struct schib schib;
 
+		if (need_rescan)
+			break;
 		sch = get_subchannel_by_schid(irq);
 		if (sch) {
 			put_device(&sch->dev);
@@ -826,15 +828,12 @@
 		if (stsch(irq, &schib))
 			/* We're through */
 			break;
-		if (need_rescan)
-			continue;
 		/* Put it on the slow path. */
 		ret = css_enqueue_subchannel_slow(irq);
 		if (ret) {
 			css_clear_subchannel_slow_list();
 			need_rescan = 1;
 		}
-		continue;
 	}
 	if (need_rescan || css_slow_subchannels_exist())
 		schedule_work(&varyonoff_work);
diff -urN linux-2.6/drivers/s390/cio/css.c linux-2.6-s390/drivers/s390/cio/css.c
--- linux-2.6/drivers/s390/cio/css.c	Wed Apr 28 17:51:15 2004
+++ linux-2.6-s390/drivers/s390/cio/css.c	Wed Apr 28 17:51:38 2004
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/css.c
  *  driver for channel subsystem
- *   $Revision: 1.72 $
+ *   $Revision: 1.73 $
  *
  *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
  *			 IBM Corporation
@@ -124,24 +124,6 @@
 	return ret;
 }
 
-static struct subchannel *
-__get_subchannel_by_stsch(int irq)
-{
-	struct subchannel *sch;
-	int cc;
-	struct schib schib;
-
-	cc = stsch(irq, &schib);
-	if (cc || !schib.pmcw.dnv)
-		return NULL;
-	sch = (struct subchannel *)(unsigned long)schib.pmcw.intparm;
-	if (!sch)
-		return NULL;
-	if (get_device(&sch->dev))
-		return sch;
-	return NULL;
-}
-
 struct subchannel *
 get_subchannel_by_schid(int irq)
 {
@@ -151,13 +133,8 @@
 
 	if (!get_bus(&css_bus_type))
 		return NULL;
-
-	/* Try to get subchannel from pmcw first. */ 
-	sch = __get_subchannel_by_stsch(irq);
-	if (sch)
-		goto out;
 	down_read(&css_bus_type.subsys.rwsem);
-
+	sch = NULL;
 	list_for_each(entry, &css_bus_type.devices.list) {
 		dev = get_device(container_of(entry,
 					      struct device, bus_list));
@@ -170,7 +147,6 @@
 		sch = NULL;
 	}
 	up_read(&css_bus_type.subsys.rwsem);
-out:
 	put_bus(&css_bus_type);
 
 	return sch;
diff -urN linux-2.6/drivers/s390/cio/device.c linux-2.6-s390/drivers/s390/cio/device.c
--- linux-2.6/drivers/s390/cio/device.c	Wed Apr 28 17:51:15 2004
+++ linux-2.6-s390/drivers/s390/cio/device.c	Wed Apr 28 17:51:38 2004
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/device.c
  *  bus driver for ccw devices
- *   $Revision: 1.113 $
+ *   $Revision: 1.115 $
  *
  *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
  *			 IBM Corporation
@@ -138,6 +138,7 @@
 };
 
 struct workqueue_struct *ccw_device_work;
+struct workqueue_struct *ccw_device_notify_work;
 static wait_queue_head_t ccw_device_init_wq;
 static atomic_t ccw_device_init_count;
 
@@ -149,20 +150,30 @@
 	init_waitqueue_head(&ccw_device_init_wq);
 	atomic_set(&ccw_device_init_count, 0);
 
-	ccw_device_work = create_workqueue("cio");
+	ccw_device_work = create_singlethread_workqueue("cio");
 	if (!ccw_device_work)
 		return -ENOMEM; /* FIXME: better errno ? */
-
+	ccw_device_notify_work = create_singlethread_workqueue("cio_notify");
+	if (!ccw_device_notify_work) {
+		ret = -ENOMEM; /* FIXME: better errno ? */
+		goto out_err;
+	}
 	if ((ret = bus_register (&ccw_bus_type)))
-		return ret;
+		goto out_err;
 
 	if ((ret = driver_register(&io_subchannel_driver.drv)))
-		return ret;
+		goto out_err;
 
 	wait_event(ccw_device_init_wq,
 		   atomic_read(&ccw_device_init_count) == 0);
 	flush_workqueue(ccw_device_work);
 	return 0;
+out_err:
+	if (ccw_device_work)
+		destroy_workqueue(ccw_device_work);
+	if (ccw_device_notify_work)
+		destroy_workqueue(ccw_device_notify_work);
+	return ret;
 }
 
 static void __exit
@@ -170,6 +181,7 @@
 {
 	driver_unregister(&io_subchannel_driver.drv);
 	bus_unregister(&ccw_bus_type);
+	destroy_workqueue(ccw_device_notify_work);
 	destroy_workqueue(ccw_device_work);
 }
 
@@ -553,18 +565,21 @@
 	wake_up(&cdev->private->wait_q);
 }
 
-static void
-device_call_sch_unregister(void *data)
+void
+ccw_device_call_sch_unregister(void *data)
 {
 	struct ccw_device *cdev = data;
 	struct subchannel *sch;
 
 	sch = to_subchannel(cdev->dev.parent);
-	device_unregister(&sch->dev);
+	/* Check if device is registered. */
+	if (!list_empty(&sch->dev.node))
+		device_unregister(&sch->dev);
 	/* Reset intparm to zeroes. */
 	sch->schib.pmcw.intparm = 0;
 	cio_modify(sch);
 	put_device(&cdev->dev);
+	put_device(&sch->dev);
 }
 
 /*
@@ -587,7 +602,7 @@
 			break;
 		sch = to_subchannel(cdev->dev.parent);
 		INIT_WORK(&cdev->private->kick_work,
-			  device_call_sch_unregister, (void *) cdev);
+			  ccw_device_call_sch_unregister, (void *) cdev);
 		queue_work(ccw_device_work, &cdev->private->kick_work);
 		break;
 	case DEV_STATE_BOXED:
@@ -982,3 +997,4 @@
 EXPORT_SYMBOL(get_ccwdev_by_busid);
 EXPORT_SYMBOL(ccw_bus_type);
 EXPORT_SYMBOL(ccw_device_work);
+EXPORT_SYMBOL(ccw_device_notify_work);
diff -urN linux-2.6/drivers/s390/cio/device.h linux-2.6-s390/drivers/s390/cio/device.h
--- linux-2.6/drivers/s390/cio/device.h	Wed Apr 28 17:51:15 2004
+++ linux-2.6-s390/drivers/s390/cio/device.h	Wed Apr 28 17:51:38 2004
@@ -66,6 +66,7 @@
 }
 
 extern struct workqueue_struct *ccw_device_work;
+extern struct workqueue_struct *ccw_device_notify_work;
 
 void io_subchannel_recog_done(struct ccw_device *cdev);
 
@@ -73,7 +74,7 @@
 
 int ccw_device_register(struct ccw_device *);
 void ccw_device_do_unreg_rereg(void *);
-
+void ccw_device_call_sch_unregister(void *);
 
 int ccw_device_recognition(struct ccw_device *);
 int ccw_device_online(struct ccw_device *);
diff -urN linux-2.6/drivers/s390/cio/device_fsm.c linux-2.6-s390/drivers/s390/cio/device_fsm.c
--- linux-2.6/drivers/s390/cio/device_fsm.c	Wed Apr 28 17:51:15 2004
+++ linux-2.6-s390/drivers/s390/cio/device_fsm.c	Wed Apr 28 17:51:38 2004
@@ -328,7 +328,7 @@
 		cdev->private->flags.donotify = 0;
 		PREPARE_WORK(&cdev->private->kick_work, ccw_device_oper_notify,
 			     (void *)cdev);
-		queue_work(ccw_device_work, &cdev->private->kick_work);
+		queue_work(ccw_device_notify_work, &cdev->private->kick_work);
 	}
 	wake_up(&cdev->private->wait_q);
 
@@ -441,10 +441,13 @@
 		if (get_device(&sch->dev)) {
 			/* Driver doesn't want to keep device. */
 			cio_disable_subchannel(sch);
-			device_unregister(&sch->dev);
-			sch->schib.pmcw.intparm = 0;
-			cio_modify(sch);
-			put_device(&sch->dev);
+			if (get_device(&cdev->dev)) {
+				PREPARE_WORK(&cdev->private->kick_work,
+					     ccw_device_call_sch_unregister,
+					     (void *)cdev);
+				queue_work(ccw_device_work,
+					   &cdev->private->kick_work);
+			}
 		}
 	} else {
 		cio_disable_subchannel(sch);
@@ -464,7 +467,7 @@
 	cdev = sch->dev.driver_data;
 	PREPARE_WORK(&cdev->private->kick_work,
 		     ccw_device_nopath_notify, (void *)cdev);
-	queue_work(ccw_device_work, &cdev->private->kick_work);
+	queue_work(ccw_device_notify_work, &cdev->private->kick_work);
 }
 
 
@@ -482,7 +485,7 @@
 	default:
 		PREPARE_WORK(&cdev->private->kick_work,
 			     ccw_device_nopath_notify, (void *)cdev);
-		queue_work(ccw_device_work, &cdev->private->kick_work);
+		queue_work(ccw_device_notify_work, &cdev->private->kick_work);
 		ccw_device_done(cdev, DEV_STATE_NOT_OPER);
 		break;
 	}
@@ -722,7 +725,8 @@
 		if (!sch->lpm) {
 			PREPARE_WORK(&cdev->private->kick_work,
 				     ccw_device_nopath_notify, (void *)cdev);
-			queue_work(ccw_device_work, &cdev->private->kick_work);
+			queue_work(ccw_device_notify_work,
+				   &cdev->private->kick_work);
 		} else
 			dev_fsm_event(cdev, DEV_EVENT_NOTOPER);
 	} else if (cdev->handler)
@@ -798,7 +802,7 @@
 	if (!sch->lpm) {
 		PREPARE_WORK(&cdev->private->kick_work,
 			     ccw_device_nopath_notify, (void *)cdev);
-		queue_work(ccw_device_work, &cdev->private->kick_work);
+		queue_work(ccw_device_notify_work, &cdev->private->kick_work);
 	} else if (cdev->private->flags.doverify)
 		/* Start delayed path verification. */
 		ccw_device_online_verify(cdev, 0);
@@ -821,7 +825,8 @@
 		if (!sch->lpm) {
 			PREPARE_WORK(&cdev->private->kick_work,
 				     ccw_device_nopath_notify, (void *)cdev);
-			queue_work(ccw_device_work, &cdev->private->kick_work);
+			queue_work(ccw_device_notify_work,
+				   &cdev->private->kick_work);
 		} else
 			dev_fsm_event(cdev, DEV_EVENT_NOTOPER);
 		return;
@@ -871,7 +876,7 @@
 	if (!sch->lpm) {
 		PREPARE_WORK(&cdev->private->kick_work,
 			     ccw_device_nopath_notify, (void *)cdev);
-		queue_work(ccw_device_work, &cdev->private->kick_work);
+		queue_work(ccw_device_notify_work, &cdev->private->kick_work);
 	} else if (cdev->private->flags.doverify)
 		ccw_device_online_verify(cdev, 0);
 }
@@ -894,7 +899,8 @@
 		if (!sch->lpm) {
 			PREPARE_WORK(&cdev->private->kick_work,
 				     ccw_device_nopath_notify, (void *)cdev);
-			queue_work(ccw_device_work, &cdev->private->kick_work);
+			queue_work(ccw_device_notify_work,
+				   &cdev->private->kick_work);
 		} else
 			dev_fsm_event(cdev, DEV_EVENT_NOTOPER);
 		return;
@@ -905,7 +911,7 @@
 	if (!sch->lpm) {
 		PREPARE_WORK(&cdev->private->kick_work,
 			     ccw_device_nopath_notify, (void *)cdev);
-		queue_work(ccw_device_work, &cdev->private->kick_work);
+		queue_work(ccw_device_notify_work, &cdev->private->kick_work);
 	} else if (cdev->private->flags.doverify)
 		/* Start delayed path verification. */
 		ccw_device_online_verify(cdev, 0);
diff -urN linux-2.6/drivers/s390/cio/device_pgid.c linux-2.6-s390/drivers/s390/cio/device_pgid.c
--- linux-2.6/drivers/s390/cio/device_pgid.c	Sun Apr  4 05:37:23 2004
+++ linux-2.6-s390/drivers/s390/cio/device_pgid.c	Wed Apr 28 17:51:38 2004
@@ -227,7 +227,7 @@
 		ret = cio_start (sch, cdev->private->iccws,
 				 cdev->private->imask);
 		/* ret is 0, -EBUSY, -EACCES or -ENODEV */
-		if (ret != -EACCES)
+		if ((ret != -EACCES) && (ret != -ENODEV))
 			return ret;
 	}
 	/* PGID command failed on this path. Switch it off. */

^ permalink raw reply	[flat|nested] 2+ messages in thread
* [PATCH] s390 (2/6): common i/o layer.
@ 2004-05-13 19:14 Martin Schwidefsky
  0 siblings, 0 replies; 2+ messages in thread
From: Martin Schwidefsky @ 2004-05-13 19:14 UTC (permalink / raw)
  To: akpm, linux-kernel

[PATCH] s390: cio changes.

From: Martin Schwidefsky <schwidefsky@de.ibm.com>

Common i/o layer changes:
 - Delay unregister/register of ccw devices reappering on a different
   subchannel. Search for the old ccw_device & subchannel for the
   reattached device and deregister it too to avoid inconsistencies.
 - Fix path grouping for devices that present command reject for
   SetPGID but not for SensePGID.

diffstat:
 drivers/s390/cio/css.c         |   23 +++++++---
 drivers/s390/cio/device.c      |   92 ++++++++++++++++++++++++++++++++++++-----
 drivers/s390/cio/device_fsm.c  |   11 +++-
 drivers/s390/cio/device_pgid.c |    4 +
 4 files changed, 110 insertions(+), 20 deletions(-)

diff -urN linux-2.6/drivers/s390/cio/css.c linux-2.6-s390/drivers/s390/cio/css.c
--- linux-2.6/drivers/s390/cio/css.c	Mon May 10 04:32:01 2004
+++ linux-2.6-s390/drivers/s390/cio/css.c	Thu May 13 21:00:59 2004
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/css.c
  *  driver for channel subsystem
- *   $Revision: 1.73 $
+ *   $Revision: 1.74 $
  *
  *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
  *			 IBM Corporation
@@ -218,12 +218,21 @@
 		 * We don't notify the driver since we have to throw the device
 		 * away in any case.
 		 */
-		device_unregister(&sch->dev);
-		/* Reset intparm to zeroes. */
-		sch->schib.pmcw.intparm = 0;
-		cio_modify(sch);
-		put_device(&sch->dev);
-		ret = css_probe_device(irq);
+		if (!disc) {
+			device_unregister(&sch->dev);
+			/* Reset intparm to zeroes. */
+			sch->schib.pmcw.intparm = 0;
+			cio_modify(sch);
+			put_device(&sch->dev);
+			ret = css_probe_device(irq);
+		} else {
+			/*
+			 * We can't immediately deregister the disconnected
+			 * device since it might block.
+			 */
+			device_trigger_reprobe(sch);
+			ret = 0;
+		}
 		break;
 	case CIO_OPER:
 		if (disc)
diff -urN linux-2.6/drivers/s390/cio/device.c linux-2.6-s390/drivers/s390/cio/device.c
--- linux-2.6/drivers/s390/cio/device.c	Mon May 10 04:32:54 2004
+++ linux-2.6-s390/drivers/s390/cio/device.c	Thu May 13 21:00:59 2004
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/device.c
  *  bus driver for ccw devices
- *   $Revision: 1.115 $
+ *   $Revision: 1.117 $
  *
  *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
  *			 IBM Corporation
@@ -26,6 +26,7 @@
 #include "cio.h"
 #include "css.h"
 #include "device.h"
+#include "ioasm.h"
 
 /******************* bus type handling ***********************/
 
@@ -499,20 +500,93 @@
 	return ret;
 }
 
-void
-ccw_device_do_unreg_rereg(void *data)
+static struct ccw_device *
+get_disc_ccwdev_by_devno(unsigned int devno, struct ccw_device *sibling)
 {
+	struct ccw_device *cdev;
+	struct list_head *entry;
 	struct device *dev;
 
-	dev = (struct device *)data;
-	device_remove_files(dev);
-	device_del(dev);
-	if (device_add(dev)) {
+	if (!get_bus(&ccw_bus_type))
+		return NULL;
+	down_read(&ccw_bus_type.subsys.rwsem);
+	cdev = NULL;
+	list_for_each(entry, &ccw_bus_type.devices.list) {
+		dev = get_device(container_of(entry,
+					      struct device, bus_list));
+		if (!dev)
+			continue;
+		cdev = to_ccwdev(dev);
+		if ((cdev->private->state == DEV_STATE_DISCONNECTED) &&
+		    (cdev->private->devno == devno) &&
+		    (!strncmp(cdev->dev.bus_id, sibling->dev.bus_id, 4))) {
+			cdev->private->state = DEV_STATE_NOT_OPER;
+			break;
+		}
 		put_device(dev);
+		cdev = NULL;
+	}
+	up_read(&ccw_bus_type.subsys.rwsem);
+	put_bus(&ccw_bus_type);
+
+	return cdev;
+}
+
+void
+ccw_device_do_unreg_rereg(void *data)
+{
+	struct ccw_device *cdev;
+	struct subchannel *sch;
+	int need_rename;
+
+	cdev = (struct ccw_device *)data;
+	sch = to_subchannel(cdev->dev.parent);
+	if (cdev->private->devno != sch->schib.pmcw.dev) {
+		/*
+		 * The device number has changed. This is usually only when
+		 * a device has been detached under VM and then re-appeared
+		 * on another subchannel because of a different attachment
+		 * order than before. Ideally, we should should just switch
+		 * subchannels, but unfortunately, this is not possible with
+		 * the current implementation.
+		 * Instead, we search for the old subchannel for this device
+		 * number and deregister so there are no collisions with the
+		 * newly registered ccw_device.
+		 * FIXME: Find another solution so the block layer doesn't
+		 *        get possibly sick...
+		 */
+		struct ccw_device *other_cdev;
+
+		need_rename = 1;
+		other_cdev = get_disc_ccwdev_by_devno(sch->schib.pmcw.dev,
+						      cdev);
+		if (other_cdev) {
+			struct subchannel *other_sch;
+
+			other_sch = to_subchannel(other_cdev->dev.parent);
+			if (get_device(&other_sch->dev)) {
+				stsch(other_sch->irq, &other_sch->schib);
+				if (other_sch->schib.pmcw.dnv) {
+					other_sch->schib.pmcw.intparm = 0;
+					cio_modify(other_sch);
+				}
+				device_unregister(&other_sch->dev);
+			}
+		}
+		cdev->private->devno = sch->schib.pmcw.dev;
+	} else
+		need_rename = 0;
+	device_remove_files(&cdev->dev);
+	device_del(&cdev->dev);
+	if (need_rename)
+		snprintf (cdev->dev.bus_id, BUS_ID_SIZE, "0.0.%04x",
+			  sch->schib.pmcw.dev);
+	if (device_add(&cdev->dev)) {
+		put_device(&cdev->dev);
 		return;
 	}
-	if (device_add_files(dev))
-		device_unregister(dev);
+	if (device_add_files(&cdev->dev))
+		device_unregister(&cdev->dev);
 }
 
 static void
diff -urN linux-2.6/drivers/s390/cio/device_fsm.c linux-2.6-s390/drivers/s390/cio/device_fsm.c
--- linux-2.6/drivers/s390/cio/device_fsm.c	Mon May 10 04:32:37 2004
+++ linux-2.6-s390/drivers/s390/cio/device_fsm.c	Thu May 13 21:00:59 2004
@@ -152,14 +152,15 @@
 	/*
 	 * Check if cu type and device type still match. If
 	 * not, it is certainly another device and we have to
-	 * de- and re-register.
+	 * de- and re-register. Also check here for non-matching devno.
 	 */
 	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->id.dev_model != cdev->private->senseid.dev_model ||
+	    cdev->private->devno != sch->schib.pmcw.dev) {
 		PREPARE_WORK(&cdev->private->kick_work,
-			     ccw_device_do_unreg_rereg, (void *)&cdev->dev);
+			     ccw_device_do_unreg_rereg, (void *)cdev);
 		queue_work(ccw_device_work, &cdev->private->kick_work);
 		return;
 	}
@@ -295,7 +296,7 @@
 		sch->driver->notify(&sch->dev, CIO_OPER) : 0;
 	if (!ret)
 		/* Driver doesn't want device back. */
-		ccw_device_do_unreg_rereg((void *)&cdev->dev);
+		ccw_device_do_unreg_rereg((void *)cdev);
 	else
 		wake_up(&cdev->private->wait_q);
 }
@@ -476,6 +477,8 @@
 {
 	cdev->private->flags.doverify = 0;
 	switch (err) {
+	case -EOPNOTSUPP: /* path grouping not supported, just set online. */
+		cdev->private->options.pgroup = 0;
 	case 0:
 		ccw_device_done(cdev, DEV_STATE_ONLINE);
 		break;
diff -urN linux-2.6/drivers/s390/cio/device_pgid.c linux-2.6-s390/drivers/s390/cio/device_pgid.c
--- linux-2.6/drivers/s390/cio/device_pgid.c	Mon May 10 04:32:38 2004
+++ linux-2.6-s390/drivers/s390/cio/device_pgid.c	Thu May 13 21:00:59 2004
@@ -338,6 +338,10 @@
 		 * One of those strange devices which claim to be able
 		 * to do multipathing but not for Set Path Group ID.
 		 */
+		if (cdev->private->flags.pgid_single) {
+			ccw_device_verify_done(cdev, -EOPNOTSUPP);
+			break;
+		}
 		cdev->private->flags.pgid_single = 1;
 		/* fall through. */
 	case -EAGAIN:		/* Try again. */

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2004-05-13 19:22 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-04-28 16:49 [PATCH] s390 (2/6): common i/o layer Martin Schwidefsky
2004-05-13 19:14 Martin Schwidefsky

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®