diff options
author | Peter Oberparleiter <peter.oberparleiter@de.ibm.com> | 2009-12-07 06:51:21 -0500 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2009-12-07 06:51:30 -0500 |
commit | 736b5db895eb900c108fe9e9b1659c171481169e (patch) | |
tree | c226120ffdd623cb6cb6831b2bd39b3b8ee053f7 /drivers/s390/cio | |
parent | a7ae2c02f5ab7080646a4cc6c01065ae9decad54 (diff) |
[S390] cio: handle error during device recognition consistently
Remove the return code from ccw_device_recognition and handle
recognition errors through the existing callback
ccw_device_recog_done to reduce cleanup code duplication.
Signed-off-by: Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio')
-rw-r--r-- | drivers/s390/cio/device.c | 57 | ||||
-rw-r--r-- | drivers/s390/cio/device.h | 2 | ||||
-rw-r--r-- | drivers/s390/cio/device_fsm.c | 20 |
3 files changed, 15 insertions, 64 deletions
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index ee3450667687..7ad6bfb2e55e 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
@@ -486,18 +486,9 @@ static int online_store_handle_offline(struct ccw_device *cdev) | |||
486 | 486 | ||
487 | static int online_store_recog_and_online(struct ccw_device *cdev) | 487 | static int online_store_recog_and_online(struct ccw_device *cdev) |
488 | { | 488 | { |
489 | int ret; | ||
490 | |||
491 | /* Do device recognition, if needed. */ | 489 | /* Do device recognition, if needed. */ |
492 | if (cdev->private->state == DEV_STATE_BOXED) { | 490 | if (cdev->private->state == DEV_STATE_BOXED) { |
493 | ret = ccw_device_recognition(cdev); | 491 | ccw_device_recognition(cdev); |
494 | if (ret) { | ||
495 | CIO_MSG_EVENT(0, "Couldn't start recognition " | ||
496 | "for device 0.%x.%04x (ret=%d)\n", | ||
497 | cdev->private->dev_id.ssid, | ||
498 | cdev->private->dev_id.devno, ret); | ||
499 | return ret; | ||
500 | } | ||
501 | wait_event(cdev->private->wait_q, | 492 | wait_event(cdev->private->wait_q, |
502 | cdev->private->flags.recog_done); | 493 | cdev->private->flags.recog_done); |
503 | if (cdev->private->state != DEV_STATE_OFFLINE) | 494 | if (cdev->private->state != DEV_STATE_OFFLINE) |
@@ -746,7 +737,7 @@ static struct ccw_device * io_subchannel_create_ccwdev(struct subchannel *sch) | |||
746 | return cdev; | 737 | return cdev; |
747 | } | 738 | } |
748 | 739 | ||
749 | static int io_subchannel_recog(struct ccw_device *, struct subchannel *); | 740 | static void io_subchannel_recog(struct ccw_device *, struct subchannel *); |
750 | 741 | ||
751 | static void sch_create_and_recog_new_device(struct subchannel *sch) | 742 | static void sch_create_and_recog_new_device(struct subchannel *sch) |
752 | { | 743 | { |
@@ -760,16 +751,7 @@ static void sch_create_and_recog_new_device(struct subchannel *sch) | |||
760 | return; | 751 | return; |
761 | } | 752 | } |
762 | /* Start recognition for the new ccw device. */ | 753 | /* Start recognition for the new ccw device. */ |
763 | if (io_subchannel_recog(cdev, sch)) { | 754 | io_subchannel_recog(cdev, sch); |
764 | spin_lock_irq(sch->lock); | ||
765 | sch_set_cdev(sch, NULL); | ||
766 | spin_unlock_irq(sch->lock); | ||
767 | css_sch_device_unregister(sch); | ||
768 | /* Put reference from io_subchannel_create_ccwdev(). */ | ||
769 | put_device(&sch->dev); | ||
770 | /* Give up initial reference. */ | ||
771 | put_device(&cdev->dev); | ||
772 | } | ||
773 | } | 755 | } |
774 | 756 | ||
775 | /* | 757 | /* |
@@ -879,10 +861,8 @@ io_subchannel_recog_done(struct ccw_device *cdev) | |||
879 | } | 861 | } |
880 | } | 862 | } |
881 | 863 | ||
882 | static int | 864 | static void io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch) |
883 | io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch) | ||
884 | { | 865 | { |
885 | int rc; | ||
886 | struct ccw_device_private *priv; | 866 | struct ccw_device_private *priv; |
887 | 867 | ||
888 | cdev->ccwlock = sch->lock; | 868 | cdev->ccwlock = sch->lock; |
@@ -903,13 +883,8 @@ io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch) | |||
903 | /* Start async. device sensing. */ | 883 | /* Start async. device sensing. */ |
904 | spin_lock_irq(sch->lock); | 884 | spin_lock_irq(sch->lock); |
905 | sch_set_cdev(sch, cdev); | 885 | sch_set_cdev(sch, cdev); |
906 | rc = ccw_device_recognition(cdev); | 886 | ccw_device_recognition(cdev); |
907 | spin_unlock_irq(sch->lock); | 887 | spin_unlock_irq(sch->lock); |
908 | if (rc) { | ||
909 | if (atomic_dec_and_test(&ccw_device_init_count)) | ||
910 | wake_up(&ccw_device_init_wq); | ||
911 | } | ||
912 | return rc; | ||
913 | } | 888 | } |
914 | 889 | ||
915 | static int ccw_device_move_to_sch(struct ccw_device *cdev, | 890 | static int ccw_device_move_to_sch(struct ccw_device *cdev, |
@@ -1528,10 +1503,7 @@ static int ccw_device_console_enable(struct ccw_device *cdev, | |||
1528 | sch->driver = &io_subchannel_driver; | 1503 | sch->driver = &io_subchannel_driver; |
1529 | /* Initialize the ccw_device structure. */ | 1504 | /* Initialize the ccw_device structure. */ |
1530 | cdev->dev.parent= &sch->dev; | 1505 | cdev->dev.parent= &sch->dev; |
1531 | rc = io_subchannel_recog(cdev, sch); | 1506 | io_subchannel_recog(cdev, sch); |
1532 | if (rc) | ||
1533 | return rc; | ||
1534 | |||
1535 | /* Now wait for the async. recognition to come to an end. */ | 1507 | /* Now wait for the async. recognition to come to an end. */ |
1536 | spin_lock_irq(cdev->ccwlock); | 1508 | spin_lock_irq(cdev->ccwlock); |
1537 | while (!dev_fsm_final_state(cdev)) | 1509 | while (!dev_fsm_final_state(cdev)) |
@@ -1547,7 +1519,7 @@ static int ccw_device_console_enable(struct ccw_device *cdev, | |||
1547 | rc = 0; | 1519 | rc = 0; |
1548 | out_unlock: | 1520 | out_unlock: |
1549 | spin_unlock_irq(cdev->ccwlock); | 1521 | spin_unlock_irq(cdev->ccwlock); |
1550 | return 0; | 1522 | return rc; |
1551 | } | 1523 | } |
1552 | 1524 | ||
1553 | struct ccw_device * | 1525 | struct ccw_device * |
@@ -1789,7 +1761,6 @@ static int ccw_device_pm_thaw(struct device *dev) | |||
1789 | static void __ccw_device_pm_restore(struct ccw_device *cdev) | 1761 | static void __ccw_device_pm_restore(struct ccw_device *cdev) |
1790 | { | 1762 | { |
1791 | struct subchannel *sch = to_subchannel(cdev->dev.parent); | 1763 | struct subchannel *sch = to_subchannel(cdev->dev.parent); |
1792 | int ret; | ||
1793 | 1764 | ||
1794 | if (cio_is_console(sch->schid)) | 1765 | if (cio_is_console(sch->schid)) |
1795 | goto out; | 1766 | goto out; |
@@ -1799,22 +1770,10 @@ static void __ccw_device_pm_restore(struct ccw_device *cdev) | |||
1799 | */ | 1770 | */ |
1800 | spin_lock_irq(sch->lock); | 1771 | spin_lock_irq(sch->lock); |
1801 | cdev->private->flags.resuming = 1; | 1772 | cdev->private->flags.resuming = 1; |
1802 | ret = ccw_device_recognition(cdev); | 1773 | ccw_device_recognition(cdev); |
1803 | spin_unlock_irq(sch->lock); | 1774 | spin_unlock_irq(sch->lock); |
1804 | if (ret) { | ||
1805 | CIO_MSG_EVENT(0, "Couldn't start recognition for device " | ||
1806 | "0.%x.%04x (ret=%d)\n", | ||
1807 | cdev->private->dev_id.ssid, | ||
1808 | cdev->private->dev_id.devno, ret); | ||
1809 | spin_lock_irq(sch->lock); | ||
1810 | cdev->private->state = DEV_STATE_DISCONNECTED; | ||
1811 | spin_unlock_irq(sch->lock); | ||
1812 | /* notify driver after the resume cb */ | ||
1813 | goto out; | ||
1814 | } | ||
1815 | wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev) || | 1775 | wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev) || |
1816 | cdev->private->state == DEV_STATE_DISCONNECTED); | 1776 | cdev->private->state == DEV_STATE_DISCONNECTED); |
1817 | |||
1818 | out: | 1777 | out: |
1819 | cdev->private->flags.resuming = 0; | 1778 | cdev->private->flags.resuming = 0; |
1820 | } | 1779 | } |
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h index adaa27efc59e..78662e05d317 100644 --- a/drivers/s390/cio/device.h +++ b/drivers/s390/cio/device.h | |||
@@ -83,7 +83,7 @@ int ccw_device_cancel_halt_clear(struct ccw_device *); | |||
83 | 83 | ||
84 | int ccw_device_is_orphan(struct ccw_device *); | 84 | int ccw_device_is_orphan(struct ccw_device *); |
85 | 85 | ||
86 | int ccw_device_recognition(struct ccw_device *); | 86 | void ccw_device_recognition(struct ccw_device *); |
87 | int ccw_device_online(struct ccw_device *); | 87 | int ccw_device_online(struct ccw_device *); |
88 | int ccw_device_offline(struct ccw_device *); | 88 | int ccw_device_offline(struct ccw_device *); |
89 | void ccw_device_update_sense_data(struct ccw_device *); | 89 | void ccw_device_update_sense_data(struct ccw_device *); |
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index b163743bf586..83adb919648f 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c | |||
@@ -498,20 +498,9 @@ ccw_device_sense_pgid_done(struct ccw_device *cdev, int err) | |||
498 | /* | 498 | /* |
499 | * Start device recognition. | 499 | * Start device recognition. |
500 | */ | 500 | */ |
501 | int | 501 | void ccw_device_recognition(struct ccw_device *cdev) |
502 | ccw_device_recognition(struct ccw_device *cdev) | ||
503 | { | 502 | { |
504 | struct subchannel *sch; | 503 | struct subchannel *sch = to_subchannel(cdev->dev.parent); |
505 | int ret; | ||
506 | |||
507 | sch = to_subchannel(cdev->dev.parent); | ||
508 | ret = cio_enable_subchannel(sch, (u32)(addr_t)sch); | ||
509 | if (ret != 0) | ||
510 | /* Couldn't enable the subchannel for i/o. Sick device. */ | ||
511 | return ret; | ||
512 | |||
513 | /* After 60s the device recognition is considered to have failed. */ | ||
514 | ccw_device_set_timeout(cdev, 60*HZ); | ||
515 | 504 | ||
516 | /* | 505 | /* |
517 | * We used to start here with a sense pgid to find out whether a device | 506 | * We used to start here with a sense pgid to find out whether a device |
@@ -523,8 +512,11 @@ ccw_device_recognition(struct ccw_device *cdev) | |||
523 | */ | 512 | */ |
524 | cdev->private->flags.recog_done = 0; | 513 | cdev->private->flags.recog_done = 0; |
525 | cdev->private->state = DEV_STATE_SENSE_ID; | 514 | cdev->private->state = DEV_STATE_SENSE_ID; |
515 | if (cio_enable_subchannel(sch, (u32) (addr_t) sch)) { | ||
516 | ccw_device_recog_done(cdev, DEV_STATE_NOT_OPER); | ||
517 | return; | ||
518 | } | ||
526 | ccw_device_sense_id_start(cdev); | 519 | ccw_device_sense_id_start(cdev); |
527 | return 0; | ||
528 | } | 520 | } |
529 | 521 | ||
530 | /* | 522 | /* |