diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-31 12:16:37 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-31 12:16:37 -0400 |
commit | 51d7cfc670e4c09e296af101326a6270060e72e7 (patch) | |
tree | d18858aacd9634b71f543f6a187f313950a13432 | |
parent | 5983b125740553d08a67d0c57e8c1021f5a06e31 (diff) | |
parent | 3ecb0a5a7b567c9719d61938bcdba22938084b65 (diff) |
Merge branch 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6:
[S390] cio: deregister ccw device when pgid disband failed
[S390] cio: Use device_schedule_callback() for removing disconnected devices.
[S390] Fix section annotations.
[S390] raw3270: use mutex instead of semaphore
[S390] arch/s390/kernel/debug.c: use mutex instead of semaphore
[S390] dasd_eer: use mutex instead of semaphore
[S390] Add exception handler for diagnose 224
-rw-r--r-- | arch/s390/hypfs/hypfs_diag.c | 17 | ||||
-rw-r--r-- | arch/s390/kernel/debug.c | 22 | ||||
-rw-r--r-- | arch/s390/kernel/setup.c | 4 | ||||
-rw-r--r-- | arch/s390/kernel/smp.c | 6 | ||||
-rw-r--r-- | drivers/s390/block/dasd_eer.c | 16 | ||||
-rw-r--r-- | drivers/s390/char/raw3270.c | 10 | ||||
-rw-r--r-- | drivers/s390/cio/device.c | 49 | ||||
-rw-r--r-- | drivers/s390/cio/device_fsm.c | 6 |
8 files changed, 87 insertions, 43 deletions
diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c index 2782cf9da5b4..b9a1ce1f28e4 100644 --- a/arch/s390/hypfs/hypfs_diag.c +++ b/arch/s390/hypfs/hypfs_diag.c | |||
@@ -481,9 +481,17 @@ out: | |||
481 | 481 | ||
482 | /* Diagnose 224 functions */ | 482 | /* Diagnose 224 functions */ |
483 | 483 | ||
484 | static void diag224(void *ptr) | 484 | static int diag224(void *ptr) |
485 | { | 485 | { |
486 | asm volatile("diag %0,%1,0x224" : :"d" (0), "d"(ptr) : "memory"); | 486 | int rc = -ENOTSUPP; |
487 | |||
488 | asm volatile( | ||
489 | " diag %1,%2,0x224\n" | ||
490 | "0: lhi %0,0x0\n" | ||
491 | "1:\n" | ||
492 | EX_TABLE(0b,1b) | ||
493 | : "+d" (rc) :"d" (0), "d" (ptr) : "memory"); | ||
494 | return rc; | ||
487 | } | 495 | } |
488 | 496 | ||
489 | static int diag224_get_name_table(void) | 497 | static int diag224_get_name_table(void) |
@@ -492,7 +500,10 @@ static int diag224_get_name_table(void) | |||
492 | diag224_cpu_names = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA); | 500 | diag224_cpu_names = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA); |
493 | if (!diag224_cpu_names) | 501 | if (!diag224_cpu_names) |
494 | return -ENOMEM; | 502 | return -ENOMEM; |
495 | diag224(diag224_cpu_names); | 503 | if (diag224(diag224_cpu_names)) { |
504 | kfree(diag224_cpu_names); | ||
505 | return -ENOTSUPP; | ||
506 | } | ||
496 | EBCASC(diag224_cpu_names + 16, (*diag224_cpu_names + 1) * 16); | 507 | EBCASC(diag224_cpu_names + 16, (*diag224_cpu_names + 1) * 16); |
497 | return 0; | 508 | return 0; |
498 | } | 509 | } |
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index dca6eaf82c80..1b2f5ce45320 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c | |||
@@ -163,7 +163,7 @@ unsigned int debug_feature_version = __DEBUG_FEATURE_VERSION; | |||
163 | 163 | ||
164 | static debug_info_t *debug_area_first = NULL; | 164 | static debug_info_t *debug_area_first = NULL; |
165 | static debug_info_t *debug_area_last = NULL; | 165 | static debug_info_t *debug_area_last = NULL; |
166 | static DECLARE_MUTEX(debug_lock); | 166 | static DEFINE_MUTEX(debug_mutex); |
167 | 167 | ||
168 | static int initialized; | 168 | static int initialized; |
169 | 169 | ||
@@ -576,7 +576,7 @@ debug_input(struct file *file, const char __user *user_buf, size_t length, | |||
576 | int rc = 0; | 576 | int rc = 0; |
577 | file_private_info_t *p_info; | 577 | file_private_info_t *p_info; |
578 | 578 | ||
579 | down(&debug_lock); | 579 | mutex_lock(&debug_mutex); |
580 | p_info = ((file_private_info_t *) file->private_data); | 580 | p_info = ((file_private_info_t *) file->private_data); |
581 | if (p_info->view->input_proc) | 581 | if (p_info->view->input_proc) |
582 | rc = p_info->view->input_proc(p_info->debug_info_org, | 582 | rc = p_info->view->input_proc(p_info->debug_info_org, |
@@ -584,7 +584,7 @@ debug_input(struct file *file, const char __user *user_buf, size_t length, | |||
584 | length, offset); | 584 | length, offset); |
585 | else | 585 | else |
586 | rc = -EPERM; | 586 | rc = -EPERM; |
587 | up(&debug_lock); | 587 | mutex_unlock(&debug_mutex); |
588 | return rc; /* number of input characters */ | 588 | return rc; /* number of input characters */ |
589 | } | 589 | } |
590 | 590 | ||
@@ -602,7 +602,7 @@ debug_open(struct inode *inode, struct file *file) | |||
602 | file_private_info_t *p_info; | 602 | file_private_info_t *p_info; |
603 | debug_info_t *debug_info, *debug_info_snapshot; | 603 | debug_info_t *debug_info, *debug_info_snapshot; |
604 | 604 | ||
605 | down(&debug_lock); | 605 | mutex_lock(&debug_mutex); |
606 | debug_info = file->f_path.dentry->d_inode->i_private; | 606 | debug_info = file->f_path.dentry->d_inode->i_private; |
607 | /* find debug view */ | 607 | /* find debug view */ |
608 | for (i = 0; i < DEBUG_MAX_VIEWS; i++) { | 608 | for (i = 0; i < DEBUG_MAX_VIEWS; i++) { |
@@ -653,7 +653,7 @@ found: | |||
653 | file->private_data = p_info; | 653 | file->private_data = p_info; |
654 | debug_info_get(debug_info); | 654 | debug_info_get(debug_info); |
655 | out: | 655 | out: |
656 | up(&debug_lock); | 656 | mutex_unlock(&debug_mutex); |
657 | return rc; | 657 | return rc; |
658 | } | 658 | } |
659 | 659 | ||
@@ -688,7 +688,7 @@ debug_register (char *name, int pages_per_area, int nr_areas, int buf_size) | |||
688 | 688 | ||
689 | if (!initialized) | 689 | if (!initialized) |
690 | BUG(); | 690 | BUG(); |
691 | down(&debug_lock); | 691 | mutex_lock(&debug_mutex); |
692 | 692 | ||
693 | /* create new debug_info */ | 693 | /* create new debug_info */ |
694 | 694 | ||
@@ -702,7 +702,7 @@ out: | |||
702 | if (!rc){ | 702 | if (!rc){ |
703 | printk(KERN_ERR "debug: debug_register failed for %s\n",name); | 703 | printk(KERN_ERR "debug: debug_register failed for %s\n",name); |
704 | } | 704 | } |
705 | up(&debug_lock); | 705 | mutex_unlock(&debug_mutex); |
706 | return rc; | 706 | return rc; |
707 | } | 707 | } |
708 | 708 | ||
@@ -716,9 +716,9 @@ debug_unregister(debug_info_t * id) | |||
716 | { | 716 | { |
717 | if (!id) | 717 | if (!id) |
718 | goto out; | 718 | goto out; |
719 | down(&debug_lock); | 719 | mutex_lock(&debug_mutex); |
720 | debug_info_put(id); | 720 | debug_info_put(id); |
721 | up(&debug_lock); | 721 | mutex_unlock(&debug_mutex); |
722 | 722 | ||
723 | out: | 723 | out: |
724 | return; | 724 | return; |
@@ -1054,11 +1054,11 @@ __init debug_init(void) | |||
1054 | int rc = 0; | 1054 | int rc = 0; |
1055 | 1055 | ||
1056 | s390dbf_sysctl_header = register_sysctl_table(s390dbf_dir_table); | 1056 | s390dbf_sysctl_header = register_sysctl_table(s390dbf_dir_table); |
1057 | down(&debug_lock); | 1057 | mutex_lock(&debug_mutex); |
1058 | debug_debugfs_root_entry = debugfs_create_dir(DEBUG_DIR_ROOT,NULL); | 1058 | debug_debugfs_root_entry = debugfs_create_dir(DEBUG_DIR_ROOT,NULL); |
1059 | printk(KERN_INFO "debug: Initialization complete\n"); | 1059 | printk(KERN_INFO "debug: Initialization complete\n"); |
1060 | initialized = 1; | 1060 | initialized = 1; |
1061 | up(&debug_lock); | 1061 | mutex_unlock(&debug_mutex); |
1062 | 1062 | ||
1063 | return rc; | 1063 | return rc; |
1064 | } | 1064 | } |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 6bfb0889eb10..51d6309e7f3b 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -102,7 +102,7 @@ static struct resource data_resource = { | |||
102 | /* | 102 | /* |
103 | * cpu_init() initializes state that is per-CPU. | 103 | * cpu_init() initializes state that is per-CPU. |
104 | */ | 104 | */ |
105 | void __devinit cpu_init (void) | 105 | void __cpuinit cpu_init(void) |
106 | { | 106 | { |
107 | int addr = hard_smp_processor_id(); | 107 | int addr = hard_smp_processor_id(); |
108 | 108 | ||
@@ -915,7 +915,7 @@ setup_arch(char **cmdline_p) | |||
915 | setup_zfcpdump(console_devno); | 915 | setup_zfcpdump(console_devno); |
916 | } | 916 | } |
917 | 917 | ||
918 | void print_cpu_info(struct cpuinfo_S390 *cpuinfo) | 918 | void __cpuinit print_cpu_info(struct cpuinfo_S390 *cpuinfo) |
919 | { | 919 | { |
920 | printk("cpu %d " | 920 | printk("cpu %d " |
921 | #ifdef CONFIG_SMP | 921 | #ifdef CONFIG_SMP |
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 09f028a3266b..8ff2feaf9b00 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -492,7 +492,7 @@ static unsigned int __init smp_count_cpus(void) | |||
492 | /* | 492 | /* |
493 | * Activate a secondary processor. | 493 | * Activate a secondary processor. |
494 | */ | 494 | */ |
495 | int __devinit start_secondary(void *cpuvoid) | 495 | int __cpuinit start_secondary(void *cpuvoid) |
496 | { | 496 | { |
497 | /* Setup the cpu */ | 497 | /* Setup the cpu */ |
498 | cpu_init(); | 498 | cpu_init(); |
@@ -741,7 +741,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
741 | smp_create_idle(cpu); | 741 | smp_create_idle(cpu); |
742 | } | 742 | } |
743 | 743 | ||
744 | void __devinit smp_prepare_boot_cpu(void) | 744 | void __init smp_prepare_boot_cpu(void) |
745 | { | 745 | { |
746 | BUG_ON(smp_processor_id() != 0); | 746 | BUG_ON(smp_processor_id() != 0); |
747 | 747 | ||
@@ -750,7 +750,7 @@ void __devinit smp_prepare_boot_cpu(void) | |||
750 | current_set[0] = current; | 750 | current_set[0] = current; |
751 | } | 751 | } |
752 | 752 | ||
753 | void smp_cpus_done(unsigned int max_cpus) | 753 | void __init smp_cpus_done(unsigned int max_cpus) |
754 | { | 754 | { |
755 | cpu_present_map = cpu_possible_map; | 755 | cpu_present_map = cpu_possible_map; |
756 | } | 756 | } |
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c index a1dc8c466ec9..0c081a664ee8 100644 --- a/drivers/s390/block/dasd_eer.c +++ b/drivers/s390/block/dasd_eer.c | |||
@@ -14,9 +14,9 @@ | |||
14 | #include <linux/moduleparam.h> | 14 | #include <linux/moduleparam.h> |
15 | #include <linux/device.h> | 15 | #include <linux/device.h> |
16 | #include <linux/poll.h> | 16 | #include <linux/poll.h> |
17 | #include <linux/mutex.h> | ||
17 | 18 | ||
18 | #include <asm/uaccess.h> | 19 | #include <asm/uaccess.h> |
19 | #include <asm/semaphore.h> | ||
20 | #include <asm/atomic.h> | 20 | #include <asm/atomic.h> |
21 | #include <asm/ebcdic.h> | 21 | #include <asm/ebcdic.h> |
22 | 22 | ||
@@ -514,7 +514,7 @@ void dasd_eer_disable(struct dasd_device *device) | |||
514 | * to transfer in a readbuffer, which is protected by the readbuffer_mutex. | 514 | * to transfer in a readbuffer, which is protected by the readbuffer_mutex. |
515 | */ | 515 | */ |
516 | static char readbuffer[PAGE_SIZE]; | 516 | static char readbuffer[PAGE_SIZE]; |
517 | static DECLARE_MUTEX(readbuffer_mutex); | 517 | static DEFINE_MUTEX(readbuffer_mutex); |
518 | 518 | ||
519 | static int dasd_eer_open(struct inode *inp, struct file *filp) | 519 | static int dasd_eer_open(struct inode *inp, struct file *filp) |
520 | { | 520 | { |
@@ -579,7 +579,7 @@ static ssize_t dasd_eer_read(struct file *filp, char __user *buf, | |||
579 | struct eerbuffer *eerb; | 579 | struct eerbuffer *eerb; |
580 | 580 | ||
581 | eerb = (struct eerbuffer *) filp->private_data; | 581 | eerb = (struct eerbuffer *) filp->private_data; |
582 | if (down_interruptible(&readbuffer_mutex)) | 582 | if (mutex_lock_interruptible(&readbuffer_mutex)) |
583 | return -ERESTARTSYS; | 583 | return -ERESTARTSYS; |
584 | 584 | ||
585 | spin_lock_irqsave(&bufferlock, flags); | 585 | spin_lock_irqsave(&bufferlock, flags); |
@@ -588,7 +588,7 @@ static ssize_t dasd_eer_read(struct file *filp, char __user *buf, | |||
588 | /* has been deleted */ | 588 | /* has been deleted */ |
589 | eerb->residual = 0; | 589 | eerb->residual = 0; |
590 | spin_unlock_irqrestore(&bufferlock, flags); | 590 | spin_unlock_irqrestore(&bufferlock, flags); |
591 | up(&readbuffer_mutex); | 591 | mutex_unlock(&readbuffer_mutex); |
592 | return -EIO; | 592 | return -EIO; |
593 | } else if (eerb->residual > 0) { | 593 | } else if (eerb->residual > 0) { |
594 | /* OK we still have a second half of a record to deliver */ | 594 | /* OK we still have a second half of a record to deliver */ |
@@ -602,7 +602,7 @@ static ssize_t dasd_eer_read(struct file *filp, char __user *buf, | |||
602 | if (!tc) { | 602 | if (!tc) { |
603 | /* no data available */ | 603 | /* no data available */ |
604 | spin_unlock_irqrestore(&bufferlock, flags); | 604 | spin_unlock_irqrestore(&bufferlock, flags); |
605 | up(&readbuffer_mutex); | 605 | mutex_unlock(&readbuffer_mutex); |
606 | if (filp->f_flags & O_NONBLOCK) | 606 | if (filp->f_flags & O_NONBLOCK) |
607 | return -EAGAIN; | 607 | return -EAGAIN; |
608 | rc = wait_event_interruptible( | 608 | rc = wait_event_interruptible( |
@@ -610,7 +610,7 @@ static ssize_t dasd_eer_read(struct file *filp, char __user *buf, | |||
610 | eerb->head != eerb->tail); | 610 | eerb->head != eerb->tail); |
611 | if (rc) | 611 | if (rc) |
612 | return rc; | 612 | return rc; |
613 | if (down_interruptible(&readbuffer_mutex)) | 613 | if (mutex_lock_interruptible(&readbuffer_mutex)) |
614 | return -ERESTARTSYS; | 614 | return -ERESTARTSYS; |
615 | spin_lock_irqsave(&bufferlock, flags); | 615 | spin_lock_irqsave(&bufferlock, flags); |
616 | } | 616 | } |
@@ -626,11 +626,11 @@ static ssize_t dasd_eer_read(struct file *filp, char __user *buf, | |||
626 | spin_unlock_irqrestore(&bufferlock, flags); | 626 | spin_unlock_irqrestore(&bufferlock, flags); |
627 | 627 | ||
628 | if (copy_to_user(buf, readbuffer, effective_count)) { | 628 | if (copy_to_user(buf, readbuffer, effective_count)) { |
629 | up(&readbuffer_mutex); | 629 | mutex_unlock(&readbuffer_mutex); |
630 | return -EFAULT; | 630 | return -EFAULT; |
631 | } | 631 | } |
632 | 632 | ||
633 | up(&readbuffer_mutex); | 633 | mutex_unlock(&readbuffer_mutex); |
634 | return effective_count; | 634 | return effective_count; |
635 | } | 635 | } |
636 | 636 | ||
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index f6ef90ee3e7d..743944ad61ec 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c | |||
@@ -487,7 +487,7 @@ struct raw3270_ua { /* Query Reply structure for Usable Area */ | |||
487 | } __attribute__ ((packed)); | 487 | } __attribute__ ((packed)); |
488 | 488 | ||
489 | static struct diag210 raw3270_init_diag210; | 489 | static struct diag210 raw3270_init_diag210; |
490 | static DECLARE_MUTEX(raw3270_init_sem); | 490 | static DEFINE_MUTEX(raw3270_init_mutex); |
491 | 491 | ||
492 | static int | 492 | static int |
493 | raw3270_init_irq(struct raw3270_view *view, struct raw3270_request *rq, | 493 | raw3270_init_irq(struct raw3270_view *view, struct raw3270_request *rq, |
@@ -713,7 +713,7 @@ raw3270_size_device(struct raw3270 *rp) | |||
713 | { | 713 | { |
714 | int rc; | 714 | int rc; |
715 | 715 | ||
716 | down(&raw3270_init_sem); | 716 | mutex_lock(&raw3270_init_mutex); |
717 | rp->view = &raw3270_init_view; | 717 | rp->view = &raw3270_init_view; |
718 | raw3270_init_view.dev = rp; | 718 | raw3270_init_view.dev = rp; |
719 | if (MACHINE_IS_VM) | 719 | if (MACHINE_IS_VM) |
@@ -722,7 +722,7 @@ raw3270_size_device(struct raw3270 *rp) | |||
722 | rc = __raw3270_size_device(rp); | 722 | rc = __raw3270_size_device(rp); |
723 | raw3270_init_view.dev = NULL; | 723 | raw3270_init_view.dev = NULL; |
724 | rp->view = NULL; | 724 | rp->view = NULL; |
725 | up(&raw3270_init_sem); | 725 | mutex_unlock(&raw3270_init_mutex); |
726 | if (rc == 0) { /* Found something. */ | 726 | if (rc == 0) { /* Found something. */ |
727 | /* Try to find a model. */ | 727 | /* Try to find a model. */ |
728 | rp->model = 0; | 728 | rp->model = 0; |
@@ -749,7 +749,7 @@ raw3270_reset_device(struct raw3270 *rp) | |||
749 | { | 749 | { |
750 | int rc; | 750 | int rc; |
751 | 751 | ||
752 | down(&raw3270_init_sem); | 752 | mutex_lock(&raw3270_init_mutex); |
753 | memset(&rp->init_request, 0, sizeof(rp->init_request)); | 753 | memset(&rp->init_request, 0, sizeof(rp->init_request)); |
754 | memset(&rp->init_data, 0, sizeof(rp->init_data)); | 754 | memset(&rp->init_data, 0, sizeof(rp->init_data)); |
755 | /* Store reset data stream to init_data/init_request */ | 755 | /* Store reset data stream to init_data/init_request */ |
@@ -764,7 +764,7 @@ raw3270_reset_device(struct raw3270 *rp) | |||
764 | rc = raw3270_start_init(rp, &raw3270_init_view, &rp->init_request); | 764 | rc = raw3270_start_init(rp, &raw3270_init_view, &rp->init_request); |
765 | raw3270_init_view.dev = NULL; | 765 | raw3270_init_view.dev = NULL; |
766 | rp->view = NULL; | 766 | rp->view = NULL; |
767 | up(&raw3270_init_sem); | 767 | mutex_unlock(&raw3270_init_mutex); |
768 | return rc; | 768 | return rc; |
769 | } | 769 | } |
770 | 770 | ||
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index a8b373f69cf0..6b264bdb5bfb 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
@@ -296,30 +296,57 @@ static void ccw_device_unregister(struct ccw_device *cdev) | |||
296 | device_del(&cdev->dev); | 296 | device_del(&cdev->dev); |
297 | } | 297 | } |
298 | 298 | ||
299 | static void ccw_device_remove_orphan_cb(struct device *dev) | ||
300 | { | ||
301 | struct ccw_device *cdev = to_ccwdev(dev); | ||
302 | |||
303 | ccw_device_unregister(cdev); | ||
304 | put_device(&cdev->dev); | ||
305 | } | ||
306 | |||
307 | static void ccw_device_remove_sch_cb(struct device *dev) | ||
308 | { | ||
309 | struct subchannel *sch; | ||
310 | |||
311 | sch = to_subchannel(dev); | ||
312 | css_sch_device_unregister(sch); | ||
313 | /* Reset intparm to zeroes. */ | ||
314 | sch->schib.pmcw.intparm = 0; | ||
315 | cio_modify(sch); | ||
316 | put_device(&sch->dev); | ||
317 | } | ||
318 | |||
299 | static void | 319 | static void |
300 | ccw_device_remove_disconnected(struct ccw_device *cdev) | 320 | ccw_device_remove_disconnected(struct ccw_device *cdev) |
301 | { | 321 | { |
302 | struct subchannel *sch; | ||
303 | unsigned long flags; | 322 | unsigned long flags; |
323 | int rc; | ||
324 | |||
304 | /* | 325 | /* |
305 | * Forced offline in disconnected state means | 326 | * Forced offline in disconnected state means |
306 | * 'throw away device'. | 327 | * 'throw away device'. |
307 | */ | 328 | */ |
308 | if (ccw_device_is_orphan(cdev)) { | 329 | if (ccw_device_is_orphan(cdev)) { |
309 | /* Deregister ccw device. */ | 330 | /* |
331 | * Deregister ccw device. | ||
332 | * Unfortunately, we cannot do this directly from the | ||
333 | * attribute method. | ||
334 | */ | ||
310 | spin_lock_irqsave(cdev->ccwlock, flags); | 335 | spin_lock_irqsave(cdev->ccwlock, flags); |
311 | cdev->private->state = DEV_STATE_NOT_OPER; | 336 | cdev->private->state = DEV_STATE_NOT_OPER; |
312 | spin_unlock_irqrestore(cdev->ccwlock, flags); | 337 | spin_unlock_irqrestore(cdev->ccwlock, flags); |
313 | ccw_device_unregister(cdev); | 338 | rc = device_schedule_callback(&cdev->dev, |
314 | put_device(&cdev->dev); | 339 | ccw_device_remove_orphan_cb); |
315 | return ; | 340 | if (rc) |
341 | dev_info(&cdev->dev, "Couldn't unregister orphan\n"); | ||
342 | return; | ||
316 | } | 343 | } |
317 | sch = to_subchannel(cdev->dev.parent); | 344 | /* Deregister subchannel, which will kill the ccw device. */ |
318 | css_sch_device_unregister(sch); | 345 | rc = device_schedule_callback(cdev->dev.parent, |
319 | /* Reset intparm to zeroes. */ | 346 | ccw_device_remove_sch_cb); |
320 | sch->schib.pmcw.intparm = 0; | 347 | if (rc) |
321 | cio_modify(sch); | 348 | dev_info(&cdev->dev, |
322 | put_device(&sch->dev); | 349 | "Couldn't unregister disconnected device\n"); |
323 | } | 350 | } |
324 | 351 | ||
325 | int | 352 | int |
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index 898ec3b2bebb..6bba80929577 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c | |||
@@ -688,6 +688,12 @@ ccw_device_disband_done(struct ccw_device *cdev, int err) | |||
688 | ccw_device_done(cdev, DEV_STATE_BOXED); | 688 | ccw_device_done(cdev, DEV_STATE_BOXED); |
689 | break; | 689 | break; |
690 | default: | 690 | default: |
691 | cdev->private->flags.donotify = 0; | ||
692 | if (get_device(&cdev->dev)) { | ||
693 | PREPARE_WORK(&cdev->private->kick_work, | ||
694 | ccw_device_call_sch_unregister); | ||
695 | queue_work(ccw_device_work, &cdev->private->kick_work); | ||
696 | } | ||
691 | ccw_device_done(cdev, DEV_STATE_NOT_OPER); | 697 | ccw_device_done(cdev, DEV_STATE_NOT_OPER); |
692 | break; | 698 | break; |
693 | } | 699 | } |