diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2011-03-15 12:08:28 -0400 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2011-03-15 12:08:23 -0400 |
commit | 85fb534e27eca3f433a7b53bb78cf208b92bf190 (patch) | |
tree | 14ba66c82b776818bf2d8166def106e6a13b225d /drivers/s390/cio | |
parent | f92519e83e3bd509cb861a946701a26f74cb77fa (diff) |
[S390] css: move chsc_private to drv_data
Use the subchannels drv_data to access chsc_private
for chsc subchannels.
Note: Also set the drv_data prior to the cio_enable_subchannel
call, since we can receive an interrupt the moment we enable
the subchannel and the IRQ handler relies on this data.
Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio')
-rw-r--r-- | drivers/s390/cio/chsc_sch.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c index 3c3f3ffe217..09c2ea84a57 100644 --- a/drivers/s390/cio/chsc_sch.c +++ b/drivers/s390/cio/chsc_sch.c | |||
@@ -50,7 +50,7 @@ MODULE_LICENSE("GPL"); | |||
50 | 50 | ||
51 | static void chsc_subchannel_irq(struct subchannel *sch) | 51 | static void chsc_subchannel_irq(struct subchannel *sch) |
52 | { | 52 | { |
53 | struct chsc_private *private = sch->private; | 53 | struct chsc_private *private = dev_get_drvdata(&sch->dev); |
54 | struct chsc_request *request = private->request; | 54 | struct chsc_request *request = private->request; |
55 | struct irb *irb = (struct irb *)&S390_lowcore.irb; | 55 | struct irb *irb = (struct irb *)&S390_lowcore.irb; |
56 | 56 | ||
@@ -80,13 +80,14 @@ static int chsc_subchannel_probe(struct subchannel *sch) | |||
80 | private = kzalloc(sizeof(*private), GFP_KERNEL); | 80 | private = kzalloc(sizeof(*private), GFP_KERNEL); |
81 | if (!private) | 81 | if (!private) |
82 | return -ENOMEM; | 82 | return -ENOMEM; |
83 | dev_set_drvdata(&sch->dev, private); | ||
83 | ret = cio_enable_subchannel(sch, (u32)(unsigned long)sch); | 84 | ret = cio_enable_subchannel(sch, (u32)(unsigned long)sch); |
84 | if (ret) { | 85 | if (ret) { |
85 | CHSC_MSG(0, "Failed to enable 0.%x.%04x: %d\n", | 86 | CHSC_MSG(0, "Failed to enable 0.%x.%04x: %d\n", |
86 | sch->schid.ssid, sch->schid.sch_no, ret); | 87 | sch->schid.ssid, sch->schid.sch_no, ret); |
88 | dev_set_drvdata(&sch->dev, NULL); | ||
87 | kfree(private); | 89 | kfree(private); |
88 | } else { | 90 | } else { |
89 | sch->private = private; | ||
90 | if (dev_get_uevent_suppress(&sch->dev)) { | 91 | if (dev_get_uevent_suppress(&sch->dev)) { |
91 | dev_set_uevent_suppress(&sch->dev, 0); | 92 | dev_set_uevent_suppress(&sch->dev, 0); |
92 | kobject_uevent(&sch->dev.kobj, KOBJ_ADD); | 93 | kobject_uevent(&sch->dev.kobj, KOBJ_ADD); |
@@ -100,8 +101,8 @@ static int chsc_subchannel_remove(struct subchannel *sch) | |||
100 | struct chsc_private *private; | 101 | struct chsc_private *private; |
101 | 102 | ||
102 | cio_disable_subchannel(sch); | 103 | cio_disable_subchannel(sch); |
103 | private = sch->private; | 104 | private = dev_get_drvdata(&sch->dev); |
104 | sch->private = NULL; | 105 | dev_set_drvdata(&sch->dev, NULL); |
105 | if (private->request) { | 106 | if (private->request) { |
106 | complete(&private->request->completion); | 107 | complete(&private->request->completion); |
107 | put_device(&sch->dev); | 108 | put_device(&sch->dev); |
@@ -241,7 +242,7 @@ static int chsc_async(struct chsc_async_area *chsc_area, | |||
241 | chsc_area->header.key = PAGE_DEFAULT_KEY >> 4; | 242 | chsc_area->header.key = PAGE_DEFAULT_KEY >> 4; |
242 | while ((sch = chsc_get_next_subchannel(sch))) { | 243 | while ((sch = chsc_get_next_subchannel(sch))) { |
243 | spin_lock(sch->lock); | 244 | spin_lock(sch->lock); |
244 | private = sch->private; | 245 | private = dev_get_drvdata(&sch->dev); |
245 | if (private->request) { | 246 | if (private->request) { |
246 | spin_unlock(sch->lock); | 247 | spin_unlock(sch->lock); |
247 | ret = -EBUSY; | 248 | ret = -EBUSY; |