aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block/dasd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/block/dasd.c')
-rw-r--r--drivers/s390/block/dasd.c97
1 files changed, 21 insertions, 76 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 08c88fcd8963..af1d5b404cee 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -18,7 +18,6 @@
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/buffer_head.h> 19#include <linux/buffer_head.h>
20#include <linux/hdreg.h> 20#include <linux/hdreg.h>
21#include <linux/notifier.h>
22 21
23#include <asm/ccwdev.h> 22#include <asm/ccwdev.h>
24#include <asm/ebcdic.h> 23#include <asm/ebcdic.h>
@@ -58,7 +57,6 @@ static void dasd_int_handler(struct ccw_device *, unsigned long, struct irb *);
58static void dasd_flush_ccw_queue(struct dasd_device *, int); 57static void dasd_flush_ccw_queue(struct dasd_device *, int);
59static void dasd_tasklet(struct dasd_device *); 58static void dasd_tasklet(struct dasd_device *);
60static void do_kick_device(void *data); 59static void do_kick_device(void *data);
61static void dasd_disable_eer(struct dasd_device *device);
62 60
63/* 61/*
64 * SECTION: Operations on the device structure. 62 * SECTION: Operations on the device structure.
@@ -153,10 +151,13 @@ dasd_state_new_to_known(struct dasd_device *device)
153static inline void 151static inline void
154dasd_state_known_to_new(struct dasd_device * device) 152dasd_state_known_to_new(struct dasd_device * device)
155{ 153{
156 /* disable extended error reporting for this device */
157 dasd_disable_eer(device);
158 /* Forget the discipline information. */ 154 /* Forget the discipline information. */
155 if (device->discipline)
156 module_put(device->discipline->owner);
159 device->discipline = NULL; 157 device->discipline = NULL;
158 if (device->base_discipline)
159 module_put(device->base_discipline->owner);
160 device->base_discipline = NULL;
160 device->state = DASD_STATE_NEW; 161 device->state = DASD_STATE_NEW;
161 162
162 dasd_free_queue(device); 163 dasd_free_queue(device);
@@ -871,9 +872,6 @@ dasd_handle_state_change_pending(struct dasd_device *device)
871 struct dasd_ccw_req *cqr; 872 struct dasd_ccw_req *cqr;
872 struct list_head *l, *n; 873 struct list_head *l, *n;
873 874
874 /* first of all call extended error reporting */
875 dasd_write_eer_trigger(DASD_EER_STATECHANGE, device, NULL);
876
877 device->stopped &= ~DASD_STOPPED_PENDING; 875 device->stopped &= ~DASD_STOPPED_PENDING;
878 876
879 /* restart all 'running' IO on queue */ 877 /* restart all 'running' IO on queue */
@@ -1093,19 +1091,6 @@ restart:
1093 } 1091 }
1094 goto restart; 1092 goto restart;
1095 } 1093 }
1096
1097 /* first of all call extended error reporting */
1098 if (device->eer && cqr->status == DASD_CQR_FAILED) {
1099 dasd_write_eer_trigger(DASD_EER_FATALERROR,
1100 device, cqr);
1101
1102 /* restart request */
1103 cqr->status = DASD_CQR_QUEUED;
1104 cqr->retries = 255;
1105 device->stopped |= DASD_STOPPED_QUIESCE;
1106 goto restart;
1107 }
1108
1109 /* Process finished ERP request. */ 1094 /* Process finished ERP request. */
1110 if (cqr->refers) { 1095 if (cqr->refers) {
1111 __dasd_process_erp(device, cqr); 1096 __dasd_process_erp(device, cqr);
@@ -1243,8 +1228,7 @@ __dasd_start_head(struct dasd_device * device)
1243 cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list); 1228 cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list);
1244 /* check FAILFAST */ 1229 /* check FAILFAST */
1245 if (device->stopped & ~DASD_STOPPED_PENDING && 1230 if (device->stopped & ~DASD_STOPPED_PENDING &&
1246 test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) && 1231 test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags)) {
1247 (!device->eer)) {
1248 cqr->status = DASD_CQR_FAILED; 1232 cqr->status = DASD_CQR_FAILED;
1249 dasd_schedule_bh(device); 1233 dasd_schedule_bh(device);
1250 } 1234 }
@@ -1880,9 +1864,10 @@ dasd_generic_remove (struct ccw_device *cdev)
1880 */ 1864 */
1881int 1865int
1882dasd_generic_set_online (struct ccw_device *cdev, 1866dasd_generic_set_online (struct ccw_device *cdev,
1883 struct dasd_discipline *discipline) 1867 struct dasd_discipline *base_discipline)
1884 1868
1885{ 1869{
1870 struct dasd_discipline *discipline;
1886 struct dasd_device *device; 1871 struct dasd_device *device;
1887 int rc; 1872 int rc;
1888 1873
@@ -1890,6 +1875,7 @@ dasd_generic_set_online (struct ccw_device *cdev,
1890 if (IS_ERR(device)) 1875 if (IS_ERR(device))
1891 return PTR_ERR(device); 1876 return PTR_ERR(device);
1892 1877
1878 discipline = base_discipline;
1893 if (device->features & DASD_FEATURE_USEDIAG) { 1879 if (device->features & DASD_FEATURE_USEDIAG) {
1894 if (!dasd_diag_discipline_pointer) { 1880 if (!dasd_diag_discipline_pointer) {
1895 printk (KERN_WARNING 1881 printk (KERN_WARNING
@@ -1901,6 +1887,16 @@ dasd_generic_set_online (struct ccw_device *cdev,
1901 } 1887 }
1902 discipline = dasd_diag_discipline_pointer; 1888 discipline = dasd_diag_discipline_pointer;
1903 } 1889 }
1890 if (!try_module_get(base_discipline->owner)) {
1891 dasd_delete_device(device);
1892 return -EINVAL;
1893 }
1894 if (!try_module_get(discipline->owner)) {
1895 module_put(base_discipline->owner);
1896 dasd_delete_device(device);
1897 return -EINVAL;
1898 }
1899 device->base_discipline = base_discipline;
1904 device->discipline = discipline; 1900 device->discipline = discipline;
1905 1901
1906 rc = discipline->check_device(device); 1902 rc = discipline->check_device(device);
@@ -1909,6 +1905,8 @@ dasd_generic_set_online (struct ccw_device *cdev,
1909 "dasd_generic couldn't online device %s " 1905 "dasd_generic couldn't online device %s "
1910 "with discipline %s rc=%i\n", 1906 "with discipline %s rc=%i\n",
1911 cdev->dev.bus_id, discipline->name, rc); 1907 cdev->dev.bus_id, discipline->name, rc);
1908 module_put(discipline->owner);
1909 module_put(base_discipline->owner);
1912 dasd_delete_device(device); 1910 dasd_delete_device(device);
1913 return rc; 1911 return rc;
1914 } 1912 }
@@ -1986,9 +1984,6 @@ dasd_generic_notify(struct ccw_device *cdev, int event)
1986 switch (event) { 1984 switch (event) {
1987 case CIO_GONE: 1985 case CIO_GONE:
1988 case CIO_NO_PATH: 1986 case CIO_NO_PATH:
1989 /* first of all call extended error reporting */
1990 dasd_write_eer_trigger(DASD_EER_NOPATH, device, NULL);
1991
1992 if (device->state < DASD_STATE_BASIC) 1987 if (device->state < DASD_STATE_BASIC)
1993 break; 1988 break;
1994 /* Device is active. We want to keep it. */ 1989 /* Device is active. We want to keep it. */
@@ -2046,51 +2041,6 @@ dasd_generic_auto_online (struct ccw_driver *dasd_discipline_driver)
2046 put_driver(drv); 2041 put_driver(drv);
2047} 2042}
2048 2043
2049/*
2050 * notifications for extended error reports
2051 */
2052static struct notifier_block *dasd_eer_chain;
2053
2054int
2055dasd_register_eer_notifier(struct notifier_block *nb)
2056{
2057 return notifier_chain_register(&dasd_eer_chain, nb);
2058}
2059
2060int
2061dasd_unregister_eer_notifier(struct notifier_block *nb)
2062{
2063 return notifier_chain_unregister(&dasd_eer_chain, nb);
2064}
2065
2066/*
2067 * Notify the registered error reporting module of a problem
2068 */
2069void
2070dasd_write_eer_trigger(unsigned int id, struct dasd_device *device,
2071 struct dasd_ccw_req *cqr)
2072{
2073 if (device->eer) {
2074 struct dasd_eer_trigger temp;
2075 temp.id = id;
2076 temp.device = device;
2077 temp.cqr = cqr;
2078 notifier_call_chain(&dasd_eer_chain, DASD_EER_TRIGGER,
2079 (void *)&temp);
2080 }
2081}
2082
2083/*
2084 * Tell the registered error reporting module to disable error reporting for
2085 * a given device and to cleanup any private data structures on that device.
2086 */
2087static void
2088dasd_disable_eer(struct dasd_device *device)
2089{
2090 notifier_call_chain(&dasd_eer_chain, DASD_EER_DISABLE, (void *)device);
2091}
2092
2093
2094static int __init 2044static int __init
2095dasd_init(void) 2045dasd_init(void)
2096{ 2046{
@@ -2172,11 +2122,6 @@ EXPORT_SYMBOL_GPL(dasd_generic_set_online);
2172EXPORT_SYMBOL_GPL(dasd_generic_set_offline); 2122EXPORT_SYMBOL_GPL(dasd_generic_set_offline);
2173EXPORT_SYMBOL_GPL(dasd_generic_auto_online); 2123EXPORT_SYMBOL_GPL(dasd_generic_auto_online);
2174 2124
2175EXPORT_SYMBOL(dasd_register_eer_notifier);
2176EXPORT_SYMBOL(dasd_unregister_eer_notifier);
2177EXPORT_SYMBOL(dasd_write_eer_trigger);
2178
2179
2180/* 2125/*
2181 * Overrides for Emacs so that we follow Linus's tabbing style. 2126 * Overrides for Emacs so that we follow Linus's tabbing style.
2182 * Emacs will notice this stuff at the end of the file and automatically 2127 * Emacs will notice this stuff at the end of the file and automatically