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