diff options
| -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 | } | 
