diff options
author | Stefan Weinhuber <wein@de.ibm.com> | 2006-03-24 06:15:25 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-24 10:33:17 -0500 |
commit | 20c644680af1ef9a6b36c0873f59498c98b07ab1 (patch) | |
tree | af2e50faeb690b7aacf7be3480f08f0a6ec0b56f /drivers/s390/block/dasd.c | |
parent | 554a826e0a29f1a88e5a5332f0718c059885ec17 (diff) |
[PATCH] s390: dasd extended error reporting
The DASD extended error reporting is a facility that allows to get detailed
information about certain problems in the DASD I/O. This information can be
used to implement fail-over applications that can recover these problems.
Signed-off-by: Stefan Weinhuber <wein@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/s390/block/dasd.c')
-rw-r--r-- | drivers/s390/block/dasd.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 9e0b371ebe69..f32f7447588b 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -151,6 +151,8 @@ dasd_state_new_to_known(struct dasd_device *device) | |||
151 | static inline void | 151 | static inline void |
152 | dasd_state_known_to_new(struct dasd_device * device) | 152 | dasd_state_known_to_new(struct dasd_device * device) |
153 | { | 153 | { |
154 | /* Disable extended error reporting for this device. */ | ||
155 | dasd_eer_disable(device); | ||
154 | /* Forget the discipline information. */ | 156 | /* Forget the discipline information. */ |
155 | if (device->discipline) | 157 | if (device->discipline) |
156 | module_put(device->discipline->owner); | 158 | module_put(device->discipline->owner); |
@@ -892,6 +894,9 @@ dasd_handle_state_change_pending(struct dasd_device *device) | |||
892 | struct dasd_ccw_req *cqr; | 894 | struct dasd_ccw_req *cqr; |
893 | struct list_head *l, *n; | 895 | struct list_head *l, *n; |
894 | 896 | ||
897 | /* First of all start sense subsystem status request. */ | ||
898 | dasd_eer_snss(device); | ||
899 | |||
895 | device->stopped &= ~DASD_STOPPED_PENDING; | 900 | device->stopped &= ~DASD_STOPPED_PENDING; |
896 | 901 | ||
897 | /* restart all 'running' IO on queue */ | 902 | /* restart all 'running' IO on queue */ |
@@ -1111,6 +1116,19 @@ restart: | |||
1111 | } | 1116 | } |
1112 | goto restart; | 1117 | goto restart; |
1113 | } | 1118 | } |
1119 | |||
1120 | /* First of all call extended error reporting. */ | ||
1121 | if (dasd_eer_enabled(device) && | ||
1122 | cqr->status == DASD_CQR_FAILED) { | ||
1123 | dasd_eer_write(device, cqr, DASD_EER_FATALERROR); | ||
1124 | |||
1125 | /* restart request */ | ||
1126 | cqr->status = DASD_CQR_QUEUED; | ||
1127 | cqr->retries = 255; | ||
1128 | device->stopped |= DASD_STOPPED_QUIESCE; | ||
1129 | goto restart; | ||
1130 | } | ||
1131 | |||
1114 | /* Process finished ERP request. */ | 1132 | /* Process finished ERP request. */ |
1115 | if (cqr->refers) { | 1133 | if (cqr->refers) { |
1116 | __dasd_process_erp(device, cqr); | 1134 | __dasd_process_erp(device, cqr); |
@@ -1248,7 +1266,8 @@ __dasd_start_head(struct dasd_device * device) | |||
1248 | cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list); | 1266 | cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list); |
1249 | /* check FAILFAST */ | 1267 | /* check FAILFAST */ |
1250 | if (device->stopped & ~DASD_STOPPED_PENDING && | 1268 | if (device->stopped & ~DASD_STOPPED_PENDING && |
1251 | test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags)) { | 1269 | test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) && |
1270 | (!dasd_eer_enabled(device))) { | ||
1252 | cqr->status = DASD_CQR_FAILED; | 1271 | cqr->status = DASD_CQR_FAILED; |
1253 | dasd_schedule_bh(device); | 1272 | dasd_schedule_bh(device); |
1254 | } | 1273 | } |
@@ -1807,6 +1826,7 @@ dasd_exit(void) | |||
1807 | #ifdef CONFIG_PROC_FS | 1826 | #ifdef CONFIG_PROC_FS |
1808 | dasd_proc_exit(); | 1827 | dasd_proc_exit(); |
1809 | #endif | 1828 | #endif |
1829 | dasd_eer_exit(); | ||
1810 | if (dasd_page_cache != NULL) { | 1830 | if (dasd_page_cache != NULL) { |
1811 | kmem_cache_destroy(dasd_page_cache); | 1831 | kmem_cache_destroy(dasd_page_cache); |
1812 | dasd_page_cache = NULL; | 1832 | dasd_page_cache = NULL; |
@@ -2003,6 +2023,9 @@ dasd_generic_notify(struct ccw_device *cdev, int event) | |||
2003 | switch (event) { | 2023 | switch (event) { |
2004 | case CIO_GONE: | 2024 | case CIO_GONE: |
2005 | case CIO_NO_PATH: | 2025 | case CIO_NO_PATH: |
2026 | /* First of all call extended error reporting. */ | ||
2027 | dasd_eer_write(device, NULL, DASD_EER_NOPATH); | ||
2028 | |||
2006 | if (device->state < DASD_STATE_BASIC) | 2029 | if (device->state < DASD_STATE_BASIC) |
2007 | break; | 2030 | break; |
2008 | /* Device is active. We want to keep it. */ | 2031 | /* Device is active. We want to keep it. */ |
@@ -2060,6 +2083,7 @@ dasd_generic_auto_online (struct ccw_driver *dasd_discipline_driver) | |||
2060 | put_driver(drv); | 2083 | put_driver(drv); |
2061 | } | 2084 | } |
2062 | 2085 | ||
2086 | |||
2063 | static int __init | 2087 | static int __init |
2064 | dasd_init(void) | 2088 | dasd_init(void) |
2065 | { | 2089 | { |
@@ -2092,6 +2116,9 @@ dasd_init(void) | |||
2092 | rc = dasd_parse(); | 2116 | rc = dasd_parse(); |
2093 | if (rc) | 2117 | if (rc) |
2094 | goto failed; | 2118 | goto failed; |
2119 | rc = dasd_eer_init(); | ||
2120 | if (rc) | ||
2121 | goto failed; | ||
2095 | #ifdef CONFIG_PROC_FS | 2122 | #ifdef CONFIG_PROC_FS |
2096 | rc = dasd_proc_init(); | 2123 | rc = dasd_proc_init(); |
2097 | if (rc) | 2124 | if (rc) |