s390: subchannel register/unregister mutex.
Subsystems (2)
PATCH 1/1 s390: subchannel register/unregister mutex.
From: Cornelia Huck <[email protected]>
[S390] subchannel register/unregister mutex.
Add a reg_mutex to prevent unregistering a subchannel before it has been registered. Since 2.6.17, we've seen oopses in kslowcrw when a device is found to be not operational during sense id when doing initial device recognition; it is not clear yet why that particular problem was not (yet) observed with earlier kernels...
Signed-off-by Cornelia Huck <[email protected]>
Signed-off-by Martin Schwidefsky <[email protected]>
---
drivers/s390/cio/cio.c | 1 + drivers/s390/cio/cio.h | 3 ++- drivers/s390/cio/css.c | 24 +++++++++++++++++++++--- drivers/s390/cio/css.h | 2 ++ drivers/s390/cio/device.c | 6 +++--- 5 files changed, 29 insertions(+), 7 deletions(-)
drivers/s390/cio/cio.c +1 -0
@@ -519,6 +519,7 @@ cio_validate_subchannel (struct subchannmemset (sch,0 ,sizeof (struct subchannel ));spin_lock_init (&sch->lock); +mutex_init (&sch->reg_mutex);/* Set a name for the subchannel */ snprintf (sch->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x", schid.ssid,
drivers/s390/cio/cio.h +2 -1
@@ -2,6 +2,7 @@#define S390_CIO_H #include "schid.h" +#include <linux/mutex.h> /* * where we put the ssd info
@@ -87,7 +88,7 @@ struct orb {struct subchannel {struct subchannel_id schid;spinlock_t lock;/* subchannel lock */ - +struct mutex reg_mutex;enum {SUBCHANNEL_TYPE_IO =0 ,SUBCHANNEL_TYPE_CHSC =1 ,
drivers/s390/cio/css.c +21 -3
@@ -108,6 +108,24 @@ css_subchannel_release(struct device *deextern int css_get_ssd_info (struct subchannel *sch); + +int css_sch_device_register (struct subchannel *sch) +{ +int ret; + +mutex_lock (&sch->reg_mutex); + ret =device_register (&sch->dev); +mutex_unlock (&sch->reg_mutex); +return ret; +} + +void css_sch_device_unregister (struct subchannel *sch) +{ +mutex_lock (&sch->reg_mutex); +device_unregister (&sch->dev); +mutex_unlock (&sch->reg_mutex); +} +static int css_register_subchannel (struct subchannel *sch) {
@@ -119,7 +137,7 @@ css_register_subchannel(struct subchanne sch->dev.release = &css_subchannel_release;/* make it known to the system */ - ret =device_register (&sch->dev); + ret =css_sch_device_register (sch);if (ret)printk (KERN_WARNING "%s: could not register %s\n" , __func__, sch->dev.bus_id);
@@ -250,7 +268,7 @@ css_evaluate_subchannel(struct subchanne* The device will be killed automatically. */ cio_disable_subchannel (sch); -device_unregister (&sch->dev); +css_sch_device_unregister (sch);/* Reset intparm to zeroes. */ sch->schib.pmcw.intparm =0 ;cio_modify (sch);
@@ -264,7 +282,7 @@ css_evaluate_subchannel(struct subchanne* away in any case. */ if (!disc) { -device_unregister (&sch->dev); +css_sch_device_unregister (sch);/* Reset intparm to zeroes. */ sch->schib.pmcw.intparm =0 ;cio_modify (sch);
drivers/s390/cio/css.h +2 -0
@@ -136,6 +136,8 @@ extern struct bus_type css_bus_type;extern struct css_driver io_subchannel_driver;extern int css_probe_device (struct subchannel_id ); +extern int css_sch_device_register (struct subchannel *); +extern void css_sch_device_unregister (struct subchannel *);extern struct subchannel *get_subchannel_by_schid (struct subchannel_id );extern int css_init_done;extern int for_each_subchannel (int (*fn)(struct subchannel_id ,void *),void *);
drivers/s390/cio/device.c +3 -3
@@ -280,7 +280,7 @@ ccw_device_remove_disconnected(struct cc* 'throw away device'. */ sch =to_subchannel (cdev->dev.parent); -device_unregister (&sch->dev); +css_sch_device_unregister (sch);/* Reset intparm to zeroes. */ sch->schib.pmcw.intparm =0 ;cio_modify (sch);
@@ -625,7 +625,7 @@ ccw_device_do_unreg_rereg(void *data) other_sch->schib.pmcw.intparm =0 ;cio_modify (other_sch); } -device_unregister (&other_sch->dev); +css_sch_device_unregister (other_sch); } }/* Update ssd info here. */
@@ -709,7 +709,7 @@ ccw_device_call_sch_unregister(void *datstruct subchannel *sch; sch =to_subchannel (cdev->dev.parent); -device_unregister (&sch->dev); +css_sch_device_unregister (sch);/* Reset intparm to zeroes. */ sch->schib.pmcw.intparm =0 ;cio_modify (sch);