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 /drivers | |
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
Diffstat (limited to 'drivers')
-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 |
4 files changed, 57 insertions, 24 deletions
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 | } |