aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2006-12-08 09:53:57 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2006-12-08 09:53:57 -0500
commitc16375329c2ab4667df873394c4be7a61d163c62 (patch)
tree9ee9505e4587ce5f472db3fd09935611b0062f83 /drivers/s390
parente45ccc0562e3f391dcba8b2e8a02551e8e42d8db (diff)
[S390] more workqueue fixes.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/char/tape.h3
-rw-r--r--drivers/s390/char/tape_34xx.c23
-rw-r--r--drivers/s390/char/tape_3590.c7
-rw-r--r--drivers/s390/char/tape_block.c14
-rw-r--r--drivers/s390/char/tape_core.c14
-rw-r--r--drivers/s390/cio/css.h2
-rw-r--r--drivers/s390/cio/device.c43
-rw-r--r--drivers/s390/cio/device.h4
-rw-r--r--drivers/s390/cio/device_fsm.c38
-rw-r--r--drivers/s390/cio/qdio.c8
10 files changed, 89 insertions, 67 deletions
diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h
index 1f4c89967be4..c9f1c4c8bb13 100644
--- a/drivers/s390/char/tape.h
+++ b/drivers/s390/char/tape.h
@@ -179,6 +179,7 @@ struct tape_char_data {
179/* Block Frontend Data */ 179/* Block Frontend Data */
180struct tape_blk_data 180struct tape_blk_data
181{ 181{
182 struct tape_device * device;
182 /* Block device request queue. */ 183 /* Block device request queue. */
183 request_queue_t * request_queue; 184 request_queue_t * request_queue;
184 spinlock_t request_queue_lock; 185 spinlock_t request_queue_lock;
@@ -240,7 +241,7 @@ struct tape_device {
240#endif 241#endif
241 242
242 /* Function to start or stop the next request later. */ 243 /* Function to start or stop the next request later. */
243 struct work_struct tape_dnr; 244 struct delayed_work tape_dnr;
244}; 245};
245 246
246/* Externals from tape_core.c */ 247/* Externals from tape_core.c */
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c
index 7b95dab913d0..e765875e8db2 100644
--- a/drivers/s390/char/tape_34xx.c
+++ b/drivers/s390/char/tape_34xx.c
@@ -95,6 +95,12 @@ tape_34xx_medium_sense(struct tape_device *device)
95 return rc; 95 return rc;
96} 96}
97 97
98struct tape_34xx_work {
99 struct tape_device *device;
100 enum tape_op op;
101 struct work_struct work;
102};
103
98/* 104/*
99 * These functions are currently used only to schedule a medium_sense for 105 * These functions are currently used only to schedule a medium_sense for
100 * later execution. This is because we get an interrupt whenever a medium 106 * later execution. This is because we get an interrupt whenever a medium
@@ -103,13 +109,10 @@ tape_34xx_medium_sense(struct tape_device *device)
103 * interrupt handler. 109 * interrupt handler.
104 */ 110 */
105static void 111static void
106tape_34xx_work_handler(void *data) 112tape_34xx_work_handler(struct work_struct *work)
107{ 113{
108 struct { 114 struct tape_34xx_work *p =
109 struct tape_device *device; 115 container_of(work, struct tape_34xx_work, work);
110 enum tape_op op;
111 struct work_struct work;
112 } *p = data;
113 116
114 switch(p->op) { 117 switch(p->op) {
115 case TO_MSEN: 118 case TO_MSEN:
@@ -126,17 +129,13 @@ tape_34xx_work_handler(void *data)
126static int 129static int
127tape_34xx_schedule_work(struct tape_device *device, enum tape_op op) 130tape_34xx_schedule_work(struct tape_device *device, enum tape_op op)
128{ 131{
129 struct { 132 struct tape_34xx_work *p;
130 struct tape_device *device;
131 enum tape_op op;
132 struct work_struct work;
133 } *p;
134 133
135 if ((p = kmalloc(sizeof(*p), GFP_ATOMIC)) == NULL) 134 if ((p = kmalloc(sizeof(*p), GFP_ATOMIC)) == NULL)
136 return -ENOMEM; 135 return -ENOMEM;
137 136
138 memset(p, 0, sizeof(*p)); 137 memset(p, 0, sizeof(*p));
139 INIT_WORK(&p->work, tape_34xx_work_handler, p); 138 INIT_WORK(&p->work, tape_34xx_work_handler);
140 139
141 p->device = tape_get_device_reference(device); 140 p->device = tape_get_device_reference(device);
142 p->op = op; 141 p->op = op;
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c
index 928cbefc49d5..9df912f63188 100644
--- a/drivers/s390/char/tape_3590.c
+++ b/drivers/s390/char/tape_3590.c
@@ -236,9 +236,10 @@ struct work_handler_data {
236}; 236};
237 237
238static void 238static void
239tape_3590_work_handler(void *data) 239tape_3590_work_handler(struct work_struct *work)
240{ 240{
241 struct work_handler_data *p = data; 241 struct work_handler_data *p =
242 container_of(work, struct work_handler_data, work);
242 243
243 switch (p->op) { 244 switch (p->op) {
244 case TO_MSEN: 245 case TO_MSEN:
@@ -263,7 +264,7 @@ tape_3590_schedule_work(struct tape_device *device, enum tape_op op)
263 if ((p = kzalloc(sizeof(*p), GFP_ATOMIC)) == NULL) 264 if ((p = kzalloc(sizeof(*p), GFP_ATOMIC)) == NULL)
264 return -ENOMEM; 265 return -ENOMEM;
265 266
266 INIT_WORK(&p->work, tape_3590_work_handler, p); 267 INIT_WORK(&p->work, tape_3590_work_handler);
267 268
268 p->device = tape_get_device_reference(device); 269 p->device = tape_get_device_reference(device);
269 p->op = op; 270 p->op = op;
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c
index 3225fcd1dcb4..c8a89b3b87d4 100644
--- a/drivers/s390/char/tape_block.c
+++ b/drivers/s390/char/tape_block.c
@@ -15,6 +15,7 @@
15#include <linux/blkdev.h> 15#include <linux/blkdev.h>
16#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/buffer_head.h> 17#include <linux/buffer_head.h>
18#include <linux/kernel.h>
18 19
19#include <asm/debug.h> 20#include <asm/debug.h>
20 21
@@ -143,7 +144,8 @@ tapeblock_start_request(struct tape_device *device, struct request *req)
143 * queue. 144 * queue.
144 */ 145 */
145static void 146static void
146tapeblock_requeue(void *data) { 147tapeblock_requeue(struct work_struct *work) {
148 struct tape_blk_data * blkdat;
147 struct tape_device * device; 149 struct tape_device * device;
148 request_queue_t * queue; 150 request_queue_t * queue;
149 int nr_queued; 151 int nr_queued;
@@ -151,7 +153,8 @@ tapeblock_requeue(void *data) {
151 struct list_head * l; 153 struct list_head * l;
152 int rc; 154 int rc;
153 155
154 device = (struct tape_device *) data; 156 blkdat = container_of(work, struct tape_blk_data, requeue_task);
157 device = blkdat->device;
155 if (!device) 158 if (!device)
156 return; 159 return;
157 160
@@ -212,6 +215,7 @@ tapeblock_setup_device(struct tape_device * device)
212 int rc; 215 int rc;
213 216
214 blkdat = &device->blk_data; 217 blkdat = &device->blk_data;
218 blkdat->device = device;
215 spin_lock_init(&blkdat->request_queue_lock); 219 spin_lock_init(&blkdat->request_queue_lock);
216 atomic_set(&blkdat->requeue_scheduled, 0); 220 atomic_set(&blkdat->requeue_scheduled, 0);
217 221
@@ -255,8 +259,8 @@ tapeblock_setup_device(struct tape_device * device)
255 259
256 add_disk(disk); 260 add_disk(disk);
257 261
258 INIT_WORK(&blkdat->requeue_task, tapeblock_requeue, 262 tape_get_device_reference(device);
259 tape_get_device_reference(device)); 263 INIT_WORK(&blkdat->requeue_task, tapeblock_requeue);
260 264
261 return 0; 265 return 0;
262 266
@@ -271,7 +275,7 @@ void
271tapeblock_cleanup_device(struct tape_device *device) 275tapeblock_cleanup_device(struct tape_device *device)
272{ 276{
273 flush_scheduled_work(); 277 flush_scheduled_work();
274 device->blk_data.requeue_task.data = tape_put_device(device); 278 tape_put_device(device);
275 279
276 if (!device->blk_data.disk) { 280 if (!device->blk_data.disk) {
277 PRINT_ERR("(%s): No gendisk to clean up!\n", 281 PRINT_ERR("(%s): No gendisk to clean up!\n",
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index 2826aed91043..c6c2e918b990 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -28,7 +28,7 @@
28#define PRINTK_HEADER "TAPE_CORE: " 28#define PRINTK_HEADER "TAPE_CORE: "
29 29
30static void __tape_do_irq (struct ccw_device *, unsigned long, struct irb *); 30static void __tape_do_irq (struct ccw_device *, unsigned long, struct irb *);
31static void tape_delayed_next_request(void * data); 31static void tape_delayed_next_request(struct work_struct *);
32 32
33/* 33/*
34 * One list to contain all tape devices of all disciplines, so 34 * One list to contain all tape devices of all disciplines, so
@@ -272,7 +272,7 @@ __tape_cancel_io(struct tape_device *device, struct tape_request *request)
272 return 0; 272 return 0;
273 case -EBUSY: 273 case -EBUSY:
274 request->status = TAPE_REQUEST_CANCEL; 274 request->status = TAPE_REQUEST_CANCEL;
275 schedule_work(&device->tape_dnr); 275 schedule_delayed_work(&device->tape_dnr, 0);
276 return 0; 276 return 0;
277 case -ENODEV: 277 case -ENODEV:
278 DBF_EXCEPTION(2, "device gone, retry\n"); 278 DBF_EXCEPTION(2, "device gone, retry\n");
@@ -470,7 +470,7 @@ tape_alloc_device(void)
470 *device->modeset_byte = 0; 470 *device->modeset_byte = 0;
471 device->first_minor = -1; 471 device->first_minor = -1;
472 atomic_set(&device->ref_count, 1); 472 atomic_set(&device->ref_count, 1);
473 INIT_WORK(&device->tape_dnr, tape_delayed_next_request, device); 473 INIT_DELAYED_WORK(&device->tape_dnr, tape_delayed_next_request);
474 474
475 return device; 475 return device;
476} 476}
@@ -724,7 +724,7 @@ __tape_start_io(struct tape_device *device, struct tape_request *request)
724 } else if (rc == -EBUSY) { 724 } else if (rc == -EBUSY) {
725 /* The common I/O subsystem is currently busy. Retry later. */ 725 /* The common I/O subsystem is currently busy. Retry later. */
726 request->status = TAPE_REQUEST_QUEUED; 726 request->status = TAPE_REQUEST_QUEUED;
727 schedule_work(&device->tape_dnr); 727 schedule_delayed_work(&device->tape_dnr, 0);
728 rc = 0; 728 rc = 0;
729 } else { 729 } else {
730 /* Start failed. Remove request and indicate failure. */ 730 /* Start failed. Remove request and indicate failure. */
@@ -790,11 +790,11 @@ __tape_start_next_request(struct tape_device *device)
790} 790}
791 791
792static void 792static void
793tape_delayed_next_request(void *data) 793tape_delayed_next_request(struct work_struct *work)
794{ 794{
795 struct tape_device * device; 795 struct tape_device *device =
796 container_of(work, struct tape_device, tape_dnr.work);
796 797
797 device = (struct tape_device *) data;
798 DBF_LH(6, "tape_delayed_next_request(%p)\n", device); 798 DBF_LH(6, "tape_delayed_next_request(%p)\n", device);
799 spin_lock_irq(get_ccwdev_lock(device->cdev)); 799 spin_lock_irq(get_ccwdev_lock(device->cdev));
800 __tape_start_next_request(device); 800 __tape_start_next_request(device);
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h
index 9ff064e71767..dfd5462f993f 100644
--- a/drivers/s390/cio/css.h
+++ b/drivers/s390/cio/css.h
@@ -73,6 +73,8 @@ struct senseid {
73} __attribute__ ((packed,aligned(4))); 73} __attribute__ ((packed,aligned(4)));
74 74
75struct ccw_device_private { 75struct ccw_device_private {
76 struct ccw_device *cdev;
77 struct subchannel *sch;
76 int state; /* device state */ 78 int state; /* device state */
77 atomic_t onoff; 79 atomic_t onoff;
78 unsigned long registered; 80 unsigned long registered;
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index d3d3716ff84b..0f604621de40 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -585,12 +585,13 @@ static struct ccw_device * get_disc_ccwdev_by_dev_id(struct ccw_dev_id *dev_id,
585} 585}
586 586
587static void 587static void
588ccw_device_add_changed(void *data) 588ccw_device_add_changed(struct work_struct *work)
589{ 589{
590 590 struct ccw_device_private *priv;
591 struct ccw_device *cdev; 591 struct ccw_device *cdev;
592 592
593 cdev = data; 593 priv = container_of(work, struct ccw_device_private, kick_work);
594 cdev = priv->cdev;
594 if (device_add(&cdev->dev)) { 595 if (device_add(&cdev->dev)) {
595 put_device(&cdev->dev); 596 put_device(&cdev->dev);
596 return; 597 return;
@@ -605,13 +606,15 @@ ccw_device_add_changed(void *data)
605extern int css_get_ssd_info(struct subchannel *sch); 606extern int css_get_ssd_info(struct subchannel *sch);
606 607
607void 608void
608ccw_device_do_unreg_rereg(void *data) 609ccw_device_do_unreg_rereg(struct work_struct *work)
609{ 610{
611 struct ccw_device_private *priv;
610 struct ccw_device *cdev; 612 struct ccw_device *cdev;
611 struct subchannel *sch; 613 struct subchannel *sch;
612 int need_rename; 614 int need_rename;
613 615
614 cdev = data; 616 priv = container_of(work, struct ccw_device_private, kick_work);
617 cdev = priv->cdev;
615 sch = to_subchannel(cdev->dev.parent); 618 sch = to_subchannel(cdev->dev.parent);
616 if (cdev->private->dev_id.devno != sch->schib.pmcw.dev) { 619 if (cdev->private->dev_id.devno != sch->schib.pmcw.dev) {
617 /* 620 /*
@@ -659,7 +662,7 @@ ccw_device_do_unreg_rereg(void *data)
659 snprintf (cdev->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x", 662 snprintf (cdev->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x",
660 sch->schid.ssid, sch->schib.pmcw.dev); 663 sch->schid.ssid, sch->schib.pmcw.dev);
661 PREPARE_WORK(&cdev->private->kick_work, 664 PREPARE_WORK(&cdev->private->kick_work,
662 ccw_device_add_changed, cdev); 665 ccw_device_add_changed);
663 queue_work(ccw_device_work, &cdev->private->kick_work); 666 queue_work(ccw_device_work, &cdev->private->kick_work);
664} 667}
665 668
@@ -677,14 +680,16 @@ ccw_device_release(struct device *dev)
677 * Register recognized device. 680 * Register recognized device.
678 */ 681 */
679static void 682static void
680io_subchannel_register(void *data) 683io_subchannel_register(struct work_struct *work)
681{ 684{
685 struct ccw_device_private *priv;
682 struct ccw_device *cdev; 686 struct ccw_device *cdev;
683 struct subchannel *sch; 687 struct subchannel *sch;
684 int ret; 688 int ret;
685 unsigned long flags; 689 unsigned long flags;
686 690
687 cdev = data; 691 priv = container_of(work, struct ccw_device_private, kick_work);
692 cdev = priv->cdev;
688 sch = to_subchannel(cdev->dev.parent); 693 sch = to_subchannel(cdev->dev.parent);
689 694
690 /* 695 /*
@@ -734,11 +739,14 @@ out:
734} 739}
735 740
736void 741void
737ccw_device_call_sch_unregister(void *data) 742ccw_device_call_sch_unregister(struct work_struct *work)
738{ 743{
739 struct ccw_device *cdev = data; 744 struct ccw_device_private *priv;
745 struct ccw_device *cdev;
740 struct subchannel *sch; 746 struct subchannel *sch;
741 747
748 priv = container_of(work, struct ccw_device_private, kick_work);
749 cdev = priv->cdev;
742 sch = to_subchannel(cdev->dev.parent); 750 sch = to_subchannel(cdev->dev.parent);
743 css_sch_device_unregister(sch); 751 css_sch_device_unregister(sch);
744 /* Reset intparm to zeroes. */ 752 /* Reset intparm to zeroes. */
@@ -768,7 +776,7 @@ io_subchannel_recog_done(struct ccw_device *cdev)
768 break; 776 break;
769 sch = to_subchannel(cdev->dev.parent); 777 sch = to_subchannel(cdev->dev.parent);
770 PREPARE_WORK(&cdev->private->kick_work, 778 PREPARE_WORK(&cdev->private->kick_work,
771 ccw_device_call_sch_unregister, cdev); 779 ccw_device_call_sch_unregister);
772 queue_work(slow_path_wq, &cdev->private->kick_work); 780 queue_work(slow_path_wq, &cdev->private->kick_work);
773 if (atomic_dec_and_test(&ccw_device_init_count)) 781 if (atomic_dec_and_test(&ccw_device_init_count))
774 wake_up(&ccw_device_init_wq); 782 wake_up(&ccw_device_init_wq);
@@ -783,7 +791,7 @@ io_subchannel_recog_done(struct ccw_device *cdev)
783 if (!get_device(&cdev->dev)) 791 if (!get_device(&cdev->dev))
784 break; 792 break;
785 PREPARE_WORK(&cdev->private->kick_work, 793 PREPARE_WORK(&cdev->private->kick_work,
786 io_subchannel_register, cdev); 794 io_subchannel_register);
787 queue_work(slow_path_wq, &cdev->private->kick_work); 795 queue_work(slow_path_wq, &cdev->private->kick_work);
788 break; 796 break;
789 } 797 }
@@ -865,6 +873,7 @@ io_subchannel_probe (struct subchannel *sch)
865 kfree(cdev); 873 kfree(cdev);
866 return -ENOMEM; 874 return -ENOMEM;
867 } 875 }
876 cdev->private->cdev = cdev;
868 atomic_set(&cdev->private->onoff, 0); 877 atomic_set(&cdev->private->onoff, 0);
869 cdev->dev.parent = &sch->dev; 878 cdev->dev.parent = &sch->dev;
870 cdev->dev.release = ccw_device_release; 879 cdev->dev.release = ccw_device_release;
@@ -890,12 +899,13 @@ io_subchannel_probe (struct subchannel *sch)
890 return rc; 899 return rc;
891} 900}
892 901
893static void 902static void ccw_device_unregister(struct work_struct *work)
894ccw_device_unregister(void *data)
895{ 903{
904 struct ccw_device_private *priv;
896 struct ccw_device *cdev; 905 struct ccw_device *cdev;
897 906
898 cdev = (struct ccw_device *)data; 907 priv = container_of(work, struct ccw_device_private, kick_work);
908 cdev = priv->cdev;
899 if (test_and_clear_bit(1, &cdev->private->registered)) 909 if (test_and_clear_bit(1, &cdev->private->registered))
900 device_unregister(&cdev->dev); 910 device_unregister(&cdev->dev);
901 put_device(&cdev->dev); 911 put_device(&cdev->dev);
@@ -921,7 +931,7 @@ io_subchannel_remove (struct subchannel *sch)
921 */ 931 */
922 if (get_device(&cdev->dev)) { 932 if (get_device(&cdev->dev)) {
923 PREPARE_WORK(&cdev->private->kick_work, 933 PREPARE_WORK(&cdev->private->kick_work,
924 ccw_device_unregister, cdev); 934 ccw_device_unregister);
925 queue_work(ccw_device_work, &cdev->private->kick_work); 935 queue_work(ccw_device_work, &cdev->private->kick_work);
926 } 936 }
927 return 0; 937 return 0;
@@ -1048,6 +1058,7 @@ ccw_device_probe_console(void)
1048 memset(&console_cdev, 0, sizeof(struct ccw_device)); 1058 memset(&console_cdev, 0, sizeof(struct ccw_device));
1049 memset(&console_private, 0, sizeof(struct ccw_device_private)); 1059 memset(&console_private, 0, sizeof(struct ccw_device_private));
1050 console_cdev.private = &console_private; 1060 console_cdev.private = &console_private;
1061 console_private.cdev = &console_cdev;
1051 ret = ccw_device_console_enable(&console_cdev, sch); 1062 ret = ccw_device_console_enable(&console_cdev, sch);
1052 if (ret) { 1063 if (ret) {
1053 cio_release_console(); 1064 cio_release_console();
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
index 9233b5c0bcc8..d5fe95e04cfe 100644
--- a/drivers/s390/cio/device.h
+++ b/drivers/s390/cio/device.h
@@ -78,8 +78,8 @@ void io_subchannel_recog_done(struct ccw_device *cdev);
78 78
79int ccw_device_cancel_halt_clear(struct ccw_device *); 79int ccw_device_cancel_halt_clear(struct ccw_device *);
80 80
81void ccw_device_do_unreg_rereg(void *); 81void ccw_device_do_unreg_rereg(struct work_struct *);
82void ccw_device_call_sch_unregister(void *); 82void ccw_device_call_sch_unregister(struct work_struct *);
83 83
84int ccw_device_recognition(struct ccw_device *); 84int ccw_device_recognition(struct ccw_device *);
85int ccw_device_online(struct ccw_device *); 85int ccw_device_online(struct ccw_device *);
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 09c7672eb3f3..0f0301ce37fe 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -194,7 +194,7 @@ ccw_device_handle_oper(struct ccw_device *cdev)
194 cdev->id.dev_model != cdev->private->senseid.dev_model || 194 cdev->id.dev_model != cdev->private->senseid.dev_model ||
195 cdev->private->dev_id.devno != sch->schib.pmcw.dev) { 195 cdev->private->dev_id.devno != sch->schib.pmcw.dev) {
196 PREPARE_WORK(&cdev->private->kick_work, 196 PREPARE_WORK(&cdev->private->kick_work,
197 ccw_device_do_unreg_rereg, cdev); 197 ccw_device_do_unreg_rereg);
198 queue_work(ccw_device_work, &cdev->private->kick_work); 198 queue_work(ccw_device_work, &cdev->private->kick_work);
199 return 0; 199 return 0;
200 } 200 }
@@ -329,19 +329,21 @@ ccw_device_sense_id_done(struct ccw_device *cdev, int err)
329} 329}
330 330
331static void 331static void
332ccw_device_oper_notify(void *data) 332ccw_device_oper_notify(struct work_struct *work)
333{ 333{
334 struct ccw_device_private *priv;
334 struct ccw_device *cdev; 335 struct ccw_device *cdev;
335 struct subchannel *sch; 336 struct subchannel *sch;
336 int ret; 337 int ret;
337 338
338 cdev = data; 339 priv = container_of(work, struct ccw_device_private, kick_work);
340 cdev = priv->cdev;
339 sch = to_subchannel(cdev->dev.parent); 341 sch = to_subchannel(cdev->dev.parent);
340 ret = (sch->driver && sch->driver->notify) ? 342 ret = (sch->driver && sch->driver->notify) ?
341 sch->driver->notify(&sch->dev, CIO_OPER) : 0; 343 sch->driver->notify(&sch->dev, CIO_OPER) : 0;
342 if (!ret) 344 if (!ret)
343 /* Driver doesn't want device back. */ 345 /* Driver doesn't want device back. */
344 ccw_device_do_unreg_rereg(cdev); 346 ccw_device_do_unreg_rereg(work);
345 else { 347 else {
346 /* Reenable channel measurements, if needed. */ 348 /* Reenable channel measurements, if needed. */
347 cmf_reenable(cdev); 349 cmf_reenable(cdev);
@@ -377,8 +379,7 @@ ccw_device_done(struct ccw_device *cdev, int state)
377 379
378 if (cdev->private->flags.donotify) { 380 if (cdev->private->flags.donotify) {
379 cdev->private->flags.donotify = 0; 381 cdev->private->flags.donotify = 0;
380 PREPARE_WORK(&cdev->private->kick_work, ccw_device_oper_notify, 382 PREPARE_WORK(&cdev->private->kick_work, ccw_device_oper_notify);
381 cdev);
382 queue_work(ccw_device_notify_work, &cdev->private->kick_work); 383 queue_work(ccw_device_notify_work, &cdev->private->kick_work);
383 } 384 }
384 wake_up(&cdev->private->wait_q); 385 wake_up(&cdev->private->wait_q);
@@ -528,13 +529,15 @@ ccw_device_recog_timeout(struct ccw_device *cdev, enum dev_event dev_event)
528 529
529 530
530static void 531static void
531ccw_device_nopath_notify(void *data) 532ccw_device_nopath_notify(struct work_struct *work)
532{ 533{
534 struct ccw_device_private *priv;
533 struct ccw_device *cdev; 535 struct ccw_device *cdev;
534 struct subchannel *sch; 536 struct subchannel *sch;
535 int ret; 537 int ret;
536 538
537 cdev = data; 539 priv = container_of(work, struct ccw_device_private, kick_work);
540 cdev = priv->cdev;
538 sch = to_subchannel(cdev->dev.parent); 541 sch = to_subchannel(cdev->dev.parent);
539 /* Extra sanity. */ 542 /* Extra sanity. */
540 if (sch->lpm) 543 if (sch->lpm)
@@ -547,8 +550,7 @@ ccw_device_nopath_notify(void *data)
547 cio_disable_subchannel(sch); 550 cio_disable_subchannel(sch);
548 if (get_device(&cdev->dev)) { 551 if (get_device(&cdev->dev)) {
549 PREPARE_WORK(&cdev->private->kick_work, 552 PREPARE_WORK(&cdev->private->kick_work,
550 ccw_device_call_sch_unregister, 553 ccw_device_call_sch_unregister);
551 cdev);
552 queue_work(ccw_device_work, 554 queue_work(ccw_device_work,
553 &cdev->private->kick_work); 555 &cdev->private->kick_work);
554 } else 556 } else
@@ -607,7 +609,7 @@ ccw_device_verify_done(struct ccw_device *cdev, int err)
607 /* Reset oper notify indication after verify error. */ 609 /* Reset oper notify indication after verify error. */
608 cdev->private->flags.donotify = 0; 610 cdev->private->flags.donotify = 0;
609 PREPARE_WORK(&cdev->private->kick_work, 611 PREPARE_WORK(&cdev->private->kick_work,
610 ccw_device_nopath_notify, cdev); 612 ccw_device_nopath_notify);
611 queue_work(ccw_device_notify_work, &cdev->private->kick_work); 613 queue_work(ccw_device_notify_work, &cdev->private->kick_work);
612 ccw_device_done(cdev, DEV_STATE_NOT_OPER); 614 ccw_device_done(cdev, DEV_STATE_NOT_OPER);
613 break; 615 break;
@@ -738,7 +740,7 @@ ccw_device_offline_notoper(struct ccw_device *cdev, enum dev_event dev_event)
738 sch = to_subchannel(cdev->dev.parent); 740 sch = to_subchannel(cdev->dev.parent);
739 if (get_device(&cdev->dev)) { 741 if (get_device(&cdev->dev)) {
740 PREPARE_WORK(&cdev->private->kick_work, 742 PREPARE_WORK(&cdev->private->kick_work,
741 ccw_device_call_sch_unregister, cdev); 743 ccw_device_call_sch_unregister);
742 queue_work(ccw_device_work, &cdev->private->kick_work); 744 queue_work(ccw_device_work, &cdev->private->kick_work);
743 } 745 }
744 wake_up(&cdev->private->wait_q); 746 wake_up(&cdev->private->wait_q);
@@ -769,7 +771,7 @@ ccw_device_online_notoper(struct ccw_device *cdev, enum dev_event dev_event)
769 } 771 }
770 if (get_device(&cdev->dev)) { 772 if (get_device(&cdev->dev)) {
771 PREPARE_WORK(&cdev->private->kick_work, 773 PREPARE_WORK(&cdev->private->kick_work,
772 ccw_device_call_sch_unregister, cdev); 774 ccw_device_call_sch_unregister);
773 queue_work(ccw_device_work, &cdev->private->kick_work); 775 queue_work(ccw_device_work, &cdev->private->kick_work);
774 } 776 }
775 wake_up(&cdev->private->wait_q); 777 wake_up(&cdev->private->wait_q);
@@ -874,7 +876,7 @@ ccw_device_online_timeout(struct ccw_device *cdev, enum dev_event dev_event)
874 sch = to_subchannel(cdev->dev.parent); 876 sch = to_subchannel(cdev->dev.parent);
875 if (!sch->lpm) { 877 if (!sch->lpm) {
876 PREPARE_WORK(&cdev->private->kick_work, 878 PREPARE_WORK(&cdev->private->kick_work,
877 ccw_device_nopath_notify, cdev); 879 ccw_device_nopath_notify);
878 queue_work(ccw_device_notify_work, 880 queue_work(ccw_device_notify_work,
879 &cdev->private->kick_work); 881 &cdev->private->kick_work);
880 } else 882 } else
@@ -969,7 +971,7 @@ ccw_device_killing_irq(struct ccw_device *cdev, enum dev_event dev_event)
969 ERR_PTR(-EIO)); 971 ERR_PTR(-EIO));
970 if (!sch->lpm) { 972 if (!sch->lpm) {
971 PREPARE_WORK(&cdev->private->kick_work, 973 PREPARE_WORK(&cdev->private->kick_work,
972 ccw_device_nopath_notify, cdev); 974 ccw_device_nopath_notify);
973 queue_work(ccw_device_notify_work, &cdev->private->kick_work); 975 queue_work(ccw_device_notify_work, &cdev->private->kick_work);
974 } else if (cdev->private->flags.doverify) 976 } else if (cdev->private->flags.doverify)
975 /* Start delayed path verification. */ 977 /* Start delayed path verification. */
@@ -992,7 +994,7 @@ ccw_device_killing_timeout(struct ccw_device *cdev, enum dev_event dev_event)
992 sch = to_subchannel(cdev->dev.parent); 994 sch = to_subchannel(cdev->dev.parent);
993 if (!sch->lpm) { 995 if (!sch->lpm) {
994 PREPARE_WORK(&cdev->private->kick_work, 996 PREPARE_WORK(&cdev->private->kick_work,
995 ccw_device_nopath_notify, cdev); 997 ccw_device_nopath_notify);
996 queue_work(ccw_device_notify_work, 998 queue_work(ccw_device_notify_work,
997 &cdev->private->kick_work); 999 &cdev->private->kick_work);
998 } else 1000 } else
@@ -1021,7 +1023,7 @@ void device_kill_io(struct subchannel *sch)
1021 if (ret == -ENODEV) { 1023 if (ret == -ENODEV) {
1022 if (!sch->lpm) { 1024 if (!sch->lpm) {
1023 PREPARE_WORK(&cdev->private->kick_work, 1025 PREPARE_WORK(&cdev->private->kick_work,
1024 ccw_device_nopath_notify, cdev); 1026 ccw_device_nopath_notify);
1025 queue_work(ccw_device_notify_work, 1027 queue_work(ccw_device_notify_work,
1026 &cdev->private->kick_work); 1028 &cdev->private->kick_work);
1027 } else 1029 } else
@@ -1033,7 +1035,7 @@ void device_kill_io(struct subchannel *sch)
1033 ERR_PTR(-EIO)); 1035 ERR_PTR(-EIO));
1034 if (!sch->lpm) { 1036 if (!sch->lpm) {
1035 PREPARE_WORK(&cdev->private->kick_work, 1037 PREPARE_WORK(&cdev->private->kick_work,
1036 ccw_device_nopath_notify, cdev); 1038 ccw_device_nopath_notify);
1037 queue_work(ccw_device_notify_work, &cdev->private->kick_work); 1039 queue_work(ccw_device_notify_work, &cdev->private->kick_work);
1038 } else 1040 } else
1039 /* Start delayed path verification. */ 1041 /* Start delayed path verification. */
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index 8d5fa1b4d11f..d066dbf2c65d 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -2045,11 +2045,13 @@ omit_handler_call:
2045} 2045}
2046 2046
2047static void 2047static void
2048qdio_call_shutdown(void *data) 2048qdio_call_shutdown(struct work_struct *work)
2049{ 2049{
2050 struct ccw_device_private *priv;
2050 struct ccw_device *cdev; 2051 struct ccw_device *cdev;
2051 2052
2052 cdev = (struct ccw_device *)data; 2053 priv = container_of(work, struct ccw_device_private, kick_work);
2054 cdev = priv->cdev;
2053 qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR); 2055 qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR);
2054 put_device(&cdev->dev); 2056 put_device(&cdev->dev);
2055} 2057}
@@ -2091,7 +2093,7 @@ qdio_timeout_handler(struct ccw_device *cdev)
2091 if (get_device(&cdev->dev)) { 2093 if (get_device(&cdev->dev)) {
2092 /* Can't call shutdown from interrupt context. */ 2094 /* Can't call shutdown from interrupt context. */
2093 PREPARE_WORK(&cdev->private->kick_work, 2095 PREPARE_WORK(&cdev->private->kick_work,
2094 qdio_call_shutdown, (void *)cdev); 2096 qdio_call_shutdown);
2095 queue_work(ccw_device_work, &cdev->private->kick_work); 2097 queue_work(ccw_device_work, &cdev->private->kick_work);
2096 } 2098 }
2097 break; 2099 break;