aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/block/dasd.c105
-rw-r--r--drivers/s390/block/dasd_3370_erp.c27
-rw-r--r--drivers/s390/block/dasd_3990_erp.c189
-rw-r--r--drivers/s390/block/dasd_9336_erp.c27
-rw-r--r--drivers/s390/block/dasd_9343_erp.c2
-rw-r--r--drivers/s390/block/dasd_devmap.c102
-rw-r--r--drivers/s390/block/dasd_diag.c6
-rw-r--r--drivers/s390/block/dasd_diag.h2
-rw-r--r--drivers/s390/block/dasd_eckd.c337
-rw-r--r--drivers/s390/block/dasd_eckd.h24
-rw-r--r--drivers/s390/block/dasd_eer.c6
-rw-r--r--drivers/s390/block/dasd_erp.c8
-rw-r--r--drivers/s390/block/dasd_fba.c49
-rw-r--r--drivers/s390/block/dasd_fba.h2
-rw-r--r--drivers/s390/block/dasd_int.h39
-rw-r--r--drivers/s390/block/dasd_ioctl.c12
-rw-r--r--drivers/s390/char/raw3270.c67
-rw-r--r--drivers/s390/cio/blacklist.c35
-rw-r--r--drivers/s390/cio/ccwgroup.c17
-rw-r--r--drivers/s390/cio/chsc.c6
-rw-r--r--drivers/s390/cio/cmf.c623
-rw-r--r--drivers/s390/cio/css.c63
-rw-r--r--drivers/s390/cio/device.c4
-rw-r--r--drivers/s390/cio/device.h10
-rw-r--r--drivers/s390/cio/device_fsm.c20
-rw-r--r--drivers/s390/cio/device_ops.c10
-rw-r--r--drivers/s390/s390mach.c5
-rw-r--r--drivers/s390/scsi/zfcp_erp.c14
28 files changed, 1079 insertions, 732 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 8b67ce006521..2dc179b14ce6 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -95,7 +95,7 @@ dasd_alloc_device(void)
95 spin_lock_init(&device->mem_lock); 95 spin_lock_init(&device->mem_lock);
96 spin_lock_init(&device->request_queue_lock); 96 spin_lock_init(&device->request_queue_lock);
97 atomic_set (&device->tasklet_scheduled, 0); 97 atomic_set (&device->tasklet_scheduled, 0);
98 tasklet_init(&device->tasklet, 98 tasklet_init(&device->tasklet,
99 (void (*)(unsigned long)) dasd_tasklet, 99 (void (*)(unsigned long)) dasd_tasklet,
100 (unsigned long) device); 100 (unsigned long) device);
101 INIT_LIST_HEAD(&device->ccw_queue); 101 INIT_LIST_HEAD(&device->ccw_queue);
@@ -128,7 +128,7 @@ dasd_state_new_to_known(struct dasd_device *device)
128 int rc; 128 int rc;
129 129
130 /* 130 /*
131 * As long as the device is not in state DASD_STATE_NEW we want to 131 * As long as the device is not in state DASD_STATE_NEW we want to
132 * keep the reference count > 0. 132 * keep the reference count > 0.
133 */ 133 */
134 dasd_get_device(device); 134 dasd_get_device(device);
@@ -336,7 +336,7 @@ dasd_decrease_state(struct dasd_device *device)
336 if (device->state == DASD_STATE_ONLINE && 336 if (device->state == DASD_STATE_ONLINE &&
337 device->target <= DASD_STATE_READY) 337 device->target <= DASD_STATE_READY)
338 dasd_state_online_to_ready(device); 338 dasd_state_online_to_ready(device);
339 339
340 if (device->state == DASD_STATE_READY && 340 if (device->state == DASD_STATE_READY &&
341 device->target <= DASD_STATE_BASIC) 341 device->target <= DASD_STATE_BASIC)
342 dasd_state_ready_to_basic(device); 342 dasd_state_ready_to_basic(device);
@@ -348,7 +348,7 @@ dasd_decrease_state(struct dasd_device *device)
348 if (device->state == DASD_STATE_BASIC && 348 if (device->state == DASD_STATE_BASIC &&
349 device->target <= DASD_STATE_KNOWN) 349 device->target <= DASD_STATE_KNOWN)
350 dasd_state_basic_to_known(device); 350 dasd_state_basic_to_known(device);
351 351
352 if (device->state == DASD_STATE_KNOWN && 352 if (device->state == DASD_STATE_KNOWN &&
353 device->target <= DASD_STATE_NEW) 353 device->target <= DASD_STATE_NEW)
354 dasd_state_known_to_new(device); 354 dasd_state_known_to_new(device);
@@ -994,7 +994,7 @@ dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
994 ((irb->scsw.cstat << 8) | irb->scsw.dstat), cqr); 994 ((irb->scsw.cstat << 8) | irb->scsw.dstat), cqr);
995 995
996 /* Find out the appropriate era_action. */ 996 /* Find out the appropriate era_action. */
997 if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC) 997 if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC)
998 era = dasd_era_fatal; 998 era = dasd_era_fatal;
999 else if (irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) && 999 else if (irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) &&
1000 irb->scsw.cstat == 0 && 1000 irb->scsw.cstat == 0 &&
@@ -1004,7 +1004,7 @@ dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
1004 era = dasd_era_fatal; /* don't recover this request */ 1004 era = dasd_era_fatal; /* don't recover this request */
1005 else if (irb->esw.esw0.erw.cons) 1005 else if (irb->esw.esw0.erw.cons)
1006 era = device->discipline->examine_error(cqr, irb); 1006 era = device->discipline->examine_error(cqr, irb);
1007 else 1007 else
1008 era = dasd_era_recover; 1008 era = dasd_era_recover;
1009 1009
1010 DBF_DEV_EVENT(DBF_DEBUG, device, "era_code %d", era); 1010 DBF_DEV_EVENT(DBF_DEBUG, device, "era_code %d", era);
@@ -1287,7 +1287,7 @@ __dasd_start_head(struct dasd_device * device)
1287} 1287}
1288 1288
1289/* 1289/*
1290 * Remove requests from the ccw queue. 1290 * Remove requests from the ccw queue.
1291 */ 1291 */
1292static void 1292static void
1293dasd_flush_ccw_queue(struct dasd_device * device, int all) 1293dasd_flush_ccw_queue(struct dasd_device * device, int all)
@@ -1450,23 +1450,23 @@ dasd_sleep_on(struct dasd_ccw_req * cqr)
1450 wait_queue_head_t wait_q; 1450 wait_queue_head_t wait_q;
1451 struct dasd_device *device; 1451 struct dasd_device *device;
1452 int rc; 1452 int rc;
1453 1453
1454 device = cqr->device; 1454 device = cqr->device;
1455 spin_lock_irq(get_ccwdev_lock(device->cdev)); 1455 spin_lock_irq(get_ccwdev_lock(device->cdev));
1456 1456
1457 init_waitqueue_head (&wait_q); 1457 init_waitqueue_head (&wait_q);
1458 cqr->callback = dasd_wakeup_cb; 1458 cqr->callback = dasd_wakeup_cb;
1459 cqr->callback_data = (void *) &wait_q; 1459 cqr->callback_data = (void *) &wait_q;
1460 cqr->status = DASD_CQR_QUEUED; 1460 cqr->status = DASD_CQR_QUEUED;
1461 list_add_tail(&cqr->list, &device->ccw_queue); 1461 list_add_tail(&cqr->list, &device->ccw_queue);
1462 1462
1463 /* let the bh start the request to keep them in order */ 1463 /* let the bh start the request to keep them in order */
1464 dasd_schedule_bh(device); 1464 dasd_schedule_bh(device);
1465 1465
1466 spin_unlock_irq(get_ccwdev_lock(device->cdev)); 1466 spin_unlock_irq(get_ccwdev_lock(device->cdev));
1467 1467
1468 wait_event(wait_q, _wait_for_wakeup(cqr)); 1468 wait_event(wait_q, _wait_for_wakeup(cqr));
1469 1469
1470 /* Request status is either done or failed. */ 1470 /* Request status is either done or failed. */
1471 rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0; 1471 rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0;
1472 return rc; 1472 return rc;
@@ -1568,7 +1568,7 @@ dasd_sleep_on_immediatly(struct dasd_ccw_req * cqr)
1568 wait_queue_head_t wait_q; 1568 wait_queue_head_t wait_q;
1569 struct dasd_device *device; 1569 struct dasd_device *device;
1570 int rc; 1570 int rc;
1571 1571
1572 device = cqr->device; 1572 device = cqr->device;
1573 spin_lock_irq(get_ccwdev_lock(device->cdev)); 1573 spin_lock_irq(get_ccwdev_lock(device->cdev));
1574 rc = _dasd_term_running_cqr(device); 1574 rc = _dasd_term_running_cqr(device);
@@ -1576,20 +1576,20 @@ dasd_sleep_on_immediatly(struct dasd_ccw_req * cqr)
1576 spin_unlock_irq(get_ccwdev_lock(device->cdev)); 1576 spin_unlock_irq(get_ccwdev_lock(device->cdev));
1577 return rc; 1577 return rc;
1578 } 1578 }
1579 1579
1580 init_waitqueue_head (&wait_q); 1580 init_waitqueue_head (&wait_q);
1581 cqr->callback = dasd_wakeup_cb; 1581 cqr->callback = dasd_wakeup_cb;
1582 cqr->callback_data = (void *) &wait_q; 1582 cqr->callback_data = (void *) &wait_q;
1583 cqr->status = DASD_CQR_QUEUED; 1583 cqr->status = DASD_CQR_QUEUED;
1584 list_add(&cqr->list, &device->ccw_queue); 1584 list_add(&cqr->list, &device->ccw_queue);
1585 1585
1586 /* let the bh start the request to keep them in order */ 1586 /* let the bh start the request to keep them in order */
1587 dasd_schedule_bh(device); 1587 dasd_schedule_bh(device);
1588 1588
1589 spin_unlock_irq(get_ccwdev_lock(device->cdev)); 1589 spin_unlock_irq(get_ccwdev_lock(device->cdev));
1590 1590
1591 wait_event(wait_q, _wait_for_wakeup(cqr)); 1591 wait_event(wait_q, _wait_for_wakeup(cqr));
1592 1592
1593 /* Request status is either done or failed. */ 1593 /* Request status is either done or failed. */
1594 rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0; 1594 rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0;
1595 return rc; 1595 return rc;
@@ -1725,7 +1725,7 @@ dasd_flush_request_queue(struct dasd_device * device)
1725 1725
1726 if (!device->request_queue) 1726 if (!device->request_queue)
1727 return; 1727 return;
1728 1728
1729 spin_lock_irq(&device->request_queue_lock); 1729 spin_lock_irq(&device->request_queue_lock);
1730 while (!list_empty(&device->request_queue->queue_head)) { 1730 while (!list_empty(&device->request_queue->queue_head)) {
1731 req = elv_next_request(device->request_queue); 1731 req = elv_next_request(device->request_queue);
@@ -1854,15 +1854,34 @@ dasd_generic_probe (struct ccw_device *cdev,
1854{ 1854{
1855 int ret; 1855 int ret;
1856 1856
1857 ret = ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
1858 if (ret) {
1859 printk(KERN_WARNING
1860 "dasd_generic_probe: could not set ccw-device options "
1861 "for %s\n", cdev->dev.bus_id);
1862 return ret;
1863 }
1857 ret = dasd_add_sysfs_files(cdev); 1864 ret = dasd_add_sysfs_files(cdev);
1858 if (ret) { 1865 if (ret) {
1859 printk(KERN_WARNING 1866 printk(KERN_WARNING
1860 "dasd_generic_probe: could not add sysfs entries " 1867 "dasd_generic_probe: could not add sysfs entries "
1861 "for %s\n", cdev->dev.bus_id); 1868 "for %s\n", cdev->dev.bus_id);
1862 } else { 1869 return ret;
1863 cdev->handler = &dasd_int_handler;
1864 } 1870 }
1871 cdev->handler = &dasd_int_handler;
1865 1872
1873 /*
1874 * Automatically online either all dasd devices (dasd_autodetect)
1875 * or all devices specified with dasd= parameters during
1876 * initial probe.
1877 */
1878 if ((dasd_get_feature(cdev, DASD_FEATURE_INITIAL_ONLINE) > 0 ) ||
1879 (dasd_autodetect && dasd_busid_known(cdev->dev.bus_id) != 0))
1880 ret = ccw_device_set_online(cdev);
1881 if (ret)
1882 printk(KERN_WARNING
1883 "dasd_generic_probe: could not initially online "
1884 "ccw-device %s\n", cdev->dev.bus_id);
1866 return ret; 1885 return ret;
1867} 1886}
1868 1887
@@ -1910,6 +1929,8 @@ dasd_generic_set_online (struct ccw_device *cdev,
1910 struct dasd_device *device; 1929 struct dasd_device *device;
1911 int rc; 1930 int rc;
1912 1931
1932 /* first online clears initial online feature flag */
1933 dasd_set_feature(cdev, DASD_FEATURE_INITIAL_ONLINE, 0);
1913 device = dasd_create_device(cdev); 1934 device = dasd_create_device(cdev);
1914 if (IS_ERR(device)) 1935 if (IS_ERR(device))
1915 return PTR_ERR(device); 1936 return PTR_ERR(device);
@@ -2064,31 +2085,6 @@ dasd_generic_notify(struct ccw_device *cdev, int event)
2064 return ret; 2085 return ret;
2065} 2086}
2066 2087
2067/*
2068 * Automatically online either all dasd devices (dasd_autodetect) or
2069 * all devices specified with dasd= parameters.
2070 */
2071static int
2072__dasd_auto_online(struct device *dev, void *data)
2073{
2074 struct ccw_device *cdev;
2075
2076 cdev = to_ccwdev(dev);
2077 if (dasd_autodetect || dasd_busid_known(cdev->dev.bus_id) == 0)
2078 ccw_device_set_online(cdev);
2079 return 0;
2080}
2081
2082void
2083dasd_generic_auto_online (struct ccw_driver *dasd_discipline_driver)
2084{
2085 struct device_driver *drv;
2086
2087 drv = get_driver(&dasd_discipline_driver->driver);
2088 driver_for_each_device(drv, NULL, NULL, __dasd_auto_online);
2089 put_driver(drv);
2090}
2091
2092 2088
2093static int __init 2089static int __init
2094dasd_init(void) 2090dasd_init(void)
@@ -2166,23 +2162,4 @@ EXPORT_SYMBOL_GPL(dasd_generic_remove);
2166EXPORT_SYMBOL_GPL(dasd_generic_notify); 2162EXPORT_SYMBOL_GPL(dasd_generic_notify);
2167EXPORT_SYMBOL_GPL(dasd_generic_set_online); 2163EXPORT_SYMBOL_GPL(dasd_generic_set_online);
2168EXPORT_SYMBOL_GPL(dasd_generic_set_offline); 2164EXPORT_SYMBOL_GPL(dasd_generic_set_offline);
2169EXPORT_SYMBOL_GPL(dasd_generic_auto_online);
2170 2165
2171/*
2172 * Overrides for Emacs so that we follow Linus's tabbing style.
2173 * Emacs will notice this stuff at the end of the file and automatically
2174 * adjust the settings for this buffer only. This must remain at the end
2175 * of the file.
2176 * ---------------------------------------------------------------------------
2177 * Local variables:
2178 * c-indent-level: 4
2179 * c-brace-imaginary-offset: 0
2180 * c-brace-offset: -4
2181 * c-argdecl-indent: 4
2182 * c-label-offset: -4
2183 * c-continued-statement-offset: 4
2184 * c-continued-brace-offset: 0
2185 * indent-tabs-mode: 1
2186 * tab-width: 8
2187 * End:
2188 */
diff --git a/drivers/s390/block/dasd_3370_erp.c b/drivers/s390/block/dasd_3370_erp.c
index 1d11c2a9525d..1ddab8991d92 100644
--- a/drivers/s390/block/dasd_3370_erp.c
+++ b/drivers/s390/block/dasd_3370_erp.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * File...........: linux/drivers/s390/block/dasd_3370_erp.c 2 * File...........: linux/drivers/s390/block/dasd_3370_erp.c
3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4 * Bugreports.to..: <Linux390@de.ibm.com> 4 * Bugreports.to..: <Linux390@de.ibm.com>
@@ -12,10 +12,10 @@
12 12
13 13
14/* 14/*
15 * DASD_3370_ERP_EXAMINE 15 * DASD_3370_ERP_EXAMINE
16 * 16 *
17 * DESCRIPTION 17 * DESCRIPTION
18 * Checks only for fatal/no/recover error. 18 * Checks only for fatal/no/recover error.
19 * A detailed examination of the sense data is done later outside 19 * A detailed examination of the sense data is done later outside
20 * the interrupt handler. 20 * the interrupt handler.
21 * 21 *
@@ -23,7 +23,7 @@
23 * 'Chapter 7. 3370 Sense Data'. 23 * 'Chapter 7. 3370 Sense Data'.
24 * 24 *
25 * RETURN VALUES 25 * RETURN VALUES
26 * dasd_era_none no error 26 * dasd_era_none no error
27 * dasd_era_fatal for all fatal (unrecoverable errors) 27 * dasd_era_fatal for all fatal (unrecoverable errors)
28 * dasd_era_recover for all others. 28 * dasd_era_recover for all others.
29 */ 29 */
@@ -82,22 +82,3 @@ dasd_3370_erp_examine(struct dasd_ccw_req * cqr, struct irb * irb)
82 return dasd_era_recover; 82 return dasd_era_recover;
83 83
84} /* END dasd_3370_erp_examine */ 84} /* END dasd_3370_erp_examine */
85
86/*
87 * Overrides for Emacs so that we follow Linus's tabbing style.
88 * Emacs will notice this stuff at the end of the file and automatically
89 * adjust the settings for this buffer only. This must remain at the end
90 * of the file.
91 * ---------------------------------------------------------------------------
92 * Local variables:
93 * c-indent-level: 4
94 * c-brace-imaginary-offset: 0
95 * c-brace-offset: -4
96 * c-argdecl-indent: 4
97 * c-label-offset: -4
98 * c-continued-statement-offset: 4
99 * c-continued-brace-offset: 0
100 * indent-tabs-mode: 1
101 * tab-width: 8
102 * End:
103 */
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
index 2ed51562319e..669805d4402d 100644
--- a/drivers/s390/block/dasd_3990_erp.c
+++ b/drivers/s390/block/dasd_3990_erp.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * File...........: linux/drivers/s390/block/dasd_3990_erp.c 2 * File...........: linux/drivers/s390/block/dasd_3990_erp.c
3 * Author(s)......: Horst Hummel <Horst.Hummel@de.ibm.com> 3 * Author(s)......: Horst Hummel <Horst.Hummel@de.ibm.com>
4 * Holger Smolinski <Holger.Smolinski@de.ibm.com> 4 * Holger Smolinski <Holger.Smolinski@de.ibm.com>
5 * Bugreports.to..: <Linux390@de.ibm.com> 5 * Bugreports.to..: <Linux390@de.ibm.com>
6 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000, 2001 6 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000, 2001
@@ -25,23 +25,23 @@ struct DCTL_data {
25} __attribute__ ((packed)); 25} __attribute__ ((packed));
26 26
27/* 27/*
28 ***************************************************************************** 28 *****************************************************************************
29 * SECTION ERP EXAMINATION 29 * SECTION ERP EXAMINATION
30 ***************************************************************************** 30 *****************************************************************************
31 */ 31 */
32 32
33/* 33/*
34 * DASD_3990_ERP_EXAMINE_24 34 * DASD_3990_ERP_EXAMINE_24
35 * 35 *
36 * DESCRIPTION 36 * DESCRIPTION
37 * Checks only for fatal (unrecoverable) error. 37 * Checks only for fatal (unrecoverable) error.
38 * A detailed examination of the sense data is done later outside 38 * A detailed examination of the sense data is done later outside
39 * the interrupt handler. 39 * the interrupt handler.
40 * 40 *
41 * Each bit configuration leading to an action code 2 (Exit with 41 * Each bit configuration leading to an action code 2 (Exit with
42 * programming error or unusual condition indication) 42 * programming error or unusual condition indication)
43 * are handled as fatal error´s. 43 * are handled as fatal error´s.
44 * 44 *
45 * All other configurations are handled as recoverable errors. 45 * All other configurations are handled as recoverable errors.
46 * 46 *
47 * RETURN VALUES 47 * RETURN VALUES
@@ -93,15 +93,15 @@ dasd_3990_erp_examine_24(struct dasd_ccw_req * cqr, char *sense)
93} /* END dasd_3990_erp_examine_24 */ 93} /* END dasd_3990_erp_examine_24 */
94 94
95/* 95/*
96 * DASD_3990_ERP_EXAMINE_32 96 * DASD_3990_ERP_EXAMINE_32
97 * 97 *
98 * DESCRIPTION 98 * DESCRIPTION
99 * Checks only for fatal/no/recoverable error. 99 * Checks only for fatal/no/recoverable error.
100 * A detailed examination of the sense data is done later outside 100 * A detailed examination of the sense data is done later outside
101 * the interrupt handler. 101 * the interrupt handler.
102 * 102 *
103 * RETURN VALUES 103 * RETURN VALUES
104 * dasd_era_none no error 104 * dasd_era_none no error
105 * dasd_era_fatal for all fatal (unrecoverable errors) 105 * dasd_era_fatal for all fatal (unrecoverable errors)
106 * dasd_era_recover for recoverable others. 106 * dasd_era_recover for recoverable others.
107 */ 107 */
@@ -128,10 +128,10 @@ dasd_3990_erp_examine_32(struct dasd_ccw_req * cqr, char *sense)
128} /* end dasd_3990_erp_examine_32 */ 128} /* end dasd_3990_erp_examine_32 */
129 129
130/* 130/*
131 * DASD_3990_ERP_EXAMINE 131 * DASD_3990_ERP_EXAMINE
132 * 132 *
133 * DESCRIPTION 133 * DESCRIPTION
134 * Checks only for fatal/no/recover error. 134 * Checks only for fatal/no/recover error.
135 * A detailed examination of the sense data is done later outside 135 * A detailed examination of the sense data is done later outside
136 * the interrupt handler. 136 * the interrupt handler.
137 * 137 *
@@ -139,7 +139,7 @@ dasd_3990_erp_examine_32(struct dasd_ccw_req * cqr, char *sense)
139 * 'Chapter 7. Error Recovery Procedures'. 139 * 'Chapter 7. Error Recovery Procedures'.
140 * 140 *
141 * RETURN VALUES 141 * RETURN VALUES
142 * dasd_era_none no error 142 * dasd_era_none no error
143 * dasd_era_fatal for all fatal (unrecoverable errors) 143 * dasd_era_fatal for all fatal (unrecoverable errors)
144 * dasd_era_recover for all others. 144 * dasd_era_recover for all others.
145 */ 145 */
@@ -178,18 +178,18 @@ dasd_3990_erp_examine(struct dasd_ccw_req * cqr, struct irb * irb)
178} /* END dasd_3990_erp_examine */ 178} /* END dasd_3990_erp_examine */
179 179
180/* 180/*
181 ***************************************************************************** 181 *****************************************************************************
182 * SECTION ERP HANDLING 182 * SECTION ERP HANDLING
183 ***************************************************************************** 183 *****************************************************************************
184 */ 184 */
185/* 185/*
186 ***************************************************************************** 186 *****************************************************************************
187 * 24 and 32 byte sense ERP functions 187 * 24 and 32 byte sense ERP functions
188 ***************************************************************************** 188 *****************************************************************************
189 */ 189 */
190 190
191/* 191/*
192 * DASD_3990_ERP_CLEANUP 192 * DASD_3990_ERP_CLEANUP
193 * 193 *
194 * DESCRIPTION 194 * DESCRIPTION
195 * Removes the already build but not necessary ERP request and sets 195 * Removes the already build but not necessary ERP request and sets
@@ -197,10 +197,10 @@ dasd_3990_erp_examine(struct dasd_ccw_req * cqr, struct irb * irb)
197 * 197 *
198 * PARAMETER 198 * PARAMETER
199 * erp request to be blocked 199 * erp request to be blocked
200 * final_status either DASD_CQR_DONE or DASD_CQR_FAILED 200 * final_status either DASD_CQR_DONE or DASD_CQR_FAILED
201 * 201 *
202 * RETURN VALUES 202 * RETURN VALUES
203 * cqr original cqr 203 * cqr original cqr
204 */ 204 */
205static struct dasd_ccw_req * 205static struct dasd_ccw_req *
206dasd_3990_erp_cleanup(struct dasd_ccw_req * erp, char final_status) 206dasd_3990_erp_cleanup(struct dasd_ccw_req * erp, char final_status)
@@ -214,7 +214,7 @@ dasd_3990_erp_cleanup(struct dasd_ccw_req * erp, char final_status)
214} /* end dasd_3990_erp_cleanup */ 214} /* end dasd_3990_erp_cleanup */
215 215
216/* 216/*
217 * DASD_3990_ERP_BLOCK_QUEUE 217 * DASD_3990_ERP_BLOCK_QUEUE
218 * 218 *
219 * DESCRIPTION 219 * DESCRIPTION
220 * Block the given device request queue to prevent from further 220 * Block the given device request queue to prevent from further
@@ -237,7 +237,7 @@ dasd_3990_erp_block_queue(struct dasd_ccw_req * erp, int expires)
237} 237}
238 238
239/* 239/*
240 * DASD_3990_ERP_INT_REQ 240 * DASD_3990_ERP_INT_REQ
241 * 241 *
242 * DESCRIPTION 242 * DESCRIPTION
243 * Handles 'Intervention Required' error. 243 * Handles 'Intervention Required' error.
@@ -277,7 +277,7 @@ dasd_3990_erp_int_req(struct dasd_ccw_req * erp)
277} /* end dasd_3990_erp_int_req */ 277} /* end dasd_3990_erp_int_req */
278 278
279/* 279/*
280 * DASD_3990_ERP_ALTERNATE_PATH 280 * DASD_3990_ERP_ALTERNATE_PATH
281 * 281 *
282 * DESCRIPTION 282 * DESCRIPTION
283 * Repeat the operation on a different channel path. 283 * Repeat the operation on a different channel path.
@@ -330,15 +330,15 @@ dasd_3990_erp_alternate_path(struct dasd_ccw_req * erp)
330 * DASD_3990_ERP_DCTL 330 * DASD_3990_ERP_DCTL
331 * 331 *
332 * DESCRIPTION 332 * DESCRIPTION
333 * Setup cqr to do the Diagnostic Control (DCTL) command with an 333 * Setup cqr to do the Diagnostic Control (DCTL) command with an
334 * Inhibit Write subcommand (0x20) and the given modifier. 334 * Inhibit Write subcommand (0x20) and the given modifier.
335 * 335 *
336 * PARAMETER 336 * PARAMETER
337 * erp pointer to the current (failed) ERP 337 * erp pointer to the current (failed) ERP
338 * modifier subcommand modifier 338 * modifier subcommand modifier
339 * 339 *
340 * RETURN VALUES 340 * RETURN VALUES
341 * dctl_cqr pointer to NEW dctl_cqr 341 * dctl_cqr pointer to NEW dctl_cqr
342 * 342 *
343 */ 343 */
344static struct dasd_ccw_req * 344static struct dasd_ccw_req *
@@ -386,7 +386,7 @@ dasd_3990_erp_DCTL(struct dasd_ccw_req * erp, char modifier)
386} /* end dasd_3990_erp_DCTL */ 386} /* end dasd_3990_erp_DCTL */
387 387
388/* 388/*
389 * DASD_3990_ERP_ACTION_1 389 * DASD_3990_ERP_ACTION_1
390 * 390 *
391 * DESCRIPTION 391 * DESCRIPTION
392 * Setup ERP to do the ERP action 1 (see Reference manual). 392 * Setup ERP to do the ERP action 1 (see Reference manual).
@@ -415,7 +415,7 @@ dasd_3990_erp_action_1(struct dasd_ccw_req * erp)
415} /* end dasd_3990_erp_action_1 */ 415} /* end dasd_3990_erp_action_1 */
416 416
417/* 417/*
418 * DASD_3990_ERP_ACTION_4 418 * DASD_3990_ERP_ACTION_4
419 * 419 *
420 * DESCRIPTION 420 * DESCRIPTION
421 * Setup ERP to do the ERP action 4 (see Reference manual). 421 * Setup ERP to do the ERP action 4 (see Reference manual).
@@ -453,11 +453,11 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense)
453 453
454 if (sense[25] == 0x1D) { /* state change pending */ 454 if (sense[25] == 0x1D) { /* state change pending */
455 455
456 DEV_MESSAGE(KERN_INFO, device, 456 DEV_MESSAGE(KERN_INFO, device,
457 "waiting for state change pending " 457 "waiting for state change pending "
458 "interrupt, %d retries left", 458 "interrupt, %d retries left",
459 erp->retries); 459 erp->retries);
460 460
461 dasd_3990_erp_block_queue(erp, 30*HZ); 461 dasd_3990_erp_block_queue(erp, 30*HZ);
462 462
463 } else if (sense[25] == 0x1E) { /* busy */ 463 } else if (sense[25] == 0x1E) { /* busy */
@@ -469,9 +469,9 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense)
469 } else { 469 } else {
470 470
471 /* no state change pending - retry */ 471 /* no state change pending - retry */
472 DEV_MESSAGE (KERN_INFO, device, 472 DEV_MESSAGE (KERN_INFO, device,
473 "redriving request immediately, " 473 "redriving request immediately, "
474 "%d retries left", 474 "%d retries left",
475 erp->retries); 475 erp->retries);
476 erp->status = DASD_CQR_QUEUED; 476 erp->status = DASD_CQR_QUEUED;
477 } 477 }
@@ -482,13 +482,13 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense)
482} /* end dasd_3990_erp_action_4 */ 482} /* end dasd_3990_erp_action_4 */
483 483
484/* 484/*
485 ***************************************************************************** 485 *****************************************************************************
486 * 24 byte sense ERP functions (only) 486 * 24 byte sense ERP functions (only)
487 ***************************************************************************** 487 *****************************************************************************
488 */ 488 */
489 489
490/* 490/*
491 * DASD_3990_ERP_ACTION_5 491 * DASD_3990_ERP_ACTION_5
492 * 492 *
493 * DESCRIPTION 493 * DESCRIPTION
494 * Setup ERP to do the ERP action 5 (see Reference manual). 494 * Setup ERP to do the ERP action 5 (see Reference manual).
@@ -523,7 +523,7 @@ dasd_3990_erp_action_5(struct dasd_ccw_req * erp)
523 * 523 *
524 * PARAMETER 524 * PARAMETER
525 * sense current sense data 525 * sense current sense data
526 * 526 *
527 * RETURN VALUES 527 * RETURN VALUES
528 * void 528 * void
529 */ 529 */
@@ -1150,9 +1150,9 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense)
1150 * PARAMETER 1150 * PARAMETER
1151 * erp current erp_head 1151 * erp current erp_head
1152 * sense current sense data 1152 * sense current sense data
1153 * 1153 *
1154 * RETURN VALUES 1154 * RETURN VALUES
1155 * erp 'new' erp_head - pointer to new ERP 1155 * erp 'new' erp_head - pointer to new ERP
1156 */ 1156 */
1157static struct dasd_ccw_req * 1157static struct dasd_ccw_req *
1158dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense) 1158dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense)
@@ -1185,7 +1185,7 @@ dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense)
1185} /* end dasd_3990_erp_com_rej */ 1185} /* end dasd_3990_erp_com_rej */
1186 1186
1187/* 1187/*
1188 * DASD_3990_ERP_BUS_OUT 1188 * DASD_3990_ERP_BUS_OUT
1189 * 1189 *
1190 * DESCRIPTION 1190 * DESCRIPTION
1191 * Handles 24 byte 'Bus Out Parity Check' error. 1191 * Handles 24 byte 'Bus Out Parity Check' error.
@@ -1483,7 +1483,7 @@ dasd_3990_erp_env_data(struct dasd_ccw_req * erp, char *sense)
1483 * 1483 *
1484 * PARAMETER 1484 * PARAMETER
1485 * erp already added default ERP 1485 * erp already added default ERP
1486 * 1486 *
1487 * RETURN VALUES 1487 * RETURN VALUES
1488 * erp new erp_head - pointer to new ERP 1488 * erp new erp_head - pointer to new ERP
1489 */ 1489 */
@@ -1527,11 +1527,11 @@ dasd_3990_erp_file_prot(struct dasd_ccw_req * erp)
1527} /* end dasd_3990_erp_file_prot */ 1527} /* end dasd_3990_erp_file_prot */
1528 1528
1529/* 1529/*
1530 * DASD_3990_ERP_INSPECT_24 1530 * DASD_3990_ERP_INSPECT_24
1531 * 1531 *
1532 * DESCRIPTION 1532 * DESCRIPTION
1533 * Does a detailed inspection of the 24 byte sense data 1533 * Does a detailed inspection of the 24 byte sense data
1534 * and sets up a related error recovery action. 1534 * and sets up a related error recovery action.
1535 * 1535 *
1536 * PARAMETER 1536 * PARAMETER
1537 * sense sense data of the actual error 1537 * sense sense data of the actual error
@@ -1602,13 +1602,13 @@ dasd_3990_erp_inspect_24(struct dasd_ccw_req * erp, char *sense)
1602} /* END dasd_3990_erp_inspect_24 */ 1602} /* END dasd_3990_erp_inspect_24 */
1603 1603
1604/* 1604/*
1605 ***************************************************************************** 1605 *****************************************************************************
1606 * 32 byte sense ERP functions (only) 1606 * 32 byte sense ERP functions (only)
1607 ***************************************************************************** 1607 *****************************************************************************
1608 */ 1608 */
1609 1609
1610/* 1610/*
1611 * DASD_3990_ERPACTION_10_32 1611 * DASD_3990_ERPACTION_10_32
1612 * 1612 *
1613 * DESCRIPTION 1613 * DESCRIPTION
1614 * Handles 32 byte 'Action 10' of Single Program Action Codes. 1614 * Handles 32 byte 'Action 10' of Single Program Action Codes.
@@ -1616,7 +1616,7 @@ dasd_3990_erp_inspect_24(struct dasd_ccw_req * erp, char *sense)
1616 * 1616 *
1617 * PARAMETER 1617 * PARAMETER
1618 * erp current erp_head 1618 * erp current erp_head
1619 * sense current sense data 1619 * sense current sense data
1620 * RETURN VALUES 1620 * RETURN VALUES
1621 * erp modified erp_head 1621 * erp modified erp_head
1622 */ 1622 */
@@ -1640,18 +1640,18 @@ dasd_3990_erp_action_10_32(struct dasd_ccw_req * erp, char *sense)
1640 * 1640 *
1641 * DESCRIPTION 1641 * DESCRIPTION
1642 * Handles 32 byte 'Action 1B' of Single Program Action Codes. 1642 * Handles 32 byte 'Action 1B' of Single Program Action Codes.
1643 * A write operation could not be finished because of an unexpected 1643 * A write operation could not be finished because of an unexpected
1644 * condition. 1644 * condition.
1645 * The already created 'default erp' is used to get the link to 1645 * The already created 'default erp' is used to get the link to
1646 * the erp chain, but it can not be used for this recovery 1646 * the erp chain, but it can not be used for this recovery
1647 * action because it contains no DE/LO data space. 1647 * action because it contains no DE/LO data space.
1648 * 1648 *
1649 * PARAMETER 1649 * PARAMETER
1650 * default_erp already added default erp. 1650 * default_erp already added default erp.
1651 * sense current sense data 1651 * sense current sense data
1652 * 1652 *
1653 * RETURN VALUES 1653 * RETURN VALUES
1654 * erp new erp or 1654 * erp new erp or
1655 * default_erp in case of imprecise ending or error 1655 * default_erp in case of imprecise ending or error
1656 */ 1656 */
1657static struct dasd_ccw_req * 1657static struct dasd_ccw_req *
@@ -1789,16 +1789,16 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
1789 * DASD_3990_UPDATE_1B 1789 * DASD_3990_UPDATE_1B
1790 * 1790 *
1791 * DESCRIPTION 1791 * DESCRIPTION
1792 * Handles the update to the 32 byte 'Action 1B' of Single Program 1792 * Handles the update to the 32 byte 'Action 1B' of Single Program
1793 * Action Codes in case the first action was not successful. 1793 * Action Codes in case the first action was not successful.
1794 * The already created 'previous_erp' is the currently not successful 1794 * The already created 'previous_erp' is the currently not successful
1795 * ERP. 1795 * ERP.
1796 * 1796 *
1797 * PARAMETER 1797 * PARAMETER
1798 * previous_erp already created previous erp. 1798 * previous_erp already created previous erp.
1799 * sense current sense data 1799 * sense current sense data
1800 * RETURN VALUES 1800 * RETURN VALUES
1801 * erp modified erp 1801 * erp modified erp
1802 */ 1802 */
1803static struct dasd_ccw_req * 1803static struct dasd_ccw_req *
1804dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense) 1804dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense)
@@ -1897,7 +1897,7 @@ dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense)
1897} /* end dasd_3990_update_1B */ 1897} /* end dasd_3990_update_1B */
1898 1898
1899/* 1899/*
1900 * DASD_3990_ERP_COMPOUND_RETRY 1900 * DASD_3990_ERP_COMPOUND_RETRY
1901 * 1901 *
1902 * DESCRIPTION 1902 * DESCRIPTION
1903 * Handles the compound ERP action retry code. 1903 * Handles the compound ERP action retry code.
@@ -1943,7 +1943,7 @@ dasd_3990_erp_compound_retry(struct dasd_ccw_req * erp, char *sense)
1943} /* end dasd_3990_erp_compound_retry */ 1943} /* end dasd_3990_erp_compound_retry */
1944 1944
1945/* 1945/*
1946 * DASD_3990_ERP_COMPOUND_PATH 1946 * DASD_3990_ERP_COMPOUND_PATH
1947 * 1947 *
1948 * DESCRIPTION 1948 * DESCRIPTION
1949 * Handles the compound ERP action for retry on alternate 1949 * Handles the compound ERP action for retry on alternate
@@ -1965,7 +1965,7 @@ dasd_3990_erp_compound_path(struct dasd_ccw_req * erp, char *sense)
1965 dasd_3990_erp_alternate_path(erp); 1965 dasd_3990_erp_alternate_path(erp);
1966 1966
1967 if (erp->status == DASD_CQR_FAILED) { 1967 if (erp->status == DASD_CQR_FAILED) {
1968 /* reset the lpm and the status to be able to 1968 /* reset the lpm and the status to be able to
1969 * try further actions. */ 1969 * try further actions. */
1970 1970
1971 erp->lpm = 0; 1971 erp->lpm = 0;
@@ -1980,7 +1980,7 @@ dasd_3990_erp_compound_path(struct dasd_ccw_req * erp, char *sense)
1980} /* end dasd_3990_erp_compound_path */ 1980} /* end dasd_3990_erp_compound_path */
1981 1981
1982/* 1982/*
1983 * DASD_3990_ERP_COMPOUND_CODE 1983 * DASD_3990_ERP_COMPOUND_CODE
1984 * 1984 *
1985 * DESCRIPTION 1985 * DESCRIPTION
1986 * Handles the compound ERP action for retry code. 1986 * Handles the compound ERP action for retry code.
@@ -2001,18 +2001,18 @@ dasd_3990_erp_compound_code(struct dasd_ccw_req * erp, char *sense)
2001 2001
2002 switch (sense[28]) { 2002 switch (sense[28]) {
2003 case 0x17: 2003 case 0x17:
2004 /* issue a Diagnostic Control command with an 2004 /* issue a Diagnostic Control command with an
2005 * Inhibit Write subcommand and controler modifier */ 2005 * Inhibit Write subcommand and controler modifier */
2006 erp = dasd_3990_erp_DCTL(erp, 0x20); 2006 erp = dasd_3990_erp_DCTL(erp, 0x20);
2007 break; 2007 break;
2008 2008
2009 case 0x25: 2009 case 0x25:
2010 /* wait for 5 seconds and retry again */ 2010 /* wait for 5 seconds and retry again */
2011 erp->retries = 1; 2011 erp->retries = 1;
2012 2012
2013 dasd_3990_erp_block_queue (erp, 5*HZ); 2013 dasd_3990_erp_block_queue (erp, 5*HZ);
2014 break; 2014 break;
2015 2015
2016 default: 2016 default:
2017 /* should not happen - continue */ 2017 /* should not happen - continue */
2018 break; 2018 break;
@@ -2026,7 +2026,7 @@ dasd_3990_erp_compound_code(struct dasd_ccw_req * erp, char *sense)
2026} /* end dasd_3990_erp_compound_code */ 2026} /* end dasd_3990_erp_compound_code */
2027 2027
2028/* 2028/*
2029 * DASD_3990_ERP_COMPOUND_CONFIG 2029 * DASD_3990_ERP_COMPOUND_CONFIG
2030 * 2030 *
2031 * DESCRIPTION 2031 * DESCRIPTION
2032 * Handles the compound ERP action for configruation 2032 * Handles the compound ERP action for configruation
@@ -2063,10 +2063,10 @@ dasd_3990_erp_compound_config(struct dasd_ccw_req * erp, char *sense)
2063} /* end dasd_3990_erp_compound_config */ 2063} /* end dasd_3990_erp_compound_config */
2064 2064
2065/* 2065/*
2066 * DASD_3990_ERP_COMPOUND 2066 * DASD_3990_ERP_COMPOUND
2067 * 2067 *
2068 * DESCRIPTION 2068 * DESCRIPTION
2069 * Does the further compound program action if 2069 * Does the further compound program action if
2070 * compound retry was not successful. 2070 * compound retry was not successful.
2071 * 2071 *
2072 * PARAMETER 2072 * PARAMETER
@@ -2110,11 +2110,11 @@ dasd_3990_erp_compound(struct dasd_ccw_req * erp, char *sense)
2110} /* end dasd_3990_erp_compound */ 2110} /* end dasd_3990_erp_compound */
2111 2111
2112/* 2112/*
2113 * DASD_3990_ERP_INSPECT_32 2113 * DASD_3990_ERP_INSPECT_32
2114 * 2114 *
2115 * DESCRIPTION 2115 * DESCRIPTION
2116 * Does a detailed inspection of the 32 byte sense data 2116 * Does a detailed inspection of the 32 byte sense data
2117 * and sets up a related error recovery action. 2117 * and sets up a related error recovery action.
2118 * 2118 *
2119 * PARAMETER 2119 * PARAMETER
2120 * sense sense data of the actual error 2120 * sense sense data of the actual error
@@ -2228,9 +2228,9 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
2228} /* end dasd_3990_erp_inspect_32 */ 2228} /* end dasd_3990_erp_inspect_32 */
2229 2229
2230/* 2230/*
2231 ***************************************************************************** 2231 *****************************************************************************
2232 * main ERP control fuctions (24 and 32 byte sense) 2232 * main ERP control fuctions (24 and 32 byte sense)
2233 ***************************************************************************** 2233 *****************************************************************************
2234 */ 2234 */
2235 2235
2236/* 2236/*
@@ -2243,7 +2243,7 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
2243 * PARAMETER 2243 * PARAMETER
2244 * erp pointer to the currently created default ERP 2244 * erp pointer to the currently created default ERP
2245 * RETURN VALUES 2245 * RETURN VALUES
2246 * erp_new contens was possibly modified 2246 * erp_new contens was possibly modified
2247 */ 2247 */
2248static struct dasd_ccw_req * 2248static struct dasd_ccw_req *
2249dasd_3990_erp_inspect(struct dasd_ccw_req * erp) 2249dasd_3990_erp_inspect(struct dasd_ccw_req * erp)
@@ -2272,14 +2272,14 @@ dasd_3990_erp_inspect(struct dasd_ccw_req * erp)
2272 2272
2273/* 2273/*
2274 * DASD_3990_ERP_ADD_ERP 2274 * DASD_3990_ERP_ADD_ERP
2275 * 2275 *
2276 * DESCRIPTION 2276 * DESCRIPTION
2277 * This funtion adds an additional request block (ERP) to the head of 2277 * This funtion adds an additional request block (ERP) to the head of
2278 * the given cqr (or erp). 2278 * the given cqr (or erp).
2279 * This erp is initialized as an default erp (retry TIC) 2279 * This erp is initialized as an default erp (retry TIC)
2280 * 2280 *
2281 * PARAMETER 2281 * PARAMETER
2282 * cqr head of the current ERP-chain (or single cqr if 2282 * cqr head of the current ERP-chain (or single cqr if
2283 * first error) 2283 * first error)
2284 * RETURN VALUES 2284 * RETURN VALUES
2285 * erp pointer to new ERP-chain head 2285 * erp pointer to new ERP-chain head
@@ -2332,15 +2332,15 @@ dasd_3990_erp_add_erp(struct dasd_ccw_req * cqr)
2332} 2332}
2333 2333
2334/* 2334/*
2335 * DASD_3990_ERP_ADDITIONAL_ERP 2335 * DASD_3990_ERP_ADDITIONAL_ERP
2336 * 2336 *
2337 * DESCRIPTION 2337 * DESCRIPTION
2338 * An additional ERP is needed to handle the current error. 2338 * An additional ERP is needed to handle the current error.
2339 * Add ERP to the head of the ERP-chain containing the ERP processing 2339 * Add ERP to the head of the ERP-chain containing the ERP processing
2340 * determined based on the sense data. 2340 * determined based on the sense data.
2341 * 2341 *
2342 * PARAMETER 2342 * PARAMETER
2343 * cqr head of the current ERP-chain (or single cqr if 2343 * cqr head of the current ERP-chain (or single cqr if
2344 * first error) 2344 * first error)
2345 * 2345 *
2346 * RETURN VALUES 2346 * RETURN VALUES
@@ -2376,7 +2376,7 @@ dasd_3990_erp_additional_erp(struct dasd_ccw_req * cqr)
2376 * 24 byte sense byte 25 and 27 is set as well. 2376 * 24 byte sense byte 25 and 27 is set as well.
2377 * 2377 *
2378 * PARAMETER 2378 * PARAMETER
2379 * cqr1 first cqr, which will be compared with the 2379 * cqr1 first cqr, which will be compared with the
2380 * cqr2 second cqr. 2380 * cqr2 second cqr.
2381 * 2381 *
2382 * RETURN VALUES 2382 * RETURN VALUES
@@ -2415,7 +2415,7 @@ dasd_3990_erp_error_match(struct dasd_ccw_req *cqr1, struct dasd_ccw_req *cqr2)
2415 * cqr failed cqr (either original cqr or already an erp) 2415 * cqr failed cqr (either original cqr or already an erp)
2416 * 2416 *
2417 * RETURN VALUES 2417 * RETURN VALUES
2418 * erp erp-pointer to the already defined error 2418 * erp erp-pointer to the already defined error
2419 * recovery procedure OR 2419 * recovery procedure OR
2420 * NULL if a 'new' error occurred. 2420 * NULL if a 'new' error occurred.
2421 */ 2421 */
@@ -2451,10 +2451,10 @@ dasd_3990_erp_in_erp(struct dasd_ccw_req *cqr)
2451 * DASD_3990_ERP_FURTHER_ERP (24 & 32 byte sense) 2451 * DASD_3990_ERP_FURTHER_ERP (24 & 32 byte sense)
2452 * 2452 *
2453 * DESCRIPTION 2453 * DESCRIPTION
2454 * No retry is left for the current ERP. Check what has to be done 2454 * No retry is left for the current ERP. Check what has to be done
2455 * with the ERP. 2455 * with the ERP.
2456 * - do further defined ERP action or 2456 * - do further defined ERP action or
2457 * - wait for interrupt or 2457 * - wait for interrupt or
2458 * - exit with permanent error 2458 * - exit with permanent error
2459 * 2459 *
2460 * PARAMETER 2460 * PARAMETER
@@ -2485,7 +2485,7 @@ dasd_3990_erp_further_erp(struct dasd_ccw_req *erp)
2485 2485
2486 if (!(sense[2] & DASD_SENSE_BIT_0)) { 2486 if (!(sense[2] & DASD_SENSE_BIT_0)) {
2487 2487
2488 /* issue a Diagnostic Control command with an 2488 /* issue a Diagnostic Control command with an
2489 * Inhibit Write subcommand */ 2489 * Inhibit Write subcommand */
2490 2490
2491 switch (sense[25]) { 2491 switch (sense[25]) {
@@ -2535,14 +2535,14 @@ dasd_3990_erp_further_erp(struct dasd_ccw_req *erp)
2535} /* end dasd_3990_erp_further_erp */ 2535} /* end dasd_3990_erp_further_erp */
2536 2536
2537/* 2537/*
2538 * DASD_3990_ERP_HANDLE_MATCH_ERP 2538 * DASD_3990_ERP_HANDLE_MATCH_ERP
2539 * 2539 *
2540 * DESCRIPTION 2540 * DESCRIPTION
2541 * An error occurred again and an ERP has been detected which is already 2541 * An error occurred again and an ERP has been detected which is already
2542 * used to handle this error (e.g. retries). 2542 * used to handle this error (e.g. retries).
2543 * All prior ERP's are asumed to be successful and therefore removed 2543 * All prior ERP's are asumed to be successful and therefore removed
2544 * from queue. 2544 * from queue.
2545 * If retry counter of matching erp is already 0, it is checked if further 2545 * If retry counter of matching erp is already 0, it is checked if further
2546 * action is needed (besides retry) or if the ERP has failed. 2546 * action is needed (besides retry) or if the ERP has failed.
2547 * 2547 *
2548 * PARAMETER 2548 * PARAMETER
@@ -2631,7 +2631,7 @@ dasd_3990_erp_handle_match_erp(struct dasd_ccw_req *erp_head,
2631 * erp erp-pointer to the head of the ERP action chain. 2631 * erp erp-pointer to the head of the ERP action chain.
2632 * This means: 2632 * This means:
2633 * - either a ptr to an additional ERP cqr or 2633 * - either a ptr to an additional ERP cqr or
2634 * - the original given cqr (which's status might 2634 * - the original given cqr (which's status might
2635 * be modified) 2635 * be modified)
2636 */ 2636 */
2637struct dasd_ccw_req * 2637struct dasd_ccw_req *
@@ -2723,22 +2723,3 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr)
2723 return erp; 2723 return erp;
2724 2724
2725} /* end dasd_3990_erp_action */ 2725} /* end dasd_3990_erp_action */
2726
2727/*
2728 * Overrides for Emacs so that we follow Linus's tabbing style.
2729 * Emacs will notice this stuff at the end of the file and automatically
2730 * adjust the settings for this buffer only. This must remain at the end
2731 * of the file.
2732 * ---------------------------------------------------------------------------
2733 * Local variables:
2734 * c-indent-level: 4
2735 * c-brace-imaginary-offset: 0
2736 * c-brace-offset: -4
2737 * c-argdecl-indent: 4
2738 * c-label-offset: -4
2739 * c-continued-statement-offset: 4
2740 * c-continued-brace-offset: 0
2741 * indent-tabs-mode: 1
2742 * tab-width: 8
2743 * End:
2744 */
diff --git a/drivers/s390/block/dasd_9336_erp.c b/drivers/s390/block/dasd_9336_erp.c
index dc861446d056..6e082688475a 100644
--- a/drivers/s390/block/dasd_9336_erp.c
+++ b/drivers/s390/block/dasd_9336_erp.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * File...........: linux/drivers/s390/block/dasd_9336_erp.c 2 * File...........: linux/drivers/s390/block/dasd_9336_erp.c
3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4 * Bugreports.to..: <Linux390@de.ibm.com> 4 * Bugreports.to..: <Linux390@de.ibm.com>
@@ -12,10 +12,10 @@
12 12
13 13
14/* 14/*
15 * DASD_9336_ERP_EXAMINE 15 * DASD_9336_ERP_EXAMINE
16 * 16 *
17 * DESCRIPTION 17 * DESCRIPTION
18 * Checks only for fatal/no/recover error. 18 * Checks only for fatal/no/recover error.
19 * A detailed examination of the sense data is done later outside 19 * A detailed examination of the sense data is done later outside
20 * the interrupt handler. 20 * the interrupt handler.
21 * 21 *
@@ -23,7 +23,7 @@
23 * 'Chapter 7. 9336 Sense Data'. 23 * 'Chapter 7. 9336 Sense Data'.
24 * 24 *
25 * RETURN VALUES 25 * RETURN VALUES
26 * dasd_era_none no error 26 * dasd_era_none no error
27 * dasd_era_fatal for all fatal (unrecoverable errors) 27 * dasd_era_fatal for all fatal (unrecoverable errors)
28 * dasd_era_recover for all others. 28 * dasd_era_recover for all others.
29 */ 29 */
@@ -39,22 +39,3 @@ dasd_9336_erp_examine(struct dasd_ccw_req * cqr, struct irb * irb)
39 return dasd_era_recover; 39 return dasd_era_recover;
40 40
41} /* END dasd_9336_erp_examine */ 41} /* END dasd_9336_erp_examine */
42
43/*
44 * Overrides for Emacs so that we follow Linus's tabbing style.
45 * Emacs will notice this stuff at the end of the file and automatically
46 * adjust the settings for this buffer only. This must remain at the end
47 * of the file.
48 * ---------------------------------------------------------------------------
49 * Local variables:
50 * c-indent-level: 4
51 * c-brace-imaginary-offset: 0
52 * c-brace-offset: -4
53 * c-argdecl-indent: 4
54 * c-label-offset: -4
55 * c-continued-statement-offset: 4
56 * c-continued-brace-offset: 0
57 * indent-tabs-mode: 1
58 * tab-width: 8
59 * End:
60 */
diff --git a/drivers/s390/block/dasd_9343_erp.c b/drivers/s390/block/dasd_9343_erp.c
index 4a5b79569aaa..ddecb9808ed4 100644
--- a/drivers/s390/block/dasd_9343_erp.c
+++ b/drivers/s390/block/dasd_9343_erp.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * File...........: linux/drivers/s390/block/dasd_9345_erp.c 2 * File...........: linux/drivers/s390/block/dasd_9345_erp.c
3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4 * Bugreports.to..: <Linux390@de.ibm.com> 4 * Bugreports.to..: <Linux390@de.ibm.com>
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index 216bc4fba199..9e9ae7179602 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -27,7 +27,7 @@
27#include "dasd_int.h" 27#include "dasd_int.h"
28 28
29kmem_cache_t *dasd_page_cache; 29kmem_cache_t *dasd_page_cache;
30EXPORT_SYMBOL(dasd_page_cache); 30EXPORT_SYMBOL_GPL(dasd_page_cache);
31 31
32/* 32/*
33 * dasd_devmap_t is used to store the features and the relation 33 * dasd_devmap_t is used to store the features and the relation
@@ -49,6 +49,20 @@ struct dasd_devmap {
49}; 49};
50 50
51/* 51/*
52 * dasd_servermap is used to store the server_id of all storage servers
53 * accessed by DASD device driver.
54 */
55struct dasd_servermap {
56 struct list_head list;
57 struct server_id {
58 char vendor[4];
59 char serial[15];
60 } sid;
61};
62
63static struct list_head dasd_serverlist;
64
65/*
52 * Parameter parsing functions for dasd= parameter. The syntax is: 66 * Parameter parsing functions for dasd= parameter. The syntax is:
53 * <devno> : (0x)?[0-9a-fA-F]+ 67 * <devno> : (0x)?[0-9a-fA-F]+
54 * <busid> : [0-0a-f]\.[0-9a-f]\.(0x)?[0-9a-fA-F]+ 68 * <busid> : [0-0a-f]\.[0-9a-f]\.(0x)?[0-9a-fA-F]+
@@ -64,6 +78,8 @@ struct dasd_devmap {
64 78
65int dasd_probeonly = 0; /* is true, when probeonly mode is active */ 79int dasd_probeonly = 0; /* is true, when probeonly mode is active */
66int dasd_autodetect = 0; /* is true, when autodetection is active */ 80int dasd_autodetect = 0; /* is true, when autodetection is active */
81int dasd_nopav = 0; /* is true, when PAV is disabled */
82EXPORT_SYMBOL_GPL(dasd_nopav);
67 83
68/* 84/*
69 * char *dasd[] is intended to hold the ranges supplied by the dasd= statement 85 * char *dasd[] is intended to hold the ranges supplied by the dasd= statement
@@ -123,7 +139,7 @@ static inline int
123dasd_busid(char **str, int *id0, int *id1, int *devno) 139dasd_busid(char **str, int *id0, int *id1, int *devno)
124{ 140{
125 int val, old_style; 141 int val, old_style;
126 142
127 /* check for leading '0x' */ 143 /* check for leading '0x' */
128 old_style = 0; 144 old_style = 0;
129 if ((*str)[0] == '0' && (*str)[1] == 'x') { 145 if ((*str)[0] == '0' && (*str)[1] == 'x') {
@@ -179,7 +195,7 @@ dasd_feature_list(char *str, char **endp)
179 features = 0; 195 features = 0;
180 196
181 while (1) { 197 while (1) {
182 for (len = 0; 198 for (len = 0;
183 str[len] && str[len] != ':' && str[len] != ')'; len++); 199 str[len] && str[len] != ':' && str[len] != ')'; len++);
184 if (len == 2 && !strncmp(str, "ro", 2)) 200 if (len == 2 && !strncmp(str, "ro", 2))
185 features |= DASD_FEATURE_READONLY; 201 features |= DASD_FEATURE_READONLY;
@@ -228,19 +244,24 @@ dasd_parse_keyword( char *parsestring ) {
228 length = strlen(parsestring); 244 length = strlen(parsestring);
229 residual_str = parsestring + length; 245 residual_str = parsestring + length;
230 } 246 }
231 if (strncmp ("autodetect", parsestring, length) == 0) { 247 if (strncmp("autodetect", parsestring, length) == 0) {
232 dasd_autodetect = 1; 248 dasd_autodetect = 1;
233 MESSAGE (KERN_INFO, "%s", 249 MESSAGE (KERN_INFO, "%s",
234 "turning to autodetection mode"); 250 "turning to autodetection mode");
235 return residual_str; 251 return residual_str;
236 } 252 }
237 if (strncmp ("probeonly", parsestring, length) == 0) { 253 if (strncmp("probeonly", parsestring, length) == 0) {
238 dasd_probeonly = 1; 254 dasd_probeonly = 1;
239 MESSAGE(KERN_INFO, "%s", 255 MESSAGE(KERN_INFO, "%s",
240 "turning to probeonly mode"); 256 "turning to probeonly mode");
241 return residual_str; 257 return residual_str;
242 } 258 }
243 if (strncmp ("fixedbuffers", parsestring, length) == 0) { 259 if (strncmp("nopav", parsestring, length) == 0) {
260 dasd_nopav = 1;
261 MESSAGE(KERN_INFO, "%s", "disable PAV mode");
262 return residual_str;
263 }
264 if (strncmp("fixedbuffers", parsestring, length) == 0) {
244 if (dasd_page_cache) 265 if (dasd_page_cache)
245 return residual_str; 266 return residual_str;
246 dasd_page_cache = 267 dasd_page_cache =
@@ -294,6 +315,8 @@ dasd_parse_range( char *parsestring ) {
294 features = dasd_feature_list(str, &str); 315 features = dasd_feature_list(str, &str);
295 if (features < 0) 316 if (features < 0)
296 return ERR_PTR(-EINVAL); 317 return ERR_PTR(-EINVAL);
318 /* each device in dasd= parameter should be set initially online */
319 features |= DASD_FEATURE_INITIAL_ONLINE;
297 while (from <= to) { 320 while (from <= to) {
298 sprintf(bus_id, "%01x.%01x.%04x", 321 sprintf(bus_id, "%01x.%01x.%04x",
299 from_id0, from_id1, from++); 322 from_id0, from_id1, from++);
@@ -359,7 +382,7 @@ dasd_parse(void)
359 * Add a devmap for the device specified by busid. It is possible that 382 * Add a devmap for the device specified by busid. It is possible that
360 * the devmap already exists (dasd= parameter). The order of the devices 383 * the devmap already exists (dasd= parameter). The order of the devices
361 * added through this function will define the kdevs for the individual 384 * added through this function will define the kdevs for the individual
362 * devices. 385 * devices.
363 */ 386 */
364static struct dasd_devmap * 387static struct dasd_devmap *
365dasd_add_busid(char *bus_id, int features) 388dasd_add_busid(char *bus_id, int features)
@@ -368,7 +391,7 @@ dasd_add_busid(char *bus_id, int features)
368 int hash; 391 int hash;
369 392
370 new = (struct dasd_devmap *) 393 new = (struct dasd_devmap *)
371 kmalloc(sizeof(struct dasd_devmap), GFP_KERNEL); 394 kzalloc(sizeof(struct dasd_devmap), GFP_KERNEL);
372 if (!new) 395 if (!new)
373 return ERR_PTR(-ENOMEM); 396 return ERR_PTR(-ENOMEM);
374 spin_lock(&dasd_devmap_lock); 397 spin_lock(&dasd_devmap_lock);
@@ -630,7 +653,8 @@ dasd_ro_show(struct device *dev, struct device_attribute *attr, char *buf)
630} 653}
631 654
632static ssize_t 655static ssize_t
633dasd_ro_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 656dasd_ro_store(struct device *dev, struct device_attribute *attr,
657 const char *buf, size_t count)
634{ 658{
635 struct dasd_devmap *devmap; 659 struct dasd_devmap *devmap;
636 int ro_flag; 660 int ro_flag;
@@ -658,7 +682,7 @@ static DEVICE_ATTR(readonly, 0644, dasd_ro_show, dasd_ro_store);
658 * use_diag controls whether the driver should use diag rather than ssch 682 * use_diag controls whether the driver should use diag rather than ssch
659 * to talk to the device 683 * to talk to the device
660 */ 684 */
661static ssize_t 685static ssize_t
662dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf) 686dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf)
663{ 687{
664 struct dasd_devmap *devmap; 688 struct dasd_devmap *devmap;
@@ -673,7 +697,8 @@ dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf)
673} 697}
674 698
675static ssize_t 699static ssize_t
676dasd_use_diag_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 700dasd_use_diag_store(struct device *dev, struct device_attribute *attr,
701 const char *buf, size_t count)
677{ 702{
678 struct dasd_devmap *devmap; 703 struct dasd_devmap *devmap;
679 ssize_t rc; 704 ssize_t rc;
@@ -697,11 +722,11 @@ dasd_use_diag_store(struct device *dev, struct device_attribute *attr, const cha
697 return rc; 722 return rc;
698} 723}
699 724
700static 725static DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store);
701DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store);
702 726
703static ssize_t 727static ssize_t
704dasd_discipline_show(struct device *dev, struct device_attribute *attr, char *buf) 728dasd_discipline_show(struct device *dev, struct device_attribute *attr,
729 char *buf)
705{ 730{
706 struct dasd_devmap *devmap; 731 struct dasd_devmap *devmap;
707 char *dname; 732 char *dname;
@@ -834,6 +859,38 @@ static struct attribute_group dasd_attr_group = {
834 .attrs = dasd_attrs, 859 .attrs = dasd_attrs,
835}; 860};
836 861
862/*
863 * Check if the related storage server is already contained in the
864 * dasd_serverlist. If server is not contained, create new entry.
865 * Return 0 if server was already in serverlist,
866 * 1 if the server was added successfully
867 * <0 in case of error.
868 */
869static int
870dasd_add_server(struct dasd_uid *uid)
871{
872 struct dasd_servermap *new, *tmp;
873
874 /* check if server is already contained */
875 list_for_each_entry(tmp, &dasd_serverlist, list)
876 // normale cmp?
877 if (strncmp(tmp->sid.vendor, uid->vendor,
878 sizeof(tmp->sid.vendor)) == 0
879 && strncmp(tmp->sid.serial, uid->serial,
880 sizeof(tmp->sid.serial)) == 0)
881 return 0;
882
883 new = (struct dasd_servermap *)
884 kzalloc(sizeof(struct dasd_servermap), GFP_KERNEL);
885 if (!new)
886 return -ENOMEM;
887
888 strncpy(new->sid.vendor, uid->vendor, sizeof(new->sid.vendor));
889 strncpy(new->sid.serial, uid->serial, sizeof(new->sid.serial));
890 list_add(&new->list, &dasd_serverlist);
891 return 1;
892}
893
837 894
838/* 895/*
839 * Return copy of the device unique identifier. 896 * Return copy of the device unique identifier.
@@ -854,21 +911,26 @@ dasd_get_uid(struct ccw_device *cdev, struct dasd_uid *uid)
854 911
855/* 912/*
856 * Register the given device unique identifier into devmap struct. 913 * Register the given device unique identifier into devmap struct.
914 * Return 0 if server was already in serverlist,
915 * 1 if the server was added successful
916 * <0 in case of error.
857 */ 917 */
858int 918int
859dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid) 919dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid)
860{ 920{
861 struct dasd_devmap *devmap; 921 struct dasd_devmap *devmap;
922 int rc;
862 923
863 devmap = dasd_find_busid(cdev->dev.bus_id); 924 devmap = dasd_find_busid(cdev->dev.bus_id);
864 if (IS_ERR(devmap)) 925 if (IS_ERR(devmap))
865 return PTR_ERR(devmap); 926 return PTR_ERR(devmap);
866 spin_lock(&dasd_devmap_lock); 927 spin_lock(&dasd_devmap_lock);
867 devmap->uid = *uid; 928 devmap->uid = *uid;
929 rc = dasd_add_server(uid);
868 spin_unlock(&dasd_devmap_lock); 930 spin_unlock(&dasd_devmap_lock);
869 return 0; 931 return rc;
870} 932}
871EXPORT_SYMBOL(dasd_set_uid); 933EXPORT_SYMBOL_GPL(dasd_set_uid);
872 934
873/* 935/*
874 * Return value of the specified feature. 936 * Return value of the specified feature.
@@ -880,7 +942,7 @@ dasd_get_feature(struct ccw_device *cdev, int feature)
880 942
881 devmap = dasd_find_busid(cdev->dev.bus_id); 943 devmap = dasd_find_busid(cdev->dev.bus_id);
882 if (IS_ERR(devmap)) 944 if (IS_ERR(devmap))
883 return (int) PTR_ERR(devmap); 945 return PTR_ERR(devmap);
884 946
885 return ((devmap->features & feature) != 0); 947 return ((devmap->features & feature) != 0);
886} 948}
@@ -896,7 +958,7 @@ dasd_set_feature(struct ccw_device *cdev, int feature, int flag)
896 958
897 devmap = dasd_find_busid(cdev->dev.bus_id); 959 devmap = dasd_find_busid(cdev->dev.bus_id);
898 if (IS_ERR(devmap)) 960 if (IS_ERR(devmap))
899 return (int) PTR_ERR(devmap); 961 return PTR_ERR(devmap);
900 962
901 spin_lock(&dasd_devmap_lock); 963 spin_lock(&dasd_devmap_lock);
902 if (flag) 964 if (flag)
@@ -932,8 +994,10 @@ dasd_devmap_init(void)
932 dasd_max_devindex = 0; 994 dasd_max_devindex = 0;
933 for (i = 0; i < 256; i++) 995 for (i = 0; i < 256; i++)
934 INIT_LIST_HEAD(&dasd_hashlists[i]); 996 INIT_LIST_HEAD(&dasd_hashlists[i]);
935 return 0;
936 997
998 /* Initialize servermap structure. */
999 INIT_LIST_HEAD(&dasd_serverlist);
1000 return 0;
937} 1001}
938 1002
939void 1003void
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index 3f9d704d2657..4002f6c1c1b3 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * File...........: linux/drivers/s390/block/dasd_diag.c 2 * File...........: linux/drivers/s390/block/dasd_diag.c
3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4 * Based on.......: linux/drivers/s390/block/mdisk.c 4 * Based on.......: linux/drivers/s390/block/mdisk.c
@@ -336,7 +336,7 @@ dasd_diag_check_device(struct dasd_device *device)
336 336
337 private = (struct dasd_diag_private *) device->private; 337 private = (struct dasd_diag_private *) device->private;
338 if (private == NULL) { 338 if (private == NULL) {
339 private = kmalloc(sizeof(struct dasd_diag_private),GFP_KERNEL); 339 private = kzalloc(sizeof(struct dasd_diag_private),GFP_KERNEL);
340 if (private == NULL) { 340 if (private == NULL) {
341 DEV_MESSAGE(KERN_WARNING, device, "%s", 341 DEV_MESSAGE(KERN_WARNING, device, "%s",
342 "memory allocation failed for private data"); 342 "memory allocation failed for private data");
@@ -527,7 +527,7 @@ dasd_diag_build_cp(struct dasd_device * device, struct request *req)
527 datasize, device); 527 datasize, device);
528 if (IS_ERR(cqr)) 528 if (IS_ERR(cqr))
529 return cqr; 529 return cqr;
530 530
531 dreq = (struct dasd_diag_req *) cqr->data; 531 dreq = (struct dasd_diag_req *) cqr->data;
532 dreq->block_count = count; 532 dreq->block_count = count;
533 dbio = dreq->bio; 533 dbio = dreq->bio;
diff --git a/drivers/s390/block/dasd_diag.h b/drivers/s390/block/dasd_diag.h
index 38a4e55f8953..b8c78267ff3e 100644
--- a/drivers/s390/block/dasd_diag.h
+++ b/drivers/s390/block/dasd_diag.h
@@ -1,4 +1,4 @@
1/* 1/*
2 * File...........: linux/drivers/s390/block/dasd_diag.h 2 * File...........: linux/drivers/s390/block/dasd_diag.h
3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4 * Based on.......: linux/drivers/s390/block/mdisk.h 4 * Based on.......: linux/drivers/s390/block/mdisk.h
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 7d5a6cee4bd8..0dfab30e8089 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * File...........: linux/drivers/s390/block/dasd_eckd.c 2 * File...........: linux/drivers/s390/block/dasd_eckd.c
3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4 * Horst Hummel <Horst.Hummel@de.ibm.com> 4 * Horst Hummel <Horst.Hummel@de.ibm.com>
5 * Carsten Otte <Cotte@de.ibm.com> 5 * Carsten Otte <Cotte@de.ibm.com>
6 * Martin Schwidefsky <schwidefsky@de.ibm.com> 6 * Martin Schwidefsky <schwidefsky@de.ibm.com>
7 * Bugreports.to..: <Linux390@de.ibm.com> 7 * Bugreports.to..: <Linux390@de.ibm.com>
@@ -24,6 +24,7 @@
24#include <asm/io.h> 24#include <asm/io.h>
25#include <asm/todclk.h> 25#include <asm/todclk.h>
26#include <asm/uaccess.h> 26#include <asm/uaccess.h>
27#include <asm/cio.h>
27#include <asm/ccwdev.h> 28#include <asm/ccwdev.h>
28 29
29#include "dasd_int.h" 30#include "dasd_int.h"
@@ -89,17 +90,22 @@ dasd_eckd_probe (struct ccw_device *cdev)
89{ 90{
90 int ret; 91 int ret;
91 92
92 ret = dasd_generic_probe (cdev, &dasd_eckd_discipline); 93 /* set ECKD specific ccw-device options */
93 if (ret) 94 ret = ccw_device_set_options(cdev, CCWDEV_ALLOW_FORCE);
95 if (ret) {
96 printk(KERN_WARNING
97 "dasd_eckd_probe: could not set ccw-device options "
98 "for %s\n", cdev->dev.bus_id);
94 return ret; 99 return ret;
95 ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP | CCWDEV_ALLOW_FORCE); 100 }
96 return 0; 101 ret = dasd_generic_probe(cdev, &dasd_eckd_discipline);
102 return ret;
97} 103}
98 104
99static int 105static int
100dasd_eckd_set_online(struct ccw_device *cdev) 106dasd_eckd_set_online(struct ccw_device *cdev)
101{ 107{
102 return dasd_generic_set_online (cdev, &dasd_eckd_discipline); 108 return dasd_generic_set_online(cdev, &dasd_eckd_discipline);
103} 109}
104 110
105static struct ccw_driver dasd_eckd_driver = { 111static struct ccw_driver dasd_eckd_driver = {
@@ -210,14 +216,14 @@ check_XRC (struct ccw1 *de_ccw,
210 216
211 /* switch on System Time Stamp - needed for XRC Support */ 217 /* switch on System Time Stamp - needed for XRC Support */
212 if (private->rdc_data.facilities.XRC_supported) { 218 if (private->rdc_data.facilities.XRC_supported) {
213 219
214 data->ga_extended |= 0x08; /* switch on 'Time Stamp Valid' */ 220 data->ga_extended |= 0x08; /* switch on 'Time Stamp Valid' */
215 data->ga_extended |= 0x02; /* switch on 'Extended Parameter' */ 221 data->ga_extended |= 0x02; /* switch on 'Extended Parameter' */
216 222
217 data->ep_sys_time = get_clock (); 223 data->ep_sys_time = get_clock ();
218 224
219 de_ccw->count = sizeof (struct DE_eckd_data); 225 de_ccw->count = sizeof (struct DE_eckd_data);
220 de_ccw->flags |= CCW_FLAG_SLI; 226 de_ccw->flags |= CCW_FLAG_SLI;
221 } 227 }
222 228
223 return; 229 return;
@@ -296,8 +302,8 @@ define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk,
296 /* check for sequential prestage - enhance cylinder range */ 302 /* check for sequential prestage - enhance cylinder range */
297 if (data->attributes.operation == DASD_SEQ_PRESTAGE || 303 if (data->attributes.operation == DASD_SEQ_PRESTAGE ||
298 data->attributes.operation == DASD_SEQ_ACCESS) { 304 data->attributes.operation == DASD_SEQ_ACCESS) {
299 305
300 if (end.cyl + private->attrib.nr_cyl < geo.cyl) 306 if (end.cyl + private->attrib.nr_cyl < geo.cyl)
301 end.cyl += private->attrib.nr_cyl; 307 end.cyl += private->attrib.nr_cyl;
302 else 308 else
303 end.cyl = (geo.cyl - 1); 309 end.cyl = (geo.cyl - 1);
@@ -317,7 +323,7 @@ locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, int trk,
317 struct dasd_eckd_private *private; 323 struct dasd_eckd_private *private;
318 int sector; 324 int sector;
319 int dn, d; 325 int dn, d;
320 326
321 private = (struct dasd_eckd_private *) device->private; 327 private = (struct dasd_eckd_private *) device->private;
322 328
323 DBF_DEV_EVENT(DBF_INFO, device, 329 DBF_DEV_EVENT(DBF_INFO, device,
@@ -541,6 +547,86 @@ dasd_eckd_read_conf(struct dasd_device *device)
541} 547}
542 548
543/* 549/*
550 * Build CP for Perform Subsystem Function - SSC.
551 */
552struct dasd_ccw_req *
553dasd_eckd_build_psf_ssc(struct dasd_device *device)
554{
555 struct dasd_ccw_req *cqr;
556 struct dasd_psf_ssc_data *psf_ssc_data;
557 struct ccw1 *ccw;
558
559 cqr = dasd_smalloc_request("ECKD", 1 /* PSF */ ,
560 sizeof(struct dasd_psf_ssc_data),
561 device);
562
563 if (IS_ERR(cqr)) {
564 DEV_MESSAGE(KERN_WARNING, device, "%s",
565 "Could not allocate PSF-SSC request");
566 return cqr;
567 }
568 psf_ssc_data = (struct dasd_psf_ssc_data *)cqr->data;
569 psf_ssc_data->order = PSF_ORDER_SSC;
570 psf_ssc_data->suborder = 0x08;
571
572 ccw = cqr->cpaddr;
573 ccw->cmd_code = DASD_ECKD_CCW_PSF;
574 ccw->cda = (__u32)(addr_t)psf_ssc_data;
575 ccw->count = 66;
576
577 cqr->device = device;
578 cqr->expires = 10*HZ;
579 cqr->buildclk = get_clock();
580 cqr->status = DASD_CQR_FILLED;
581 return cqr;
582}
583
584/*
585 * Perform Subsystem Function.
586 * It is necessary to trigger CIO for channel revalidation since this
587 * call might change behaviour of DASD devices.
588 */
589static int
590dasd_eckd_psf_ssc(struct dasd_device *device)
591{
592 struct dasd_ccw_req *cqr;
593 int rc;
594
595 cqr = dasd_eckd_build_psf_ssc(device);
596 if (IS_ERR(cqr))
597 return PTR_ERR(cqr);
598
599 rc = dasd_sleep_on(cqr);
600 if (!rc)
601 /* trigger CIO to reprobe devices */
602 css_schedule_reprobe();
603 dasd_sfree_request(cqr, cqr->device);
604 return rc;
605}
606
607/*
608 * Valide storage server of current device.
609 */
610static int
611dasd_eckd_validate_server(struct dasd_device *device)
612{
613 int rc;
614
615 /* Currently PAV is the only reason to 'validate' server on LPAR */
616 if (dasd_nopav || MACHINE_IS_VM)
617 return 0;
618
619 rc = dasd_eckd_psf_ssc(device);
620 if (rc)
621 /* may be requested feature is not available on server,
622 * therefore just report error and go ahead */
623 DEV_MESSAGE(KERN_INFO, device,
624 "Perform Subsystem Function returned rc=%d", rc);
625 /* RE-Read Configuration Data */
626 return dasd_eckd_read_conf(device);
627}
628
629/*
544 * Check device characteristics. 630 * Check device characteristics.
545 * If the device is accessible using ECKD discipline, the device is enabled. 631 * If the device is accessible using ECKD discipline, the device is enabled.
546 */ 632 */
@@ -554,7 +640,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
554 640
555 private = (struct dasd_eckd_private *) device->private; 641 private = (struct dasd_eckd_private *) device->private;
556 if (private == NULL) { 642 if (private == NULL) {
557 private = kmalloc(sizeof(struct dasd_eckd_private), 643 private = kzalloc(sizeof(struct dasd_eckd_private),
558 GFP_KERNEL | GFP_DMA); 644 GFP_KERNEL | GFP_DMA);
559 if (private == NULL) { 645 if (private == NULL) {
560 DEV_MESSAGE(KERN_WARNING, device, "%s", 646 DEV_MESSAGE(KERN_WARNING, device, "%s",
@@ -562,7 +648,6 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
562 "data"); 648 "data");
563 return -ENOMEM; 649 return -ENOMEM;
564 } 650 }
565 memset(private, 0, sizeof(struct dasd_eckd_private));
566 device->private = (void *) private; 651 device->private = (void *) private;
567 } 652 }
568 /* Invalidate status of initial analysis. */ 653 /* Invalidate status of initial analysis. */
@@ -571,16 +656,29 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
571 private->attrib.operation = DASD_NORMAL_CACHE; 656 private->attrib.operation = DASD_NORMAL_CACHE;
572 private->attrib.nr_cyl = 0; 657 private->attrib.nr_cyl = 0;
573 658
659 /* Read Configuration Data */
660 rc = dasd_eckd_read_conf(device);
661 if (rc)
662 return rc;
663
664 /* Generate device unique id and register in devmap */
665 rc = dasd_eckd_generate_uid(device, &uid);
666 if (rc)
667 return rc;
668 rc = dasd_set_uid(device->cdev, &uid);
669 if (rc == 1) /* new server found */
670 rc = dasd_eckd_validate_server(device);
671 if (rc)
672 return rc;
673
574 /* Read Device Characteristics */ 674 /* Read Device Characteristics */
575 rdc_data = (void *) &(private->rdc_data); 675 rdc_data = (void *) &(private->rdc_data);
576 memset(rdc_data, 0, sizeof(rdc_data)); 676 memset(rdc_data, 0, sizeof(rdc_data));
577 rc = read_dev_chars(device->cdev, &rdc_data, 64); 677 rc = read_dev_chars(device->cdev, &rdc_data, 64);
578 if (rc) { 678 if (rc)
579 DEV_MESSAGE(KERN_WARNING, device, 679 DEV_MESSAGE(KERN_WARNING, device,
580 "Read device characteristics returned error %d", 680 "Read device characteristics returned "
581 rc); 681 "rc=%d", rc);
582 return rc;
583 }
584 682
585 DEV_MESSAGE(KERN_INFO, device, 683 DEV_MESSAGE(KERN_INFO, device,
586 "%04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d", 684 "%04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d",
@@ -591,19 +689,6 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
591 private->rdc_data.no_cyl, 689 private->rdc_data.no_cyl,
592 private->rdc_data.trk_per_cyl, 690 private->rdc_data.trk_per_cyl,
593 private->rdc_data.sec_per_trk); 691 private->rdc_data.sec_per_trk);
594
595 /* Read Configuration Data */
596 rc = dasd_eckd_read_conf (device);
597 if (rc)
598 return rc;
599
600 /* Generate device unique id and register in devmap */
601 rc = dasd_eckd_generate_uid(device, &uid);
602 if (rc)
603 return rc;
604
605 rc = dasd_set_uid(device->cdev, &uid);
606
607 return rc; 692 return rc;
608} 693}
609 694
@@ -773,7 +858,7 @@ dasd_eckd_end_analysis(struct dasd_device *device)
773 ((private->rdc_data.no_cyl * 858 ((private->rdc_data.no_cyl *
774 private->rdc_data.trk_per_cyl * 859 private->rdc_data.trk_per_cyl *
775 blk_per_trk * (device->bp_block >> 9)) >> 1), 860 blk_per_trk * (device->bp_block >> 9)) >> 1),
776 ((blk_per_trk * device->bp_block) >> 10), 861 ((blk_per_trk * device->bp_block) >> 10),
777 private->uses_cdl ? 862 private->uses_cdl ?
778 "compatible disk layout" : "linux disk layout"); 863 "compatible disk layout" : "linux disk layout");
779 864
@@ -970,7 +1055,7 @@ dasd_eckd_format_device(struct dasd_device * device,
970 if (i < 3) { 1055 if (i < 3) {
971 ect->kl = 4; 1056 ect->kl = 4;
972 ect->dl = sizes_trk0[i] - 4; 1057 ect->dl = sizes_trk0[i] - 4;
973 } 1058 }
974 } 1059 }
975 if ((fdata->intensity & 0x08) && 1060 if ((fdata->intensity & 0x08) &&
976 fdata->start_unit == 1) { 1061 fdata->start_unit == 1) {
@@ -1270,7 +1355,7 @@ dasd_eckd_fill_info(struct dasd_device * device,
1270 1355
1271/* 1356/*
1272 * Release device ioctl. 1357 * Release device ioctl.
1273 * Buils a channel programm to releases a prior reserved 1358 * Buils a channel programm to releases a prior reserved
1274 * (see dasd_eckd_reserve) device. 1359 * (see dasd_eckd_reserve) device.
1275 */ 1360 */
1276static int 1361static int
@@ -1310,8 +1395,8 @@ dasd_eckd_release(struct dasd_device *device)
1310/* 1395/*
1311 * Reserve device ioctl. 1396 * Reserve device ioctl.
1312 * Options are set to 'synchronous wait for interrupt' and 1397 * Options are set to 'synchronous wait for interrupt' and
1313 * 'timeout the request'. This leads to a terminate IO if 1398 * 'timeout the request'. This leads to a terminate IO if
1314 * the interrupt is outstanding for a certain time. 1399 * the interrupt is outstanding for a certain time.
1315 */ 1400 */
1316static int 1401static int
1317dasd_eckd_reserve(struct dasd_device *device) 1402dasd_eckd_reserve(struct dasd_device *device)
@@ -1349,7 +1434,7 @@ dasd_eckd_reserve(struct dasd_device *device)
1349 1434
1350/* 1435/*
1351 * Steal lock ioctl - unconditional reserve device. 1436 * Steal lock ioctl - unconditional reserve device.
1352 * Buils a channel programm to break a device's reservation. 1437 * Buils a channel programm to break a device's reservation.
1353 * (unconditional reserve) 1438 * (unconditional reserve)
1354 */ 1439 */
1355static int 1440static int
@@ -1522,6 +1607,40 @@ dasd_eckd_ioctl(struct dasd_device *device, unsigned int cmd, void __user *argp)
1522} 1607}
1523 1608
1524/* 1609/*
1610 * Dump the range of CCWs into 'page' buffer
1611 * and return number of printed chars.
1612 */
1613static inline int
1614dasd_eckd_dump_ccw_range(struct ccw1 *from, struct ccw1 *to, char *page)
1615{
1616 int len, count;
1617 char *datap;
1618
1619 len = 0;
1620 while (from <= to) {
1621 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
1622 " CCW %p: %08X %08X DAT:",
1623 from, ((int *) from)[0], ((int *) from)[1]);
1624
1625 /* get pointer to data (consider IDALs) */
1626 if (from->flags & CCW_FLAG_IDA)
1627 datap = (char *) *((addr_t *) (addr_t) from->cda);
1628 else
1629 datap = (char *) ((addr_t) from->cda);
1630
1631 /* dump data (max 32 bytes) */
1632 for (count = 0; count < from->count && count < 32; count++) {
1633 if (count % 8 == 0) len += sprintf(page + len, " ");
1634 if (count % 4 == 0) len += sprintf(page + len, " ");
1635 len += sprintf(page + len, "%02x", datap[count]);
1636 }
1637 len += sprintf(page + len, "\n");
1638 from++;
1639 }
1640 return len;
1641}
1642
1643/*
1525 * Print sense data and related channel program. 1644 * Print sense data and related channel program.
1526 * Parts are printed because printk buffer is only 1024 bytes. 1645 * Parts are printed because printk buffer is only 1024 bytes.
1527 */ 1646 */
@@ -1530,8 +1649,8 @@ dasd_eckd_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
1530 struct irb *irb) 1649 struct irb *irb)
1531{ 1650{
1532 char *page; 1651 char *page;
1533 struct ccw1 *act, *end, *last; 1652 struct ccw1 *first, *last, *fail, *from, *to;
1534 int len, sl, sct, count; 1653 int len, sl, sct;
1535 1654
1536 page = (char *) get_zeroed_page(GFP_ATOMIC); 1655 page = (char *) get_zeroed_page(GFP_ATOMIC);
1537 if (page == NULL) { 1656 if (page == NULL) {
@@ -1539,7 +1658,8 @@ dasd_eckd_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
1539 "No memory to dump sense data"); 1658 "No memory to dump sense data");
1540 return; 1659 return;
1541 } 1660 }
1542 len = sprintf(page, KERN_ERR PRINTK_HEADER 1661 /* dump the sense data */
1662 len = sprintf(page, KERN_ERR PRINTK_HEADER
1543 " I/O status report for device %s:\n", 1663 " I/O status report for device %s:\n",
1544 device->cdev->dev.bus_id); 1664 device->cdev->dev.bus_id);
1545 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 1665 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
@@ -1564,87 +1684,55 @@ dasd_eckd_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
1564 1684
1565 if (irb->ecw[27] & DASD_SENSE_BIT_0) { 1685 if (irb->ecw[27] & DASD_SENSE_BIT_0) {
1566 /* 24 Byte Sense Data */ 1686 /* 24 Byte Sense Data */
1567 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 1687 sprintf(page + len, KERN_ERR PRINTK_HEADER
1568 " 24 Byte: %x MSG %x, " 1688 " 24 Byte: %x MSG %x, "
1569 "%s MSGb to SYSOP\n", 1689 "%s MSGb to SYSOP\n",
1570 irb->ecw[7] >> 4, irb->ecw[7] & 0x0f, 1690 irb->ecw[7] >> 4, irb->ecw[7] & 0x0f,
1571 irb->ecw[1] & 0x10 ? "" : "no"); 1691 irb->ecw[1] & 0x10 ? "" : "no");
1572 } else { 1692 } else {
1573 /* 32 Byte Sense Data */ 1693 /* 32 Byte Sense Data */
1574 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 1694 sprintf(page + len, KERN_ERR PRINTK_HEADER
1575 " 32 Byte: Format: %x " 1695 " 32 Byte: Format: %x "
1576 "Exception class %x\n", 1696 "Exception class %x\n",
1577 irb->ecw[6] & 0x0f, irb->ecw[22] >> 4); 1697 irb->ecw[6] & 0x0f, irb->ecw[22] >> 4);
1578 } 1698 }
1579 } else { 1699 } else {
1580 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 1700 sprintf(page + len, KERN_ERR PRINTK_HEADER
1581 " SORRY - NO VALID SENSE AVAILABLE\n"); 1701 " SORRY - NO VALID SENSE AVAILABLE\n");
1582 } 1702 }
1583 MESSAGE_LOG(KERN_ERR, "%s", 1703 printk("%s", page);
1584 page + sizeof(KERN_ERR PRINTK_HEADER)); 1704
1585 1705 /* dump the Channel Program (max 140 Bytes per line) */
1586 /* dump the Channel Program */ 1706 /* Count CCW and print first CCWs (maximum 1024 % 140 = 7) */
1587 /* print first CCWs (maximum 8) */ 1707 first = req->cpaddr;
1588 act = req->cpaddr; 1708 for (last = first; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++);
1589 for (last = act; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++); 1709 to = min(first + 6, last);
1590 end = min(act + 8, last); 1710 len = sprintf(page, KERN_ERR PRINTK_HEADER
1591 len = sprintf(page, KERN_ERR PRINTK_HEADER
1592 " Related CP in req: %p\n", req); 1711 " Related CP in req: %p\n", req);
1593 while (act <= end) { 1712 dasd_eckd_dump_ccw_range(first, to, page + len);
1594 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 1713 printk("%s", page);
1595 " CCW %p: %08X %08X DAT:",
1596 act, ((int *) act)[0], ((int *) act)[1]);
1597 for (count = 0; count < 32 && count < act->count;
1598 count += sizeof(int))
1599 len += sprintf(page + len, " %08X",
1600 ((int *) (addr_t) act->cda)
1601 [(count>>2)]);
1602 len += sprintf(page + len, "\n");
1603 act++;
1604 }
1605 MESSAGE_LOG(KERN_ERR, "%s",
1606 page + sizeof(KERN_ERR PRINTK_HEADER));
1607 1714
1608 /* print failing CCW area */ 1715 /* print failing CCW area (maximum 4) */
1716 /* scsw->cda is either valid or zero */
1609 len = 0; 1717 len = 0;
1610 if (act < ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2) { 1718 from = ++to;
1611 act = ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2; 1719 fail = (struct ccw1 *)(addr_t) irb->scsw.cpa; /* failing CCW */
1612 len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n"); 1720 if (from < fail - 2) {
1613 } 1721 from = fail - 2; /* there is a gap - print header */
1614 end = min((struct ccw1 *)(addr_t) irb->scsw.cpa + 2, last); 1722 len += sprintf(page, KERN_ERR PRINTK_HEADER "......\n");
1615 while (act <= end) {
1616 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
1617 " CCW %p: %08X %08X DAT:",
1618 act, ((int *) act)[0], ((int *) act)[1]);
1619 for (count = 0; count < 32 && count < act->count;
1620 count += sizeof(int))
1621 len += sprintf(page + len, " %08X",
1622 ((int *) (addr_t) act->cda)
1623 [(count>>2)]);
1624 len += sprintf(page + len, "\n");
1625 act++;
1626 } 1723 }
1724 to = min(fail + 1, last);
1725 len += dasd_eckd_dump_ccw_range(from, to, page + len);
1627 1726
1628 /* print last CCWs */ 1727 /* print last CCWs (maximum 2) */
1629 if (act < last - 2) { 1728 from = max(from, ++to);
1630 act = last - 2; 1729 if (from < last - 1) {
1730 from = last - 1; /* there is a gap - print header */
1631 len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n"); 1731 len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n");
1632 } 1732 }
1633 while (act <= last) { 1733 len += dasd_eckd_dump_ccw_range(from, last, page + len);
1634 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
1635 " CCW %p: %08X %08X DAT:",
1636 act, ((int *) act)[0], ((int *) act)[1]);
1637 for (count = 0; count < 32 && count < act->count;
1638 count += sizeof(int))
1639 len += sprintf(page + len, " %08X",
1640 ((int *) (addr_t) act->cda)
1641 [(count>>2)]);
1642 len += sprintf(page + len, "\n");
1643 act++;
1644 }
1645 if (len > 0) 1734 if (len > 0)
1646 MESSAGE_LOG(KERN_ERR, "%s", 1735 printk("%s", page);
1647 page + sizeof(KERN_ERR PRINTK_HEADER));
1648 free_page((unsigned long) page); 1736 free_page((unsigned long) page);
1649} 1737}
1650 1738
@@ -1685,14 +1773,8 @@ static struct dasd_discipline dasd_eckd_discipline = {
1685static int __init 1773static int __init
1686dasd_eckd_init(void) 1774dasd_eckd_init(void)
1687{ 1775{
1688 int ret;
1689
1690 ASCEBC(dasd_eckd_discipline.ebcname, 4); 1776 ASCEBC(dasd_eckd_discipline.ebcname, 4);
1691 1777 return ccw_driver_register(&dasd_eckd_driver);
1692 ret = ccw_driver_register(&dasd_eckd_driver);
1693 if (!ret)
1694 dasd_generic_auto_online(&dasd_eckd_driver);
1695 return ret;
1696} 1778}
1697 1779
1698static void __exit 1780static void __exit
@@ -1703,22 +1785,3 @@ dasd_eckd_cleanup(void)
1703 1785
1704module_init(dasd_eckd_init); 1786module_init(dasd_eckd_init);
1705module_exit(dasd_eckd_cleanup); 1787module_exit(dasd_eckd_cleanup);
1706
1707/*
1708 * Overrides for Emacs so that we follow Linus's tabbing style.
1709 * Emacs will notice this stuff at the end of the file and automatically
1710 * adjust the settings for this buffer only. This must remain at the end
1711 * of the file.
1712 * ---------------------------------------------------------------------------
1713 * Local variables:
1714 * c-indent-level: 4
1715 * c-brace-imaginary-offset: 0
1716 * c-brace-offset: -4
1717 * c-argdecl-indent: 4
1718 * c-label-offset: -4
1719 * c-continued-statement-offset: 4
1720 * c-continued-brace-offset: 0
1721 * indent-tabs-mode: 1
1722 * tab-width: 8
1723 * End:
1724 */
diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h
index d5734e976e1c..712ff1650134 100644
--- a/drivers/s390/block/dasd_eckd.h
+++ b/drivers/s390/block/dasd_eckd.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * File...........: linux/drivers/s390/block/dasd_eckd.h 2 * File...........: linux/drivers/s390/block/dasd_eckd.h
3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4 * Horst Hummel <Horst.Hummel@de.ibm.com> 4 * Horst Hummel <Horst.Hummel@de.ibm.com>
5 * Bugreports.to..: <Linux390@de.ibm.com> 5 * Bugreports.to..: <Linux390@de.ibm.com>
6 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 6 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
7 * 7 *
@@ -41,9 +41,10 @@
41#define DASD_ECKD_CCW_RESERVE 0xB4 41#define DASD_ECKD_CCW_RESERVE 0xB4
42 42
43/* 43/*
44 *Perform Subsystem Function / Sub-Orders 44 * Perform Subsystem Function / Sub-Orders
45 */ 45 */
46#define PSF_ORDER_PRSSD 0x18 46#define PSF_ORDER_PRSSD 0x18
47#define PSF_ORDER_SSC 0x1D
47 48
48/***************************************************************************** 49/*****************************************************************************
49 * SECTION: Type Definitions 50 * SECTION: Type Definitions
@@ -155,7 +156,7 @@ struct dasd_eckd_characteristics {
155 unsigned char reserved2:4; 156 unsigned char reserved2:4;
156 unsigned char reserved3:8; 157 unsigned char reserved3:8;
157 unsigned char defect_wr:1; 158 unsigned char defect_wr:1;
158 unsigned char XRC_supported:1; 159 unsigned char XRC_supported:1;
159 unsigned char reserved4:1; 160 unsigned char reserved4:1;
160 unsigned char striping:1; 161 unsigned char striping:1;
161 unsigned char reserved5:4; 162 unsigned char reserved5:4;
@@ -343,7 +344,7 @@ struct dasd_eckd_path {
343}; 344};
344 345
345/* 346/*
346 * Perform Subsystem Function - Prepare for Read Subsystem Data 347 * Perform Subsystem Function - Prepare for Read Subsystem Data
347 */ 348 */
348struct dasd_psf_prssd_data { 349struct dasd_psf_prssd_data {
349 unsigned char order; 350 unsigned char order;
@@ -353,4 +354,15 @@ struct dasd_psf_prssd_data {
353 unsigned char varies[9]; 354 unsigned char varies[9];
354} __attribute__ ((packed)); 355} __attribute__ ((packed));
355 356
357/*
358 * Perform Subsystem Function - Set Subsystem Characteristics
359 */
360struct dasd_psf_ssc_data {
361 unsigned char order;
362 unsigned char flags;
363 unsigned char cu_type[4];
364 unsigned char suborder;
365 unsigned char reserved[59];
366} __attribute__((packed));
367
356#endif /* DASD_ECKD_H */ 368#endif /* DASD_ECKD_H */
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c
index 2d946b6ca074..da65f1b032f5 100644
--- a/drivers/s390/block/dasd_eer.c
+++ b/drivers/s390/block/dasd_eer.c
@@ -89,7 +89,7 @@ struct eerbuffer {
89}; 89};
90 90
91static LIST_HEAD(bufferlist); 91static LIST_HEAD(bufferlist);
92static spinlock_t bufferlock = SPIN_LOCK_UNLOCKED; 92static DEFINE_SPINLOCK(bufferlock);
93static DECLARE_WAIT_QUEUE_HEAD(dasd_eer_read_wait_queue); 93static DECLARE_WAIT_QUEUE_HEAD(dasd_eer_read_wait_queue);
94 94
95/* 95/*
@@ -276,7 +276,7 @@ struct dasd_eer_header {
276 __u64 tv_sec; 276 __u64 tv_sec;
277 __u64 tv_usec; 277 __u64 tv_usec;
278 char busid[DASD_EER_BUSID_SIZE]; 278 char busid[DASD_EER_BUSID_SIZE];
279}; 279} __attribute__ ((packed));
280 280
281/* 281/*
282 * The following function can be used for those triggers that have 282 * The following function can be used for those triggers that have
@@ -521,6 +521,8 @@ static int dasd_eer_open(struct inode *inp, struct file *filp)
521 unsigned long flags; 521 unsigned long flags;
522 522
523 eerb = kzalloc(sizeof(struct eerbuffer), GFP_KERNEL); 523 eerb = kzalloc(sizeof(struct eerbuffer), GFP_KERNEL);
524 if (!eerb)
525 return -ENOMEM;
524 eerb->buffer_page_count = eer_pages; 526 eerb->buffer_page_count = eer_pages;
525 if (eerb->buffer_page_count < 1 || 527 if (eerb->buffer_page_count < 1 ||
526 eerb->buffer_page_count > INT_MAX / PAGE_SIZE) { 528 eerb->buffer_page_count > INT_MAX / PAGE_SIZE) {
diff --git a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c
index b842377cb0c6..4108d96f6a5a 100644
--- a/drivers/s390/block/dasd_erp.c
+++ b/drivers/s390/block/dasd_erp.c
@@ -90,7 +90,7 @@ dasd_default_erp_action(struct dasd_ccw_req * cqr)
90 90
91 /* just retry - there is nothing to save ... I got no sense data.... */ 91 /* just retry - there is nothing to save ... I got no sense data.... */
92 if (cqr->retries > 0) { 92 if (cqr->retries > 0) {
93 DEV_MESSAGE (KERN_DEBUG, device, 93 DEV_MESSAGE (KERN_DEBUG, device,
94 "default ERP called (%i retries left)", 94 "default ERP called (%i retries left)",
95 cqr->retries); 95 cqr->retries);
96 cqr->lpm = LPM_ANYPATH; 96 cqr->lpm = LPM_ANYPATH;
@@ -155,7 +155,7 @@ dasd_default_erp_postaction(struct dasd_ccw_req * cqr)
155 155
156/* 156/*
157 * Print the hex dump of the memory used by a request. This includes 157 * Print the hex dump of the memory used by a request. This includes
158 * all error recovery ccws that have been chained in from of the 158 * all error recovery ccws that have been chained in from of the
159 * real request. 159 * real request.
160 */ 160 */
161static inline void 161static inline void
@@ -227,12 +227,12 @@ dasd_log_ccw(struct dasd_ccw_req * cqr, int caller, __u32 cpa)
227 /* 227 /*
228 * Log bytes arround failed CCW but only if we did 228 * Log bytes arround failed CCW but only if we did
229 * not log the whole CP of the CCW is outside the 229 * not log the whole CP of the CCW is outside the
230 * logged CP. 230 * logged CP.
231 */ 231 */
232 if (cplength > 40 || 232 if (cplength > 40 ||
233 ((addr_t) cpa < (addr_t) lcqr->cpaddr && 233 ((addr_t) cpa < (addr_t) lcqr->cpaddr &&
234 (addr_t) cpa > (addr_t) (lcqr->cpaddr + cplength + 4))) { 234 (addr_t) cpa > (addr_t) (lcqr->cpaddr + cplength + 4))) {
235 235
236 DEV_MESSAGE(KERN_ERR, device, 236 DEV_MESSAGE(KERN_ERR, device,
237 "Failed CCW (%p) (area):", 237 "Failed CCW (%p) (area):",
238 (void *) (long) cpa); 238 (void *) (long) cpa);
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
index 91145698f8e9..bb7755b9b19d 100644
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * File...........: linux/drivers/s390/block/dasd_fba.c 2 * File...........: linux/drivers/s390/block/dasd_fba.c
3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4 * Bugreports.to..: <Linux390@de.ibm.com> 4 * Bugreports.to..: <Linux390@de.ibm.com>
@@ -56,19 +56,13 @@ static struct ccw_driver dasd_fba_driver; /* see below */
56static int 56static int
57dasd_fba_probe(struct ccw_device *cdev) 57dasd_fba_probe(struct ccw_device *cdev)
58{ 58{
59 int ret; 59 return dasd_generic_probe(cdev, &dasd_fba_discipline);
60
61 ret = dasd_generic_probe (cdev, &dasd_fba_discipline);
62 if (ret)
63 return ret;
64 ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
65 return 0;
66} 60}
67 61
68static int 62static int
69dasd_fba_set_online(struct ccw_device *cdev) 63dasd_fba_set_online(struct ccw_device *cdev)
70{ 64{
71 return dasd_generic_set_online (cdev, &dasd_fba_discipline); 65 return dasd_generic_set_online(cdev, &dasd_fba_discipline);
72} 66}
73 67
74static struct ccw_driver dasd_fba_driver = { 68static struct ccw_driver dasd_fba_driver = {
@@ -125,13 +119,13 @@ static int
125dasd_fba_check_characteristics(struct dasd_device *device) 119dasd_fba_check_characteristics(struct dasd_device *device)
126{ 120{
127 struct dasd_fba_private *private; 121 struct dasd_fba_private *private;
128 struct ccw_device *cdev = device->cdev; 122 struct ccw_device *cdev = device->cdev;
129 void *rdc_data; 123 void *rdc_data;
130 int rc; 124 int rc;
131 125
132 private = (struct dasd_fba_private *) device->private; 126 private = (struct dasd_fba_private *) device->private;
133 if (private == NULL) { 127 if (private == NULL) {
134 private = kmalloc(sizeof(struct dasd_fba_private), GFP_KERNEL); 128 private = kzalloc(sizeof(struct dasd_fba_private), GFP_KERNEL);
135 if (private == NULL) { 129 if (private == NULL) {
136 DEV_MESSAGE(KERN_WARNING, device, "%s", 130 DEV_MESSAGE(KERN_WARNING, device, "%s",
137 "memory allocation failed for private " 131 "memory allocation failed for private "
@@ -204,7 +198,7 @@ dasd_fba_examine_error(struct dasd_ccw_req * cqr, struct irb * irb)
204 if (irb->scsw.cstat == 0x00 && 198 if (irb->scsw.cstat == 0x00 &&
205 irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END)) 199 irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
206 return dasd_era_none; 200 return dasd_era_none;
207 201
208 cdev = device->cdev; 202 cdev = device->cdev;
209 switch (cdev->id.dev_type) { 203 switch (cdev->id.dev_type) {
210 case 0x3370: 204 case 0x3370:
@@ -539,7 +533,7 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
539 * 8192 bytes (=2 pages). For 64 bit one dasd_mchunkt_t structure has 533 * 8192 bytes (=2 pages). For 64 bit one dasd_mchunkt_t structure has
540 * 24 bytes, the struct dasd_ccw_req has 136 bytes and each block can use 534 * 24 bytes, the struct dasd_ccw_req has 136 bytes and each block can use
541 * up to 16 bytes (8 for the ccw and 8 for the idal pointer). In 535 * up to 16 bytes (8 for the ccw and 8 for the idal pointer). In
542 * addition we have one define extent ccw + 16 bytes of data and a 536 * addition we have one define extent ccw + 16 bytes of data and a
543 * locate record ccw for each block (stupid devices!) + 16 bytes of data. 537 * locate record ccw for each block (stupid devices!) + 16 bytes of data.
544 * That makes: 538 * That makes:
545 * (8192 - 24 - 136 - 8 - 16) / 40 = 200.2 blocks at maximum. 539 * (8192 - 24 - 136 - 8 - 16) / 40 = 200.2 blocks at maximum.
@@ -569,16 +563,8 @@ static struct dasd_discipline dasd_fba_discipline = {
569static int __init 563static int __init
570dasd_fba_init(void) 564dasd_fba_init(void)
571{ 565{
572 int ret;
573
574 ASCEBC(dasd_fba_discipline.ebcname, 4); 566 ASCEBC(dasd_fba_discipline.ebcname, 4);
575 567 return ccw_driver_register(&dasd_fba_driver);
576 ret = ccw_driver_register(&dasd_fba_driver);
577 if (ret)
578 return ret;
579
580 dasd_generic_auto_online(&dasd_fba_driver);
581 return 0;
582} 568}
583 569
584static void __exit 570static void __exit
@@ -589,22 +575,3 @@ dasd_fba_cleanup(void)
589 575
590module_init(dasd_fba_init); 576module_init(dasd_fba_init);
591module_exit(dasd_fba_cleanup); 577module_exit(dasd_fba_cleanup);
592
593/*
594 * Overrides for Emacs so that we follow Linus's tabbing style.
595 * Emacs will notice this stuff at the end of the file and automatically
596 * adjust the settings for this buffer only. This must remain at the end
597 * of the file.
598 * ---------------------------------------------------------------------------
599 * Local variables:
600 * c-indent-level: 4
601 * c-brace-imaginary-offset: 0
602 * c-brace-offset: -4
603 * c-argdecl-indent: 4
604 * c-label-offset: -4
605 * c-continued-statement-offset: 4
606 * c-continued-brace-offset: 0
607 * indent-tabs-mode: 1
608 * tab-width: 8
609 * End:
610 */
diff --git a/drivers/s390/block/dasd_fba.h b/drivers/s390/block/dasd_fba.h
index da1fa91fc01d..14c910baa5fe 100644
--- a/drivers/s390/block/dasd_fba.h
+++ b/drivers/s390/block/dasd_fba.h
@@ -1,4 +1,4 @@
1/* 1/*
2 * File...........: linux/drivers/s390/block/dasd_fba.h 2 * File...........: linux/drivers/s390/block/dasd_fba.h
3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4 * Bugreports.to..: <Linux390@de.ibm.com> 4 * Bugreports.to..: <Linux390@de.ibm.com>
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 1893797f2bf6..3ccf06d28ba1 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * File...........: linux/drivers/s390/block/dasd_int.h 2 * File...........: linux/drivers/s390/block/dasd_int.h
3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4 * Horst Hummel <Horst.Hummel@de.ibm.com> 4 * Horst Hummel <Horst.Hummel@de.ibm.com>
5 * Martin Schwidefsky <schwidefsky@de.ibm.com> 5 * Martin Schwidefsky <schwidefsky@de.ibm.com>
6 * Bugreports.to..: <Linux390@de.ibm.com> 6 * Bugreports.to..: <Linux390@de.ibm.com>
7 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 7 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
@@ -185,7 +185,7 @@ struct dasd_ccw_req {
185 void *callback_data; 185 void *callback_data;
186}; 186};
187 187
188/* 188/*
189 * dasd_ccw_req -> status can be: 189 * dasd_ccw_req -> status can be:
190 */ 190 */
191#define DASD_CQR_FILLED 0x00 /* request is ready to be processed */ 191#define DASD_CQR_FILLED 0x00 /* request is ready to be processed */
@@ -247,7 +247,7 @@ struct dasd_discipline {
247 /* 247 /*
248 * Error recovery functions. examine_error() returns a value that 248 * Error recovery functions. examine_error() returns a value that
249 * indicates what to do for an error condition. If examine_error() 249 * indicates what to do for an error condition. If examine_error()
250 * returns 'dasd_era_recover' erp_action() is called to create a 250 * returns 'dasd_era_recover' erp_action() is called to create a
251 * special error recovery ccw. erp_postaction() is called after 251 * special error recovery ccw. erp_postaction() is called after
252 * an error recovery ccw has finished its execution. dump_sense 252 * an error recovery ccw has finished its execution. dump_sense
253 * is called for every error condition to print the sense data 253 * is called for every error condition to print the sense data
@@ -301,11 +301,11 @@ struct dasd_device {
301 spinlock_t request_queue_lock; 301 spinlock_t request_queue_lock;
302 struct block_device *bdev; 302 struct block_device *bdev;
303 unsigned int devindex; 303 unsigned int devindex;
304 unsigned long blocks; /* size of volume in blocks */ 304 unsigned long blocks; /* size of volume in blocks */
305 unsigned int bp_block; /* bytes per block */ 305 unsigned int bp_block; /* bytes per block */
306 unsigned int s2b_shift; /* log2 (bp_block/512) */ 306 unsigned int s2b_shift; /* log2 (bp_block/512) */
307 unsigned long flags; /* per device flags */ 307 unsigned long flags; /* per device flags */
308 unsigned short features; /* copy of devmap-features (read-only!) */ 308 unsigned short features; /* copy of devmap-features (read-only!) */
309 309
310 /* extended error reporting stuff (eer) */ 310 /* extended error reporting stuff (eer) */
311 struct dasd_ccw_req *eer_cqr; 311 struct dasd_ccw_req *eer_cqr;
@@ -512,12 +512,12 @@ void dasd_generic_remove (struct ccw_device *cdev);
512int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *); 512int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *);
513int dasd_generic_set_offline (struct ccw_device *cdev); 513int dasd_generic_set_offline (struct ccw_device *cdev);
514int dasd_generic_notify(struct ccw_device *, int); 514int dasd_generic_notify(struct ccw_device *, int);
515void dasd_generic_auto_online (struct ccw_driver *);
516 515
517/* externals in dasd_devmap.c */ 516/* externals in dasd_devmap.c */
518extern int dasd_max_devindex; 517extern int dasd_max_devindex;
519extern int dasd_probeonly; 518extern int dasd_probeonly;
520extern int dasd_autodetect; 519extern int dasd_autodetect;
520extern int dasd_nopav;
521 521
522int dasd_devmap_init(void); 522int dasd_devmap_init(void);
523void dasd_devmap_exit(void); 523void dasd_devmap_exit(void);
@@ -605,22 +605,3 @@ static inline int dasd_eer_enabled(struct dasd_device *device)
605#endif /* __KERNEL__ */ 605#endif /* __KERNEL__ */
606 606
607#endif /* DASD_H */ 607#endif /* DASD_H */
608
609/*
610 * Overrides for Emacs so that we follow Linus's tabbing style.
611 * Emacs will notice this stuff at the end of the file and automatically
612 * adjust the settings for this buffer only. This must remain at the end
613 * of the file.
614 * ---------------------------------------------------------------------------
615 * Local variables:
616 * c-indent-level: 4
617 * c-brace-imaginary-offset: 0
618 * c-brace-offset: -4
619 * c-argdecl-indent: 4
620 * c-label-offset: -4
621 * c-continued-statement-offset: 4
622 * c-continued-brace-offset: 0
623 * indent-tabs-mode: 1
624 * tab-width: 8
625 * End:
626 */
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index b8c80d28df41..302bcd0f28be 100644
--- a/drivers/s390/block/dasd_ioctl.c
+++ b/drivers/s390/block/dasd_ioctl.c
@@ -90,10 +90,10 @@ static int
90dasd_ioctl_quiesce(struct dasd_device *device) 90dasd_ioctl_quiesce(struct dasd_device *device)
91{ 91{
92 unsigned long flags; 92 unsigned long flags;
93 93
94 if (!capable (CAP_SYS_ADMIN)) 94 if (!capable (CAP_SYS_ADMIN))
95 return -EACCES; 95 return -EACCES;
96 96
97 DEV_MESSAGE (KERN_DEBUG, device, "%s", 97 DEV_MESSAGE (KERN_DEBUG, device, "%s",
98 "Quiesce IO on device"); 98 "Quiesce IO on device");
99 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); 99 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
@@ -110,13 +110,13 @@ static int
110dasd_ioctl_resume(struct dasd_device *device) 110dasd_ioctl_resume(struct dasd_device *device)
111{ 111{
112 unsigned long flags; 112 unsigned long flags;
113 113
114 if (!capable (CAP_SYS_ADMIN)) 114 if (!capable (CAP_SYS_ADMIN))
115 return -EACCES; 115 return -EACCES;
116 116
117 DEV_MESSAGE (KERN_DEBUG, device, "%s", 117 DEV_MESSAGE (KERN_DEBUG, device, "%s",
118 "resume IO on device"); 118 "resume IO on device");
119 119
120 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); 120 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
121 device->stopped &= ~DASD_STOPPED_QUIESCE; 121 device->stopped &= ~DASD_STOPPED_QUIESCE;
122 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); 122 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
@@ -287,7 +287,7 @@ dasd_ioctl_information(struct dasd_device *device,
287 dasd_info->open_count = atomic_read(&device->open_count); 287 dasd_info->open_count = atomic_read(&device->open_count);
288 if (!device->bdev) 288 if (!device->bdev)
289 dasd_info->open_count++; 289 dasd_info->open_count++;
290 290
291 /* 291 /*
292 * check if device is really formatted 292 * check if device is really formatted
293 * LDL / CDL was returned by 'fill_info' 293 * LDL / CDL was returned by 'fill_info'
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index eecb2afad5c2..3c1314b7391b 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -50,6 +50,9 @@ struct raw3270 {
50 unsigned char *ascebc; /* ascii -> ebcdic table */ 50 unsigned char *ascebc; /* ascii -> ebcdic table */
51 struct class_device *clttydev; /* 3270-class tty device ptr */ 51 struct class_device *clttydev; /* 3270-class tty device ptr */
52 struct class_device *cltubdev; /* 3270-class tub device ptr */ 52 struct class_device *cltubdev; /* 3270-class tub device ptr */
53
54 struct raw3270_request init_request;
55 unsigned char init_data[256];
53}; 56};
54 57
55/* raw3270->flags */ 58/* raw3270->flags */
@@ -484,8 +487,6 @@ struct raw3270_ua { /* Query Reply structure for Usable Area */
484 } __attribute__ ((packed)) aua; 487 } __attribute__ ((packed)) aua;
485} __attribute__ ((packed)); 488} __attribute__ ((packed));
486 489
487static unsigned char raw3270_init_data[256];
488static struct raw3270_request raw3270_init_request;
489static struct diag210 raw3270_init_diag210; 490static struct diag210 raw3270_init_diag210;
490static DECLARE_MUTEX(raw3270_init_sem); 491static DECLARE_MUTEX(raw3270_init_sem);
491 492
@@ -644,17 +645,17 @@ __raw3270_size_device(struct raw3270 *rp)
644 * required (3270 device switched to 'stand-by') and command 645 * required (3270 device switched to 'stand-by') and command
645 * rejects (old devices that can't do 'read partition'). 646 * rejects (old devices that can't do 'read partition').
646 */ 647 */
647 memset(&raw3270_init_request, 0, sizeof(raw3270_init_request)); 648 memset(&rp->init_request, 0, sizeof(rp->init_request));
648 memset(raw3270_init_data, 0, sizeof(raw3270_init_data)); 649 memset(&rp->init_data, 0, 256);
649 /* Store 'read partition' data stream to raw3270_init_data */ 650 /* Store 'read partition' data stream to init_data */
650 memcpy(raw3270_init_data, wbuf, sizeof(wbuf)); 651 memcpy(&rp->init_data, wbuf, sizeof(wbuf));
651 INIT_LIST_HEAD(&raw3270_init_request.list); 652 INIT_LIST_HEAD(&rp->init_request.list);
652 raw3270_init_request.ccw.cmd_code = TC_WRITESF; 653 rp->init_request.ccw.cmd_code = TC_WRITESF;
653 raw3270_init_request.ccw.flags = CCW_FLAG_SLI; 654 rp->init_request.ccw.flags = CCW_FLAG_SLI;
654 raw3270_init_request.ccw.count = sizeof(wbuf); 655 rp->init_request.ccw.count = sizeof(wbuf);
655 raw3270_init_request.ccw.cda = (__u32) __pa(raw3270_init_data); 656 rp->init_request.ccw.cda = (__u32) __pa(&rp->init_data);
656 657
657 rc = raw3270_start_init(rp, &raw3270_init_view, &raw3270_init_request); 658 rc = raw3270_start_init(rp, &raw3270_init_view, &rp->init_request);
658 if (rc) 659 if (rc)
659 /* Check error cases: -ERESTARTSYS, -EIO and -EOPNOTSUPP */ 660 /* Check error cases: -ERESTARTSYS, -EIO and -EOPNOTSUPP */
660 return rc; 661 return rc;
@@ -679,18 +680,18 @@ __raw3270_size_device(struct raw3270 *rp)
679 * The device accepted the 'read partition' command. Now 680 * The device accepted the 'read partition' command. Now
680 * set up a read ccw and issue it. 681 * set up a read ccw and issue it.
681 */ 682 */
682 raw3270_init_request.ccw.cmd_code = TC_READMOD; 683 rp->init_request.ccw.cmd_code = TC_READMOD;
683 raw3270_init_request.ccw.flags = CCW_FLAG_SLI; 684 rp->init_request.ccw.flags = CCW_FLAG_SLI;
684 raw3270_init_request.ccw.count = sizeof(raw3270_init_data); 685 rp->init_request.ccw.count = sizeof(rp->init_data);
685 raw3270_init_request.ccw.cda = (__u32) __pa(raw3270_init_data); 686 rp->init_request.ccw.cda = (__u32) __pa(rp->init_data);
686 rc = raw3270_start_init(rp, &raw3270_init_view, &raw3270_init_request); 687 rc = raw3270_start_init(rp, &raw3270_init_view, &rp->init_request);
687 if (rc) 688 if (rc)
688 return rc; 689 return rc;
689 /* Got a Query Reply */ 690 /* Got a Query Reply */
690 count = sizeof(raw3270_init_data) - raw3270_init_request.rescnt; 691 count = sizeof(rp->init_data) - rp->init_request.rescnt;
691 uap = (struct raw3270_ua *) (raw3270_init_data + 1); 692 uap = (struct raw3270_ua *) (rp->init_data + 1);
692 /* Paranoia check. */ 693 /* Paranoia check. */
693 if (raw3270_init_data[0] != 0x88 || uap->uab.qcode != 0x81) 694 if (rp->init_data[0] != 0x88 || uap->uab.qcode != 0x81)
694 return -EOPNOTSUPP; 695 return -EOPNOTSUPP;
695 /* Copy rows/columns of default Usable Area */ 696 /* Copy rows/columns of default Usable Area */
696 rp->rows = uap->uab.h; 697 rp->rows = uap->uab.h;
@@ -749,18 +750,18 @@ raw3270_reset_device(struct raw3270 *rp)
749 int rc; 750 int rc;
750 751
751 down(&raw3270_init_sem); 752 down(&raw3270_init_sem);
752 memset(&raw3270_init_request, 0, sizeof(raw3270_init_request)); 753 memset(&rp->init_request, 0, sizeof(rp->init_request));
753 memset(raw3270_init_data, 0, sizeof(raw3270_init_data)); 754 memset(&rp->init_data, 0, sizeof(rp->init_data));
754 /* Store reset data stream to raw3270_init_data/raw3270_init_request */ 755 /* Store reset data stream to init_data/init_request */
755 raw3270_init_data[0] = TW_KR; 756 rp->init_data[0] = TW_KR;
756 INIT_LIST_HEAD(&raw3270_init_request.list); 757 INIT_LIST_HEAD(&rp->init_request.list);
757 raw3270_init_request.ccw.cmd_code = TC_EWRITEA; 758 rp->init_request.ccw.cmd_code = TC_EWRITEA;
758 raw3270_init_request.ccw.flags = CCW_FLAG_SLI; 759 rp->init_request.ccw.flags = CCW_FLAG_SLI;
759 raw3270_init_request.ccw.count = 1; 760 rp->init_request.ccw.count = 1;
760 raw3270_init_request.ccw.cda = (__u32) __pa(raw3270_init_data); 761 rp->init_request.ccw.cda = (__u32) __pa(rp->init_data);
761 rp->view = &raw3270_init_view; 762 rp->view = &raw3270_init_view;
762 raw3270_init_view.dev = rp; 763 raw3270_init_view.dev = rp;
763 rc = raw3270_start_init(rp, &raw3270_init_view, &raw3270_init_request); 764 rc = raw3270_start_init(rp, &raw3270_init_view, &rp->init_request);
764 raw3270_init_view.dev = 0; 765 raw3270_init_view.dev = 0;
765 rp->view = 0; 766 rp->view = 0;
766 up(&raw3270_init_sem); 767 up(&raw3270_init_sem);
@@ -854,7 +855,7 @@ raw3270_setup_console(struct ccw_device *cdev)
854 char *ascebc; 855 char *ascebc;
855 int rc; 856 int rc;
856 857
857 rp = (struct raw3270 *) alloc_bootmem(sizeof(struct raw3270)); 858 rp = (struct raw3270 *) alloc_bootmem_low(sizeof(struct raw3270));
858 ascebc = (char *) alloc_bootmem(256); 859 ascebc = (char *) alloc_bootmem(256);
859 rc = raw3270_setup_device(cdev, rp, ascebc); 860 rc = raw3270_setup_device(cdev, rp, ascebc);
860 if (rc) 861 if (rc)
@@ -895,7 +896,7 @@ raw3270_create_device(struct ccw_device *cdev)
895 char *ascebc; 896 char *ascebc;
896 int rc; 897 int rc;
897 898
898 rp = kmalloc(sizeof(struct raw3270), GFP_KERNEL); 899 rp = kmalloc(sizeof(struct raw3270), GFP_KERNEL | GFP_DMA);
899 if (!rp) 900 if (!rp)
900 return ERR_PTR(-ENOMEM); 901 return ERR_PTR(-ENOMEM);
901 ascebc = kmalloc(256, GFP_KERNEL); 902 ascebc = kmalloc(256, GFP_KERNEL);
diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c
index 0960bef7b199..15b895496a45 100644
--- a/drivers/s390/cio/blacklist.c
+++ b/drivers/s390/cio/blacklist.c
@@ -224,39 +224,6 @@ is_blacklisted (int ssid, int devno)
224} 224}
225 225
226#ifdef CONFIG_PROC_FS 226#ifdef CONFIG_PROC_FS
227static int
228__s390_redo_validation(struct subchannel_id schid, void *data)
229{
230 int ret;
231 struct subchannel *sch;
232
233 sch = get_subchannel_by_schid(schid);
234 if (sch) {
235 /* Already known. */
236 put_device(&sch->dev);
237 return 0;
238 }
239 ret = css_probe_device(schid);
240 if (ret == -ENXIO)
241 return ret; /* We're through. */
242 if (ret == -ENOMEM)
243 /* Stop validation for now. Bad, but no need for a panic. */
244 return ret;
245 return 0;
246}
247
248/*
249 * Function: s390_redo_validation
250 * Look for no longer blacklisted devices
251 * FIXME: there must be a better way to do this */
252static inline void
253s390_redo_validation (void)
254{
255 CIO_TRACE_EVENT (0, "redoval");
256
257 for_each_subchannel(__s390_redo_validation, NULL);
258}
259
260/* 227/*
261 * Function: blacklist_parse_proc_parameters 228 * Function: blacklist_parse_proc_parameters
262 * parse the stuff which is piped to /proc/cio_ignore 229 * parse the stuff which is piped to /proc/cio_ignore
@@ -281,7 +248,7 @@ blacklist_parse_proc_parameters (char *buf)
281 return; 248 return;
282 } 249 }
283 250
284 s390_redo_validation (); 251 css_schedule_reprobe();
285} 252}
286 253
287/* Iterator struct for all devices. */ 254/* Iterator struct for all devices. */
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index bdfee7fbaa2e..c7319a07ba35 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -404,21 +404,24 @@ ccwgroup_driver_register (struct ccwgroup_driver *cdriver)
404} 404}
405 405
406static int 406static int
407__ccwgroup_driver_unregister_device(struct device *dev, void *data) 407__ccwgroup_match_all(struct device *dev, void *data)
408{ 408{
409 __ccwgroup_remove_symlinks(to_ccwgroupdev(dev)); 409 return 1;
410 device_unregister(dev);
411 put_device(dev);
412 return 0;
413} 410}
414 411
415void 412void
416ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver) 413ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver)
417{ 414{
415 struct device *dev;
416
418 /* We don't want ccwgroup devices to live longer than their driver. */ 417 /* We don't want ccwgroup devices to live longer than their driver. */
419 get_driver(&cdriver->driver); 418 get_driver(&cdriver->driver);
420 driver_for_each_device(&cdriver->driver, NULL, NULL, 419 while ((dev = driver_find_device(&cdriver->driver, NULL, NULL,
421 __ccwgroup_driver_unregister_device); 420 __ccwgroup_match_all))) {
421 __ccwgroup_remove_symlinks(to_ccwgroupdev(dev));
422 device_unregister(dev);
423 put_device(dev);
424 }
422 put_driver(&cdriver->driver); 425 put_driver(&cdriver->driver);
423 driver_unregister(&cdriver->driver); 426 driver_unregister(&cdriver->driver);
424} 427}
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index 72187e54dcac..b00f3ed051a0 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -244,8 +244,7 @@ s390_subchannel_remove_chpid(struct device *dev, void *data)
244 244
245 if ((sch->schib.scsw.actl & SCSW_ACTL_DEVACT) && 245 if ((sch->schib.scsw.actl & SCSW_ACTL_DEVACT) &&
246 (sch->schib.scsw.actl & SCSW_ACTL_SCHACT) && 246 (sch->schib.scsw.actl & SCSW_ACTL_SCHACT) &&
247 (sch->schib.pmcw.lpum == mask) && 247 (sch->schib.pmcw.lpum == mask)) {
248 (sch->vpm == 0)) {
249 int cc; 248 int cc;
250 249
251 cc = cio_clear(sch); 250 cc = cio_clear(sch);
@@ -918,12 +917,13 @@ chp_measurement_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
918 chp = to_channelpath(container_of(kobj, struct device, kobj)); 917 chp = to_channelpath(container_of(kobj, struct device, kobj));
919 css = to_css(chp->dev.parent); 918 css = to_css(chp->dev.parent);
920 919
921 size = sizeof(struct cmg_chars); 920 size = sizeof(struct cmg_entry);
922 921
923 /* Only allow single reads. */ 922 /* Only allow single reads. */
924 if (off || count < size) 923 if (off || count < size)
925 return 0; 924 return 0;
926 chp_measurement_copy_block((struct cmg_entry *)buf, css, chp->id); 925 chp_measurement_copy_block((struct cmg_entry *)buf, css, chp->id);
926 count = size;
927 return count; 927 return count;
928} 928}
929 929
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c
index 07ef3f640f4a..1c3e8e9012b0 100644
--- a/drivers/s390/cio/cmf.c
+++ b/drivers/s390/cio/cmf.c
@@ -3,9 +3,10 @@
3 * 3 *
4 * Linux on zSeries Channel Measurement Facility support 4 * Linux on zSeries Channel Measurement Facility support
5 * 5 *
6 * Copyright 2000,2003 IBM Corporation 6 * Copyright 2000,2006 IBM Corporation
7 * 7 *
8 * Author: Arnd Bergmann <arndb@de.ibm.com> 8 * Authors: Arnd Bergmann <arndb@de.ibm.com>
9 * Cornelia Huck <cornelia.huck@de.ibm.com>
9 * 10 *
10 * original idea from Natarajan Krishnaswami <nkrishna@us.ibm.com> 11 * original idea from Natarajan Krishnaswami <nkrishna@us.ibm.com>
11 * 12 *
@@ -96,9 +97,9 @@ module_param(format, bool, 0444);
96/** 97/**
97 * struct cmb_operations - functions to use depending on cmb_format 98 * struct cmb_operations - functions to use depending on cmb_format
98 * 99 *
99 * all these functions operate on a struct cmf_device. There is only 100 * Most of these functions operate on a struct ccw_device. There is only
100 * one instance of struct cmb_operations because all cmf_device 101 * one instance of struct cmb_operations because the format of the measurement
101 * objects are guaranteed to be of the same type. 102 * data is guaranteed to be the same for every ccw_device.
102 * 103 *
103 * @alloc: allocate memory for a channel measurement block, 104 * @alloc: allocate memory for a channel measurement block,
104 * either with the help of a special pool or with kmalloc 105 * either with the help of a special pool or with kmalloc
@@ -107,6 +108,7 @@ module_param(format, bool, 0444);
107 * @readall: read a measurement block in a common format 108 * @readall: read a measurement block in a common format
108 * @reset: clear the data in the associated measurement block and 109 * @reset: clear the data in the associated measurement block and
109 * reset its time stamp 110 * reset its time stamp
111 * @align: align an allocated block so that the hardware can use it
110 */ 112 */
111struct cmb_operations { 113struct cmb_operations {
112 int (*alloc) (struct ccw_device*); 114 int (*alloc) (struct ccw_device*);
@@ -115,11 +117,19 @@ struct cmb_operations {
115 u64 (*read) (struct ccw_device*, int); 117 u64 (*read) (struct ccw_device*, int);
116 int (*readall)(struct ccw_device*, struct cmbdata *); 118 int (*readall)(struct ccw_device*, struct cmbdata *);
117 void (*reset) (struct ccw_device*); 119 void (*reset) (struct ccw_device*);
120 void * (*align) (void *);
118 121
119 struct attribute_group *attr_group; 122 struct attribute_group *attr_group;
120}; 123};
121static struct cmb_operations *cmbops; 124static struct cmb_operations *cmbops;
122 125
126struct cmb_data {
127 void *hw_block; /* Pointer to block updated by hardware */
128 void *last_block; /* Last changed block copied from hardware block */
129 int size; /* Size of hw_block and last_block */
130 unsigned long long last_update; /* when last_block was updated */
131};
132
123/* our user interface is designed in terms of nanoseconds, 133/* our user interface is designed in terms of nanoseconds,
124 * while the hardware measures total times in its own 134 * while the hardware measures total times in its own
125 * unit.*/ 135 * unit.*/
@@ -226,63 +236,229 @@ struct set_schib_struct {
226 unsigned long address; 236 unsigned long address;
227 wait_queue_head_t wait; 237 wait_queue_head_t wait;
228 int ret; 238 int ret;
239 struct kref kref;
229}; 240};
230 241
242static void cmf_set_schib_release(struct kref *kref)
243{
244 struct set_schib_struct *set_data;
245
246 set_data = container_of(kref, struct set_schib_struct, kref);
247 kfree(set_data);
248}
249
250#define CMF_PENDING 1
251
231static int set_schib_wait(struct ccw_device *cdev, u32 mme, 252static int set_schib_wait(struct ccw_device *cdev, u32 mme,
232 int mbfc, unsigned long address) 253 int mbfc, unsigned long address)
233{ 254{
234 struct set_schib_struct s = { 255 struct set_schib_struct *set_data;
235 .mme = mme, 256 int ret;
236 .mbfc = mbfc,
237 .address = address,
238 .wait = __WAIT_QUEUE_HEAD_INITIALIZER(s.wait),
239 };
240 257
241 spin_lock_irq(cdev->ccwlock); 258 spin_lock_irq(cdev->ccwlock);
242 s.ret = set_schib(cdev, mme, mbfc, address); 259 if (!cdev->private->cmb) {
243 if (s.ret != -EBUSY) { 260 ret = -ENODEV;
244 goto out_nowait; 261 goto out;
245 } 262 }
263 set_data = kzalloc(sizeof(struct set_schib_struct), GFP_ATOMIC);
264 if (!set_data) {
265 ret = -ENOMEM;
266 goto out;
267 }
268 init_waitqueue_head(&set_data->wait);
269 kref_init(&set_data->kref);
270 set_data->mme = mme;
271 set_data->mbfc = mbfc;
272 set_data->address = address;
273
274 ret = set_schib(cdev, mme, mbfc, address);
275 if (ret != -EBUSY)
276 goto out_put;
246 277
247 if (cdev->private->state != DEV_STATE_ONLINE) { 278 if (cdev->private->state != DEV_STATE_ONLINE) {
248 s.ret = -EBUSY;
249 /* if the device is not online, don't even try again */ 279 /* if the device is not online, don't even try again */
250 goto out_nowait; 280 ret = -EBUSY;
281 goto out_put;
251 } 282 }
283
252 cdev->private->state = DEV_STATE_CMFCHANGE; 284 cdev->private->state = DEV_STATE_CMFCHANGE;
253 cdev->private->cmb_wait = &s; 285 set_data->ret = CMF_PENDING;
254 s.ret = 1; 286 cdev->private->cmb_wait = set_data;
255 287
256 spin_unlock_irq(cdev->ccwlock); 288 spin_unlock_irq(cdev->ccwlock);
257 if (wait_event_interruptible(s.wait, s.ret != 1)) { 289 if (wait_event_interruptible(set_data->wait,
290 set_data->ret != CMF_PENDING)) {
258 spin_lock_irq(cdev->ccwlock); 291 spin_lock_irq(cdev->ccwlock);
259 if (s.ret == 1) { 292 if (set_data->ret == CMF_PENDING) {
260 s.ret = -ERESTARTSYS; 293 set_data->ret = -ERESTARTSYS;
261 cdev->private->cmb_wait = 0;
262 if (cdev->private->state == DEV_STATE_CMFCHANGE) 294 if (cdev->private->state == DEV_STATE_CMFCHANGE)
263 cdev->private->state = DEV_STATE_ONLINE; 295 cdev->private->state = DEV_STATE_ONLINE;
264 } 296 }
265 spin_unlock_irq(cdev->ccwlock); 297 spin_unlock_irq(cdev->ccwlock);
266 } 298 }
267 return s.ret; 299 spin_lock_irq(cdev->ccwlock);
268 300 cdev->private->cmb_wait = NULL;
269out_nowait: 301 ret = set_data->ret;
302out_put:
303 kref_put(&set_data->kref, cmf_set_schib_release);
304out:
270 spin_unlock_irq(cdev->ccwlock); 305 spin_unlock_irq(cdev->ccwlock);
271 return s.ret; 306 return ret;
272} 307}
273 308
274void retry_set_schib(struct ccw_device *cdev) 309void retry_set_schib(struct ccw_device *cdev)
275{ 310{
276 struct set_schib_struct *s; 311 struct set_schib_struct *set_data;
312
313 set_data = cdev->private->cmb_wait;
314 if (!set_data) {
315 WARN_ON(1);
316 return;
317 }
318 kref_get(&set_data->kref);
319 set_data->ret = set_schib(cdev, set_data->mme, set_data->mbfc,
320 set_data->address);
321 wake_up(&set_data->wait);
322 kref_put(&set_data->kref, cmf_set_schib_release);
323}
324
325static int cmf_copy_block(struct ccw_device *cdev)
326{
327 struct subchannel *sch;
328 void *reference_buf;
329 void *hw_block;
330 struct cmb_data *cmb_data;
331
332 sch = to_subchannel(cdev->dev.parent);
333
334 if (stsch(sch->schid, &sch->schib))
335 return -ENODEV;
336
337 if (sch->schib.scsw.fctl & SCSW_FCTL_START_FUNC) {
338 /* Don't copy if a start function is in progress. */
339 if ((!sch->schib.scsw.actl & SCSW_ACTL_SUSPENDED) &&
340 (sch->schib.scsw.actl &
341 (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT)) &&
342 (!sch->schib.scsw.stctl & SCSW_STCTL_SEC_STATUS))
343 return -EBUSY;
344 }
345 cmb_data = cdev->private->cmb;
346 hw_block = cmbops->align(cmb_data->hw_block);
347 if (!memcmp(cmb_data->last_block, hw_block, cmb_data->size))
348 /* No need to copy. */
349 return 0;
350 reference_buf = kzalloc(cmb_data->size, GFP_ATOMIC);
351 if (!reference_buf)
352 return -ENOMEM;
353 /* Ensure consistency of block copied from hardware. */
354 do {
355 memcpy(cmb_data->last_block, hw_block, cmb_data->size);
356 memcpy(reference_buf, hw_block, cmb_data->size);
357 } while (memcmp(cmb_data->last_block, reference_buf, cmb_data->size));
358 cmb_data->last_update = get_clock();
359 kfree(reference_buf);
360 return 0;
361}
362
363struct copy_block_struct {
364 wait_queue_head_t wait;
365 int ret;
366 struct kref kref;
367};
368
369static void cmf_copy_block_release(struct kref *kref)
370{
371 struct copy_block_struct *copy_block;
372
373 copy_block = container_of(kref, struct copy_block_struct, kref);
374 kfree(copy_block);
375}
376
377static int cmf_cmb_copy_wait(struct ccw_device *cdev)
378{
379 struct copy_block_struct *copy_block;
380 int ret;
381 unsigned long flags;
382
383 spin_lock_irqsave(cdev->ccwlock, flags);
384 if (!cdev->private->cmb) {
385 ret = -ENODEV;
386 goto out;
387 }
388 copy_block = kzalloc(sizeof(struct copy_block_struct), GFP_ATOMIC);
389 if (!copy_block) {
390 ret = -ENOMEM;
391 goto out;
392 }
393 init_waitqueue_head(&copy_block->wait);
394 kref_init(&copy_block->kref);
395
396 ret = cmf_copy_block(cdev);
397 if (ret != -EBUSY)
398 goto out_put;
399
400 if (cdev->private->state != DEV_STATE_ONLINE) {
401 ret = -EBUSY;
402 goto out_put;
403 }
404
405 cdev->private->state = DEV_STATE_CMFUPDATE;
406 copy_block->ret = CMF_PENDING;
407 cdev->private->cmb_wait = copy_block;
408
409 spin_unlock_irqrestore(cdev->ccwlock, flags);
410 if (wait_event_interruptible(copy_block->wait,
411 copy_block->ret != CMF_PENDING)) {
412 spin_lock_irqsave(cdev->ccwlock, flags);
413 if (copy_block->ret == CMF_PENDING) {
414 copy_block->ret = -ERESTARTSYS;
415 if (cdev->private->state == DEV_STATE_CMFUPDATE)
416 cdev->private->state = DEV_STATE_ONLINE;
417 }
418 spin_unlock_irqrestore(cdev->ccwlock, flags);
419 }
420 spin_lock_irqsave(cdev->ccwlock, flags);
421 cdev->private->cmb_wait = NULL;
422 ret = copy_block->ret;
423out_put:
424 kref_put(&copy_block->kref, cmf_copy_block_release);
425out:
426 spin_unlock_irqrestore(cdev->ccwlock, flags);
427 return ret;
428}
429
430void cmf_retry_copy_block(struct ccw_device *cdev)
431{
432 struct copy_block_struct *copy_block;
277 433
278 s = cdev->private->cmb_wait; 434 copy_block = cdev->private->cmb_wait;
279 cdev->private->cmb_wait = 0; 435 if (!copy_block) {
280 if (!s) {
281 WARN_ON(1); 436 WARN_ON(1);
282 return; 437 return;
283 } 438 }
284 s->ret = set_schib(cdev, s->mme, s->mbfc, s->address); 439 kref_get(&copy_block->kref);
285 wake_up(&s->wait); 440 copy_block->ret = cmf_copy_block(cdev);
441 wake_up(&copy_block->wait);
442 kref_put(&copy_block->kref, cmf_copy_block_release);
443}
444
445static void cmf_generic_reset(struct ccw_device *cdev)
446{
447 struct cmb_data *cmb_data;
448
449 spin_lock_irq(cdev->ccwlock);
450 cmb_data = cdev->private->cmb;
451 if (cmb_data) {
452 memset(cmb_data->last_block, 0, cmb_data->size);
453 /*
454 * Need to reset hw block as well to make the hardware start
455 * from 0 again.
456 */
457 memset(cmbops->align(cmb_data->hw_block), 0, cmb_data->size);
458 cmb_data->last_update = 0;
459 }
460 cdev->private->cmb_start_time = get_clock();
461 spin_unlock_irq(cdev->ccwlock);
286} 462}
287 463
288/** 464/**
@@ -343,8 +519,8 @@ struct cmb {
343/* insert a single device into the cmb_area list 519/* insert a single device into the cmb_area list
344 * called with cmb_area.lock held from alloc_cmb 520 * called with cmb_area.lock held from alloc_cmb
345 */ 521 */
346static inline int 522static inline int alloc_cmb_single (struct ccw_device *cdev,
347alloc_cmb_single (struct ccw_device *cdev) 523 struct cmb_data *cmb_data)
348{ 524{
349 struct cmb *cmb; 525 struct cmb *cmb;
350 struct ccw_device_private *node; 526 struct ccw_device_private *node;
@@ -358,10 +534,12 @@ alloc_cmb_single (struct ccw_device *cdev)
358 534
359 /* find first unused cmb in cmb_area.mem. 535 /* find first unused cmb in cmb_area.mem.
360 * this is a little tricky: cmb_area.list 536 * this is a little tricky: cmb_area.list
361 * remains sorted by ->cmb pointers */ 537 * remains sorted by ->cmb->hw_data pointers */
362 cmb = cmb_area.mem; 538 cmb = cmb_area.mem;
363 list_for_each_entry(node, &cmb_area.list, cmb_list) { 539 list_for_each_entry(node, &cmb_area.list, cmb_list) {
364 if ((struct cmb*)node->cmb > cmb) 540 struct cmb_data *data;
541 data = node->cmb;
542 if ((struct cmb*)data->hw_block > cmb)
365 break; 543 break;
366 cmb++; 544 cmb++;
367 } 545 }
@@ -372,7 +550,8 @@ alloc_cmb_single (struct ccw_device *cdev)
372 550
373 /* insert new cmb */ 551 /* insert new cmb */
374 list_add_tail(&cdev->private->cmb_list, &node->cmb_list); 552 list_add_tail(&cdev->private->cmb_list, &node->cmb_list);
375 cdev->private->cmb = cmb; 553 cmb_data->hw_block = cmb;
554 cdev->private->cmb = cmb_data;
376 ret = 0; 555 ret = 0;
377out: 556out:
378 spin_unlock_irq(cdev->ccwlock); 557 spin_unlock_irq(cdev->ccwlock);
@@ -385,7 +564,19 @@ alloc_cmb (struct ccw_device *cdev)
385 int ret; 564 int ret;
386 struct cmb *mem; 565 struct cmb *mem;
387 ssize_t size; 566 ssize_t size;
567 struct cmb_data *cmb_data;
568
569 /* Allocate private cmb_data. */
570 cmb_data = kzalloc(sizeof(struct cmb_data), GFP_KERNEL);
571 if (!cmb_data)
572 return -ENOMEM;
388 573
574 cmb_data->last_block = kzalloc(sizeof(struct cmb), GFP_KERNEL);
575 if (!cmb_data->last_block) {
576 kfree(cmb_data);
577 return -ENOMEM;
578 }
579 cmb_data->size = sizeof(struct cmb);
389 spin_lock(&cmb_area.lock); 580 spin_lock(&cmb_area.lock);
390 581
391 if (!cmb_area.mem) { 582 if (!cmb_area.mem) {
@@ -414,29 +605,36 @@ alloc_cmb (struct ccw_device *cdev)
414 } 605 }
415 606
416 /* do the actual allocation */ 607 /* do the actual allocation */
417 ret = alloc_cmb_single(cdev); 608 ret = alloc_cmb_single(cdev, cmb_data);
418out: 609out:
419 spin_unlock(&cmb_area.lock); 610 spin_unlock(&cmb_area.lock);
420 611 if (ret) {
612 kfree(cmb_data->last_block);
613 kfree(cmb_data);
614 }
421 return ret; 615 return ret;
422} 616}
423 617
424static void 618static void free_cmb(struct ccw_device *cdev)
425free_cmb(struct ccw_device *cdev)
426{ 619{
427 struct ccw_device_private *priv; 620 struct ccw_device_private *priv;
428 621 struct cmb_data *cmb_data;
429 priv = cdev->private;
430 622
431 spin_lock(&cmb_area.lock); 623 spin_lock(&cmb_area.lock);
432 spin_lock_irq(cdev->ccwlock); 624 spin_lock_irq(cdev->ccwlock);
433 625
626 priv = cdev->private;
627
434 if (list_empty(&priv->cmb_list)) { 628 if (list_empty(&priv->cmb_list)) {
435 /* already freed */ 629 /* already freed */
436 goto out; 630 goto out;
437 } 631 }
438 632
633 cmb_data = priv->cmb;
439 priv->cmb = NULL; 634 priv->cmb = NULL;
635 if (cmb_data)
636 kfree(cmb_data->last_block);
637 kfree(cmb_data);
440 list_del_init(&priv->cmb_list); 638 list_del_init(&priv->cmb_list);
441 639
442 if (list_empty(&cmb_area.list)) { 640 if (list_empty(&cmb_area.list)) {
@@ -451,83 +649,97 @@ out:
451 spin_unlock(&cmb_area.lock); 649 spin_unlock(&cmb_area.lock);
452} 650}
453 651
454static int 652static int set_cmb(struct ccw_device *cdev, u32 mme)
455set_cmb(struct ccw_device *cdev, u32 mme)
456{ 653{
457 u16 offset; 654 u16 offset;
655 struct cmb_data *cmb_data;
656 unsigned long flags;
458 657
459 if (!cdev->private->cmb) 658 spin_lock_irqsave(cdev->ccwlock, flags);
659 if (!cdev->private->cmb) {
660 spin_unlock_irqrestore(cdev->ccwlock, flags);
460 return -EINVAL; 661 return -EINVAL;
461 662 }
462 offset = mme ? (struct cmb *)cdev->private->cmb - cmb_area.mem : 0; 663 cmb_data = cdev->private->cmb;
664 offset = mme ? (struct cmb *)cmb_data->hw_block - cmb_area.mem : 0;
665 spin_unlock_irqrestore(cdev->ccwlock, flags);
463 666
464 return set_schib_wait(cdev, mme, 0, offset); 667 return set_schib_wait(cdev, mme, 0, offset);
465} 668}
466 669
467static u64 670static u64 read_cmb (struct ccw_device *cdev, int index)
468read_cmb (struct ccw_device *cdev, int index)
469{ 671{
470 /* yes, we have to put it on the stack 672 struct cmb *cmb;
471 * because the cmb must only be accessed
472 * atomically, e.g. with mvc */
473 struct cmb cmb;
474 unsigned long flags;
475 u32 val; 673 u32 val;
674 int ret;
675 unsigned long flags;
676
677 ret = cmf_cmb_copy_wait(cdev);
678 if (ret < 0)
679 return 0;
476 680
477 spin_lock_irqsave(cdev->ccwlock, flags); 681 spin_lock_irqsave(cdev->ccwlock, flags);
478 if (!cdev->private->cmb) { 682 if (!cdev->private->cmb) {
479 spin_unlock_irqrestore(cdev->ccwlock, flags); 683 ret = 0;
480 return 0; 684 goto out;
481 } 685 }
482 686 cmb = ((struct cmb_data *)cdev->private->cmb)->last_block;
483 cmb = *(struct cmb*)cdev->private->cmb;
484 spin_unlock_irqrestore(cdev->ccwlock, flags);
485 687
486 switch (index) { 688 switch (index) {
487 case cmb_ssch_rsch_count: 689 case cmb_ssch_rsch_count:
488 return cmb.ssch_rsch_count; 690 ret = cmb->ssch_rsch_count;
691 goto out;
489 case cmb_sample_count: 692 case cmb_sample_count:
490 return cmb.sample_count; 693 ret = cmb->sample_count;
694 goto out;
491 case cmb_device_connect_time: 695 case cmb_device_connect_time:
492 val = cmb.device_connect_time; 696 val = cmb->device_connect_time;
493 break; 697 break;
494 case cmb_function_pending_time: 698 case cmb_function_pending_time:
495 val = cmb.function_pending_time; 699 val = cmb->function_pending_time;
496 break; 700 break;
497 case cmb_device_disconnect_time: 701 case cmb_device_disconnect_time:
498 val = cmb.device_disconnect_time; 702 val = cmb->device_disconnect_time;
499 break; 703 break;
500 case cmb_control_unit_queuing_time: 704 case cmb_control_unit_queuing_time:
501 val = cmb.control_unit_queuing_time; 705 val = cmb->control_unit_queuing_time;
502 break; 706 break;
503 case cmb_device_active_only_time: 707 case cmb_device_active_only_time:
504 val = cmb.device_active_only_time; 708 val = cmb->device_active_only_time;
505 break; 709 break;
506 default: 710 default:
507 return 0; 711 ret = 0;
712 goto out;
508 } 713 }
509 return time_to_avg_nsec(val, cmb.sample_count); 714 ret = time_to_avg_nsec(val, cmb->sample_count);
715out:
716 spin_unlock_irqrestore(cdev->ccwlock, flags);
717 return ret;
510} 718}
511 719
512static int 720static int readall_cmb (struct ccw_device *cdev, struct cmbdata *data)
513readall_cmb (struct ccw_device *cdev, struct cmbdata *data)
514{ 721{
515 /* yes, we have to put it on the stack 722 struct cmb *cmb;
516 * because the cmb must only be accessed 723 struct cmb_data *cmb_data;
517 * atomically, e.g. with mvc */
518 struct cmb cmb;
519 unsigned long flags;
520 u64 time; 724 u64 time;
725 unsigned long flags;
726 int ret;
521 727
728 ret = cmf_cmb_copy_wait(cdev);
729 if (ret < 0)
730 return ret;
522 spin_lock_irqsave(cdev->ccwlock, flags); 731 spin_lock_irqsave(cdev->ccwlock, flags);
523 if (!cdev->private->cmb) { 732 cmb_data = cdev->private->cmb;
524 spin_unlock_irqrestore(cdev->ccwlock, flags); 733 if (!cmb_data) {
525 return -ENODEV; 734 ret = -ENODEV;
735 goto out;
526 } 736 }
527 737 if (cmb_data->last_update == 0) {
528 cmb = *(struct cmb*)cdev->private->cmb; 738 ret = -EAGAIN;
529 time = get_clock() - cdev->private->cmb_start_time; 739 goto out;
530 spin_unlock_irqrestore(cdev->ccwlock, flags); 740 }
741 cmb = cmb_data->last_block;
742 time = cmb_data->last_update - cdev->private->cmb_start_time;
531 743
532 memset(data, 0, sizeof(struct cmbdata)); 744 memset(data, 0, sizeof(struct cmbdata));
533 745
@@ -538,31 +750,32 @@ readall_cmb (struct ccw_device *cdev, struct cmbdata *data)
538 data->elapsed_time = (time * 1000) >> 12; 750 data->elapsed_time = (time * 1000) >> 12;
539 751
540 /* copy data to new structure */ 752 /* copy data to new structure */
541 data->ssch_rsch_count = cmb.ssch_rsch_count; 753 data->ssch_rsch_count = cmb->ssch_rsch_count;
542 data->sample_count = cmb.sample_count; 754 data->sample_count = cmb->sample_count;
543 755
544 /* time fields are converted to nanoseconds while copying */ 756 /* time fields are converted to nanoseconds while copying */
545 data->device_connect_time = time_to_nsec(cmb.device_connect_time); 757 data->device_connect_time = time_to_nsec(cmb->device_connect_time);
546 data->function_pending_time = time_to_nsec(cmb.function_pending_time); 758 data->function_pending_time = time_to_nsec(cmb->function_pending_time);
547 data->device_disconnect_time = time_to_nsec(cmb.device_disconnect_time); 759 data->device_disconnect_time =
760 time_to_nsec(cmb->device_disconnect_time);
548 data->control_unit_queuing_time 761 data->control_unit_queuing_time
549 = time_to_nsec(cmb.control_unit_queuing_time); 762 = time_to_nsec(cmb->control_unit_queuing_time);
550 data->device_active_only_time 763 data->device_active_only_time
551 = time_to_nsec(cmb.device_active_only_time); 764 = time_to_nsec(cmb->device_active_only_time);
765 ret = 0;
766out:
767 spin_unlock_irqrestore(cdev->ccwlock, flags);
768 return ret;
769}
552 770
553 return 0; 771static void reset_cmb(struct ccw_device *cdev)
772{
773 cmf_generic_reset(cdev);
554} 774}
555 775
556static void 776static void * align_cmb(void *area)
557reset_cmb(struct ccw_device *cdev)
558{ 777{
559 struct cmb *cmb; 778 return area;
560 spin_lock_irq(cdev->ccwlock);
561 cmb = cdev->private->cmb;
562 if (cmb)
563 memset (cmb, 0, sizeof (*cmb));
564 cdev->private->cmb_start_time = get_clock();
565 spin_unlock_irq(cdev->ccwlock);
566} 779}
567 780
568static struct attribute_group cmf_attr_group; 781static struct attribute_group cmf_attr_group;
@@ -574,6 +787,7 @@ static struct cmb_operations cmbops_basic = {
574 .read = read_cmb, 787 .read = read_cmb,
575 .readall = readall_cmb, 788 .readall = readall_cmb,
576 .reset = reset_cmb, 789 .reset = reset_cmb,
790 .align = align_cmb,
577 .attr_group = &cmf_attr_group, 791 .attr_group = &cmf_attr_group,
578}; 792};
579 793
@@ -610,22 +824,34 @@ static inline struct cmbe* cmbe_align(struct cmbe *c)
610 return (struct cmbe*)addr; 824 return (struct cmbe*)addr;
611} 825}
612 826
613static int 827static int alloc_cmbe (struct ccw_device *cdev)
614alloc_cmbe (struct ccw_device *cdev)
615{ 828{
616 struct cmbe *cmbe; 829 struct cmbe *cmbe;
617 cmbe = kmalloc (sizeof (*cmbe) * 2, GFP_KERNEL); 830 struct cmb_data *cmb_data;
831 int ret;
832
833 cmbe = kzalloc (sizeof (*cmbe) * 2, GFP_KERNEL);
618 if (!cmbe) 834 if (!cmbe)
619 return -ENOMEM; 835 return -ENOMEM;
620 836 cmb_data = kzalloc(sizeof(struct cmb_data), GFP_KERNEL);
837 if (!cmb_data) {
838 ret = -ENOMEM;
839 goto out_free;
840 }
841 cmb_data->last_block = kzalloc(sizeof(struct cmbe), GFP_KERNEL);
842 if (!cmb_data->last_block) {
843 ret = -ENOMEM;
844 goto out_free;
845 }
846 cmb_data->size = sizeof(struct cmbe);
621 spin_lock_irq(cdev->ccwlock); 847 spin_lock_irq(cdev->ccwlock);
622 if (cdev->private->cmb) { 848 if (cdev->private->cmb) {
623 kfree(cmbe);
624 spin_unlock_irq(cdev->ccwlock); 849 spin_unlock_irq(cdev->ccwlock);
625 return -EBUSY; 850 ret = -EBUSY;
851 goto out_free;
626 } 852 }
627 853 cmb_data->hw_block = cmbe;
628 cdev->private->cmb = cmbe; 854 cdev->private->cmb = cmb_data;
629 spin_unlock_irq(cdev->ccwlock); 855 spin_unlock_irq(cdev->ccwlock);
630 856
631 /* activate global measurement if this is the first channel */ 857 /* activate global measurement if this is the first channel */
@@ -636,14 +862,24 @@ alloc_cmbe (struct ccw_device *cdev)
636 spin_unlock(&cmb_area.lock); 862 spin_unlock(&cmb_area.lock);
637 863
638 return 0; 864 return 0;
865out_free:
866 if (cmb_data)
867 kfree(cmb_data->last_block);
868 kfree(cmb_data);
869 kfree(cmbe);
870 return ret;
639} 871}
640 872
641static void 873static void free_cmbe (struct ccw_device *cdev)
642free_cmbe (struct ccw_device *cdev)
643{ 874{
875 struct cmb_data *cmb_data;
876
644 spin_lock_irq(cdev->ccwlock); 877 spin_lock_irq(cdev->ccwlock);
645 kfree(cdev->private->cmb); 878 cmb_data = cdev->private->cmb;
646 cdev->private->cmb = NULL; 879 cdev->private->cmb = NULL;
880 if (cmb_data)
881 kfree(cmb_data->last_block);
882 kfree(cmb_data);
647 spin_unlock_irq(cdev->ccwlock); 883 spin_unlock_irq(cdev->ccwlock);
648 884
649 /* deactivate global measurement if this is the last channel */ 885 /* deactivate global measurement if this is the last channel */
@@ -654,89 +890,105 @@ free_cmbe (struct ccw_device *cdev)
654 spin_unlock(&cmb_area.lock); 890 spin_unlock(&cmb_area.lock);
655} 891}
656 892
657static int 893static int set_cmbe(struct ccw_device *cdev, u32 mme)
658set_cmbe(struct ccw_device *cdev, u32 mme)
659{ 894{
660 unsigned long mba; 895 unsigned long mba;
896 struct cmb_data *cmb_data;
897 unsigned long flags;
661 898
662 if (!cdev->private->cmb) 899 spin_lock_irqsave(cdev->ccwlock, flags);
900 if (!cdev->private->cmb) {
901 spin_unlock_irqrestore(cdev->ccwlock, flags);
663 return -EINVAL; 902 return -EINVAL;
664 mba = mme ? (unsigned long) cmbe_align(cdev->private->cmb) : 0; 903 }
904 cmb_data = cdev->private->cmb;
905 mba = mme ? (unsigned long) cmbe_align(cmb_data->hw_block) : 0;
906 spin_unlock_irqrestore(cdev->ccwlock, flags);
665 907
666 return set_schib_wait(cdev, mme, 1, mba); 908 return set_schib_wait(cdev, mme, 1, mba);
667} 909}
668 910
669 911
670u64 912static u64 read_cmbe (struct ccw_device *cdev, int index)
671read_cmbe (struct ccw_device *cdev, int index)
672{ 913{
673 /* yes, we have to put it on the stack 914 struct cmbe *cmb;
674 * because the cmb must only be accessed 915 struct cmb_data *cmb_data;
675 * atomically, e.g. with mvc */
676 struct cmbe cmb;
677 unsigned long flags;
678 u32 val; 916 u32 val;
917 int ret;
918 unsigned long flags;
679 919
680 spin_lock_irqsave(cdev->ccwlock, flags); 920 ret = cmf_cmb_copy_wait(cdev);
681 if (!cdev->private->cmb) { 921 if (ret < 0)
682 spin_unlock_irqrestore(cdev->ccwlock, flags);
683 return 0; 922 return 0;
684 }
685 923
686 cmb = *cmbe_align(cdev->private->cmb); 924 spin_lock_irqsave(cdev->ccwlock, flags);
687 spin_unlock_irqrestore(cdev->ccwlock, flags); 925 cmb_data = cdev->private->cmb;
926 if (!cmb_data) {
927 ret = 0;
928 goto out;
929 }
930 cmb = cmb_data->last_block;
688 931
689 switch (index) { 932 switch (index) {
690 case cmb_ssch_rsch_count: 933 case cmb_ssch_rsch_count:
691 return cmb.ssch_rsch_count; 934 ret = cmb->ssch_rsch_count;
935 goto out;
692 case cmb_sample_count: 936 case cmb_sample_count:
693 return cmb.sample_count; 937 ret = cmb->sample_count;
938 goto out;
694 case cmb_device_connect_time: 939 case cmb_device_connect_time:
695 val = cmb.device_connect_time; 940 val = cmb->device_connect_time;
696 break; 941 break;
697 case cmb_function_pending_time: 942 case cmb_function_pending_time:
698 val = cmb.function_pending_time; 943 val = cmb->function_pending_time;
699 break; 944 break;
700 case cmb_device_disconnect_time: 945 case cmb_device_disconnect_time:
701 val = cmb.device_disconnect_time; 946 val = cmb->device_disconnect_time;
702 break; 947 break;
703 case cmb_control_unit_queuing_time: 948 case cmb_control_unit_queuing_time:
704 val = cmb.control_unit_queuing_time; 949 val = cmb->control_unit_queuing_time;
705 break; 950 break;
706 case cmb_device_active_only_time: 951 case cmb_device_active_only_time:
707 val = cmb.device_active_only_time; 952 val = cmb->device_active_only_time;
708 break; 953 break;
709 case cmb_device_busy_time: 954 case cmb_device_busy_time:
710 val = cmb.device_busy_time; 955 val = cmb->device_busy_time;
711 break; 956 break;
712 case cmb_initial_command_response_time: 957 case cmb_initial_command_response_time:
713 val = cmb.initial_command_response_time; 958 val = cmb->initial_command_response_time;
714 break; 959 break;
715 default: 960 default:
716 return 0; 961 ret = 0;
962 goto out;
717 } 963 }
718 return time_to_avg_nsec(val, cmb.sample_count); 964 ret = time_to_avg_nsec(val, cmb->sample_count);
965out:
966 spin_unlock_irqrestore(cdev->ccwlock, flags);
967 return ret;
719} 968}
720 969
721static int 970static int readall_cmbe (struct ccw_device *cdev, struct cmbdata *data)
722readall_cmbe (struct ccw_device *cdev, struct cmbdata *data)
723{ 971{
724 /* yes, we have to put it on the stack 972 struct cmbe *cmb;
725 * because the cmb must only be accessed 973 struct cmb_data *cmb_data;
726 * atomically, e.g. with mvc */
727 struct cmbe cmb;
728 unsigned long flags;
729 u64 time; 974 u64 time;
975 unsigned long flags;
976 int ret;
730 977
978 ret = cmf_cmb_copy_wait(cdev);
979 if (ret < 0)
980 return ret;
731 spin_lock_irqsave(cdev->ccwlock, flags); 981 spin_lock_irqsave(cdev->ccwlock, flags);
732 if (!cdev->private->cmb) { 982 cmb_data = cdev->private->cmb;
733 spin_unlock_irqrestore(cdev->ccwlock, flags); 983 if (!cmb_data) {
734 return -ENODEV; 984 ret = -ENODEV;
985 goto out;
735 } 986 }
736 987 if (cmb_data->last_update == 0) {
737 cmb = *cmbe_align(cdev->private->cmb); 988 ret = -EAGAIN;
738 time = get_clock() - cdev->private->cmb_start_time; 989 goto out;
739 spin_unlock_irqrestore(cdev->ccwlock, flags); 990 }
991 time = cmb_data->last_update - cdev->private->cmb_start_time;
740 992
741 memset (data, 0, sizeof(struct cmbdata)); 993 memset (data, 0, sizeof(struct cmbdata));
742 994
@@ -746,35 +998,38 @@ readall_cmbe (struct ccw_device *cdev, struct cmbdata *data)
746 /* conver to nanoseconds */ 998 /* conver to nanoseconds */
747 data->elapsed_time = (time * 1000) >> 12; 999 data->elapsed_time = (time * 1000) >> 12;
748 1000
1001 cmb = cmb_data->last_block;
749 /* copy data to new structure */ 1002 /* copy data to new structure */
750 data->ssch_rsch_count = cmb.ssch_rsch_count; 1003 data->ssch_rsch_count = cmb->ssch_rsch_count;
751 data->sample_count = cmb.sample_count; 1004 data->sample_count = cmb->sample_count;
752 1005
753 /* time fields are converted to nanoseconds while copying */ 1006 /* time fields are converted to nanoseconds while copying */
754 data->device_connect_time = time_to_nsec(cmb.device_connect_time); 1007 data->device_connect_time = time_to_nsec(cmb->device_connect_time);
755 data->function_pending_time = time_to_nsec(cmb.function_pending_time); 1008 data->function_pending_time = time_to_nsec(cmb->function_pending_time);
756 data->device_disconnect_time = time_to_nsec(cmb.device_disconnect_time); 1009 data->device_disconnect_time =
1010 time_to_nsec(cmb->device_disconnect_time);
757 data->control_unit_queuing_time 1011 data->control_unit_queuing_time
758 = time_to_nsec(cmb.control_unit_queuing_time); 1012 = time_to_nsec(cmb->control_unit_queuing_time);
759 data->device_active_only_time 1013 data->device_active_only_time
760 = time_to_nsec(cmb.device_active_only_time); 1014 = time_to_nsec(cmb->device_active_only_time);
761 data->device_busy_time = time_to_nsec(cmb.device_busy_time); 1015 data->device_busy_time = time_to_nsec(cmb->device_busy_time);
762 data->initial_command_response_time 1016 data->initial_command_response_time
763 = time_to_nsec(cmb.initial_command_response_time); 1017 = time_to_nsec(cmb->initial_command_response_time);
764 1018
765 return 0; 1019 ret = 0;
1020out:
1021 spin_unlock_irqrestore(cdev->ccwlock, flags);
1022 return ret;
766} 1023}
767 1024
768static void 1025static void reset_cmbe(struct ccw_device *cdev)
769reset_cmbe(struct ccw_device *cdev)
770{ 1026{
771 struct cmbe *cmb; 1027 cmf_generic_reset(cdev);
772 spin_lock_irq(cdev->ccwlock); 1028}
773 cmb = cmbe_align(cdev->private->cmb); 1029
774 if (cmb) 1030static void * align_cmbe(void *area)
775 memset (cmb, 0, sizeof (*cmb)); 1031{
776 cdev->private->cmb_start_time = get_clock(); 1032 return cmbe_align(area);
777 spin_unlock_irq(cdev->ccwlock);
778} 1033}
779 1034
780static struct attribute_group cmf_attr_group_ext; 1035static struct attribute_group cmf_attr_group_ext;
@@ -786,6 +1041,7 @@ static struct cmb_operations cmbops_extended = {
786 .read = read_cmbe, 1041 .read = read_cmbe,
787 .readall = readall_cmbe, 1042 .readall = readall_cmbe,
788 .reset = reset_cmbe, 1043 .reset = reset_cmbe,
1044 .align = align_cmbe,
789 .attr_group = &cmf_attr_group_ext, 1045 .attr_group = &cmf_attr_group_ext,
790}; 1046};
791 1047
@@ -803,14 +1059,19 @@ cmb_show_avg_sample_interval(struct device *dev, struct device_attribute *attr,
803 struct ccw_device *cdev; 1059 struct ccw_device *cdev;
804 long interval; 1060 long interval;
805 unsigned long count; 1061 unsigned long count;
1062 struct cmb_data *cmb_data;
806 1063
807 cdev = to_ccwdev(dev); 1064 cdev = to_ccwdev(dev);
808 interval = get_clock() - cdev->private->cmb_start_time;
809 count = cmf_read(cdev, cmb_sample_count); 1065 count = cmf_read(cdev, cmb_sample_count);
810 if (count) 1066 spin_lock_irq(cdev->ccwlock);
1067 cmb_data = cdev->private->cmb;
1068 if (count) {
1069 interval = cmb_data->last_update -
1070 cdev->private->cmb_start_time;
811 interval /= count; 1071 interval /= count;
812 else 1072 } else
813 interval = -1; 1073 interval = -1;
1074 spin_unlock_irq(cdev->ccwlock);
814 return sprintf(buf, "%ld\n", interval); 1075 return sprintf(buf, "%ld\n", interval);
815} 1076}
816 1077
@@ -823,7 +1084,10 @@ cmb_show_avg_utilization(struct device *dev, struct device_attribute *attr, char
823 int ret; 1084 int ret;
824 1085
825 ret = cmf_readall(to_ccwdev(dev), &data); 1086 ret = cmf_readall(to_ccwdev(dev), &data);
826 if (ret) 1087 if (ret == -EAGAIN || ret == -ENODEV)
1088 /* No data (yet/currently) available to use for calculation. */
1089 return sprintf(buf, "n/a\n");
1090 else if (ret)
827 return ret; 1091 return ret;
828 1092
829 utilization = data.device_connect_time + 1093 utilization = data.device_connect_time +
@@ -982,6 +1246,13 @@ cmf_readall(struct ccw_device *cdev, struct cmbdata *data)
982 return cmbops->readall(cdev, data); 1246 return cmbops->readall(cdev, data);
983} 1247}
984 1248
1249/* Reenable cmf when a disconnected device becomes available again. */
1250int cmf_reenable(struct ccw_device *cdev)
1251{
1252 cmbops->reset(cdev);
1253 return cmbops->set(cdev, 2);
1254}
1255
985static int __init 1256static int __init
986init_cmf(void) 1257init_cmf(void)
987{ 1258{
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 74ea8aac4b7d..1d3be80797f8 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -19,9 +19,11 @@
19#include "cio_debug.h" 19#include "cio_debug.h"
20#include "ioasm.h" 20#include "ioasm.h"
21#include "chsc.h" 21#include "chsc.h"
22#include "device.h"
22 23
23int need_rescan = 0; 24int need_rescan = 0;
24int css_init_done = 0; 25int css_init_done = 0;
26static int need_reprobe = 0;
25static int max_ssid = 0; 27static int max_ssid = 0;
26 28
27struct channel_subsystem *css[__MAX_CSSID + 1]; 29struct channel_subsystem *css[__MAX_CSSID + 1];
@@ -339,6 +341,67 @@ typedef void (*workfunc)(void *);
339DECLARE_WORK(slow_path_work, (workfunc)css_trigger_slow_path, NULL); 341DECLARE_WORK(slow_path_work, (workfunc)css_trigger_slow_path, NULL);
340struct workqueue_struct *slow_path_wq; 342struct workqueue_struct *slow_path_wq;
341 343
344/* Reprobe subchannel if unregistered. */
345static int reprobe_subchannel(struct subchannel_id schid, void *data)
346{
347 struct subchannel *sch;
348 int ret;
349
350 CIO_DEBUG(KERN_INFO, 6, "cio: reprobe 0.%x.%04x\n",
351 schid.ssid, schid.sch_no);
352 if (need_reprobe)
353 return -EAGAIN;
354
355 sch = get_subchannel_by_schid(schid);
356 if (sch) {
357 /* Already known. */
358 put_device(&sch->dev);
359 return 0;
360 }
361
362 ret = css_probe_device(schid);
363 switch (ret) {
364 case 0:
365 break;
366 case -ENXIO:
367 case -ENOMEM:
368 /* These should abort looping */
369 break;
370 default:
371 ret = 0;
372 }
373
374 return ret;
375}
376
377/* Work function used to reprobe all unregistered subchannels. */
378static void reprobe_all(void *data)
379{
380 int ret;
381
382 CIO_MSG_EVENT(2, "reprobe start\n");
383
384 need_reprobe = 0;
385 /* Make sure initial subchannel scan is done. */
386 wait_event(ccw_device_init_wq,
387 atomic_read(&ccw_device_init_count) == 0);
388 ret = for_each_subchannel(reprobe_subchannel, NULL);
389
390 CIO_MSG_EVENT(2, "reprobe done (rc=%d, need_reprobe=%d)\n", ret,
391 need_reprobe);
392}
393
394DECLARE_WORK(css_reprobe_work, reprobe_all, NULL);
395
396/* Schedule reprobing of all unregistered subchannels. */
397void css_schedule_reprobe(void)
398{
399 need_reprobe = 1;
400 queue_work(ccw_device_work, &css_reprobe_work);
401}
402
403EXPORT_SYMBOL_GPL(css_schedule_reprobe);
404
342/* 405/*
343 * Rescan for new devices. FIXME: This is slow. 406 * Rescan for new devices. FIXME: This is slow.
344 * This function is called when we have lost CRWs due to overflows and we have 407 * This function is called when we have lost CRWs due to overflows and we have
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 8e3053c2a451..eafde43e8410 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -133,8 +133,8 @@ struct css_driver io_subchannel_driver = {
133 133
134struct workqueue_struct *ccw_device_work; 134struct workqueue_struct *ccw_device_work;
135struct workqueue_struct *ccw_device_notify_work; 135struct workqueue_struct *ccw_device_notify_work;
136static wait_queue_head_t ccw_device_init_wq; 136wait_queue_head_t ccw_device_init_wq;
137static atomic_t ccw_device_init_count; 137atomic_t ccw_device_init_count;
138 138
139static int __init 139static int __init
140init_ccw_bus_type (void) 140init_ccw_bus_type (void)
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
index 11587ebb7289..00be9a5b4acd 100644
--- a/drivers/s390/cio/device.h
+++ b/drivers/s390/cio/device.h
@@ -1,6 +1,10 @@
1#ifndef S390_DEVICE_H 1#ifndef S390_DEVICE_H
2#define S390_DEVICE_H 2#define S390_DEVICE_H
3 3
4#include <asm/ccwdev.h>
5#include <asm/atomic.h>
6#include <linux/wait.h>
7
4/* 8/*
5 * states of the device statemachine 9 * states of the device statemachine
6 */ 10 */
@@ -23,6 +27,7 @@ enum dev_state {
23 DEV_STATE_DISCONNECTED, 27 DEV_STATE_DISCONNECTED,
24 DEV_STATE_DISCONNECTED_SENSE_ID, 28 DEV_STATE_DISCONNECTED_SENSE_ID,
25 DEV_STATE_CMFCHANGE, 29 DEV_STATE_CMFCHANGE,
30 DEV_STATE_CMFUPDATE,
26 /* last element! */ 31 /* last element! */
27 NR_DEV_STATES 32 NR_DEV_STATES
28}; 33};
@@ -67,6 +72,8 @@ dev_fsm_final_state(struct ccw_device *cdev)
67 72
68extern struct workqueue_struct *ccw_device_work; 73extern struct workqueue_struct *ccw_device_work;
69extern struct workqueue_struct *ccw_device_notify_work; 74extern struct workqueue_struct *ccw_device_notify_work;
75extern wait_queue_head_t ccw_device_init_wq;
76extern atomic_t ccw_device_init_count;
70 77
71void io_subchannel_recog_done(struct ccw_device *cdev); 78void io_subchannel_recog_done(struct ccw_device *cdev);
72 79
@@ -112,5 +119,8 @@ int ccw_device_stlck(struct ccw_device *);
112void ccw_device_set_timeout(struct ccw_device *, int); 119void ccw_device_set_timeout(struct ccw_device *, int);
113extern struct subchannel_id ccw_device_get_subchannel_id(struct ccw_device *); 120extern struct subchannel_id ccw_device_get_subchannel_id(struct ccw_device *);
114 121
122/* Channel measurement facility related */
115void retry_set_schib(struct ccw_device *cdev); 123void retry_set_schib(struct ccw_device *cdev);
124void cmf_retry_copy_block(struct ccw_device *);
125int cmf_reenable(struct ccw_device *);
116#endif 126#endif
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 49ec562d7f60..7d0dd72635eb 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -336,8 +336,11 @@ ccw_device_oper_notify(void *data)
336 if (!ret) 336 if (!ret)
337 /* Driver doesn't want device back. */ 337 /* Driver doesn't want device back. */
338 ccw_device_do_unreg_rereg((void *)cdev); 338 ccw_device_do_unreg_rereg((void *)cdev);
339 else 339 else {
340 /* Reenable channel measurements, if needed. */
341 cmf_reenable(cdev);
340 wake_up(&cdev->private->wait_q); 342 wake_up(&cdev->private->wait_q);
343 }
341} 344}
342 345
343/* 346/*
@@ -861,6 +864,8 @@ ccw_device_clear_verify(struct ccw_device *cdev, enum dev_event dev_event)
861 irb = (struct irb *) __LC_IRB; 864 irb = (struct irb *) __LC_IRB;
862 /* Accumulate status. We don't do basic sense. */ 865 /* Accumulate status. We don't do basic sense. */
863 ccw_device_accumulate_irb(cdev, irb); 866 ccw_device_accumulate_irb(cdev, irb);
867 /* Remember to clear irb to avoid residuals. */
868 memset(&cdev->private->irb, 0, sizeof(struct irb));
864 /* Try to start delayed device verification. */ 869 /* Try to start delayed device verification. */
865 ccw_device_online_verify(cdev, 0); 870 ccw_device_online_verify(cdev, 0);
866 /* Note: Don't call handler for cio initiated clear! */ 871 /* Note: Don't call handler for cio initiated clear! */
@@ -1093,6 +1098,13 @@ ccw_device_change_cmfstate(struct ccw_device *cdev, enum dev_event dev_event)
1093 dev_fsm_event(cdev, dev_event); 1098 dev_fsm_event(cdev, dev_event);
1094} 1099}
1095 1100
1101static void ccw_device_update_cmfblock(struct ccw_device *cdev,
1102 enum dev_event dev_event)
1103{
1104 cmf_retry_copy_block(cdev);
1105 cdev->private->state = DEV_STATE_ONLINE;
1106 dev_fsm_event(cdev, dev_event);
1107}
1096 1108
1097static void 1109static void
1098ccw_device_quiesce_done(struct ccw_device *cdev, enum dev_event dev_event) 1110ccw_device_quiesce_done(struct ccw_device *cdev, enum dev_event dev_event)
@@ -1247,6 +1259,12 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = {
1247 [DEV_EVENT_TIMEOUT] = ccw_device_change_cmfstate, 1259 [DEV_EVENT_TIMEOUT] = ccw_device_change_cmfstate,
1248 [DEV_EVENT_VERIFY] = ccw_device_change_cmfstate, 1260 [DEV_EVENT_VERIFY] = ccw_device_change_cmfstate,
1249 }, 1261 },
1262 [DEV_STATE_CMFUPDATE] = {
1263 [DEV_EVENT_NOTOPER] = ccw_device_update_cmfblock,
1264 [DEV_EVENT_INTERRUPT] = ccw_device_update_cmfblock,
1265 [DEV_EVENT_TIMEOUT] = ccw_device_update_cmfblock,
1266 [DEV_EVENT_VERIFY] = ccw_device_update_cmfblock,
1267 },
1250}; 1268};
1251 1269
1252/* 1270/*
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index 795abb5a65ba..b266ad8e14ff 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -78,7 +78,8 @@ ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa,
78 return -ENODEV; 78 return -ENODEV;
79 if (cdev->private->state == DEV_STATE_NOT_OPER) 79 if (cdev->private->state == DEV_STATE_NOT_OPER)
80 return -ENODEV; 80 return -ENODEV;
81 if (cdev->private->state == DEV_STATE_VERIFY) { 81 if (cdev->private->state == DEV_STATE_VERIFY ||
82 cdev->private->state == DEV_STATE_CLEAR_VERIFY) {
82 /* Remember to fake irb when finished. */ 83 /* Remember to fake irb when finished. */
83 if (!cdev->private->flags.fake_irb) { 84 if (!cdev->private->flags.fake_irb) {
84 cdev->private->flags.fake_irb = 1; 85 cdev->private->flags.fake_irb = 1;
@@ -270,7 +271,8 @@ ccw_device_wake_up(struct ccw_device *cdev, unsigned long ip, struct irb *irb)
270 * We didn't get channel end / device end. Check if path 271 * We didn't get channel end / device end. Check if path
271 * verification has been started; we can retry after it has 272 * verification has been started; we can retry after it has
272 * finished. We also retry unit checks except for command reject 273 * finished. We also retry unit checks except for command reject
273 * or intervention required. 274 * or intervention required. Also check for long busy
275 * conditions.
274 */ 276 */
275 if (cdev->private->flags.doverify || 277 if (cdev->private->flags.doverify ||
276 cdev->private->state == DEV_STATE_VERIFY) 278 cdev->private->state == DEV_STATE_VERIFY)
@@ -279,6 +281,10 @@ ccw_device_wake_up(struct ccw_device *cdev, unsigned long ip, struct irb *irb)
279 !(irb->ecw[0] & 281 !(irb->ecw[0] &
280 (SNS0_CMD_REJECT | SNS0_INTERVENTION_REQ))) 282 (SNS0_CMD_REJECT | SNS0_INTERVENTION_REQ)))
281 cdev->private->intparm = -EAGAIN; 283 cdev->private->intparm = -EAGAIN;
284 else if ((irb->scsw.dstat & DEV_STAT_ATTENTION) &&
285 (irb->scsw.dstat & DEV_STAT_DEV_END) &&
286 (irb->scsw.dstat & DEV_STAT_UNIT_EXCEP))
287 cdev->private->intparm = -EAGAIN;
282 else 288 else
283 cdev->private->intparm = -EIO; 289 cdev->private->intparm = -EIO;
284 290
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c
index f99e55308b32..8dc75002acbe 100644
--- a/drivers/s390/s390mach.c
+++ b/drivers/s390/s390mach.c
@@ -14,6 +14,7 @@
14#include <linux/errno.h> 14#include <linux/errno.h>
15#include <linux/workqueue.h> 15#include <linux/workqueue.h>
16#include <linux/time.h> 16#include <linux/time.h>
17#include <linux/kthread.h>
17 18
18#include <asm/lowcore.h> 19#include <asm/lowcore.h>
19 20
@@ -56,8 +57,6 @@ s390_collect_crw_info(void *param)
56 unsigned int chain; 57 unsigned int chain;
57 58
58 sem = (struct semaphore *)param; 59 sem = (struct semaphore *)param;
59 /* Set a nice name. */
60 daemonize("kmcheck");
61repeat: 60repeat:
62 down_interruptible(sem); 61 down_interruptible(sem);
63 slow = 0; 62 slow = 0;
@@ -516,7 +515,7 @@ arch_initcall(machine_check_init);
516static int __init 515static int __init
517machine_check_crw_init (void) 516machine_check_crw_init (void)
518{ 517{
519 kernel_thread(s390_collect_crw_info, &m_sem, CLONE_FS|CLONE_FILES); 518 kthread_run(s390_collect_crw_info, &m_sem, "kmcheck");
520 ctl_set_bit(14, 28); /* enable channel report MCH */ 519 ctl_set_bit(14, 28); /* enable channel report MCH */
521 return 0; 520 return 0;
522} 521}
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 4682c8b8bd24..909731b99d26 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -167,7 +167,7 @@ zfcp_fsf_scsi_er_timeout_handler(unsigned long data)
167 * initiates adapter recovery which is done 167 * initiates adapter recovery which is done
168 * asynchronously 168 * asynchronously
169 * 169 *
170 * returns: 0 - initiated action succesfully 170 * returns: 0 - initiated action successfully
171 * <0 - failed to initiate action 171 * <0 - failed to initiate action
172 */ 172 */
173int 173int
@@ -203,7 +203,7 @@ zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *adapter, int clear_mask)
203 * purpose: Wrappper for zfcp_erp_adapter_reopen_internal 203 * purpose: Wrappper for zfcp_erp_adapter_reopen_internal
204 * used to ensure the correct locking 204 * used to ensure the correct locking
205 * 205 *
206 * returns: 0 - initiated action succesfully 206 * returns: 0 - initiated action successfully
207 * <0 - failed to initiate action 207 * <0 - failed to initiate action
208 */ 208 */
209int 209int
@@ -469,7 +469,7 @@ zfcp_test_link(struct zfcp_port *port)
469 * initiates Forced Reopen recovery which is done 469 * initiates Forced Reopen recovery which is done
470 * asynchronously 470 * asynchronously
471 * 471 *
472 * returns: 0 - initiated action succesfully 472 * returns: 0 - initiated action successfully
473 * <0 - failed to initiate action 473 * <0 - failed to initiate action
474 */ 474 */
475static int 475static int
@@ -509,7 +509,7 @@ zfcp_erp_port_forced_reopen_internal(struct zfcp_port *port, int clear_mask)
509 * purpose: Wrappper for zfcp_erp_port_forced_reopen_internal 509 * purpose: Wrappper for zfcp_erp_port_forced_reopen_internal
510 * used to ensure the correct locking 510 * used to ensure the correct locking
511 * 511 *
512 * returns: 0 - initiated action succesfully 512 * returns: 0 - initiated action successfully
513 * <0 - failed to initiate action 513 * <0 - failed to initiate action
514 */ 514 */
515int 515int
@@ -536,7 +536,7 @@ zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear_mask)
536 * initiates Reopen recovery which is done 536 * initiates Reopen recovery which is done
537 * asynchronously 537 * asynchronously
538 * 538 *
539 * returns: 0 - initiated action succesfully 539 * returns: 0 - initiated action successfully
540 * <0 - failed to initiate action 540 * <0 - failed to initiate action
541 */ 541 */
542static int 542static int
@@ -605,7 +605,7 @@ zfcp_erp_port_reopen(struct zfcp_port *port, int clear_mask)
605 * initiates Reopen recovery which is done 605 * initiates Reopen recovery which is done
606 * asynchronously 606 * asynchronously
607 * 607 *
608 * returns: 0 - initiated action succesfully 608 * returns: 0 - initiated action successfully
609 * <0 - failed to initiate action 609 * <0 - failed to initiate action
610 */ 610 */
611static int 611static int
@@ -1805,7 +1805,7 @@ zfcp_erp_modify_unit_status(struct zfcp_unit *unit, u32 mask, int set_or_clear)
1805 * purpose: Wrappper for zfcp_erp_port_reopen_all_internal 1805 * purpose: Wrappper for zfcp_erp_port_reopen_all_internal
1806 * used to ensure the correct locking 1806 * used to ensure the correct locking
1807 * 1807 *
1808 * returns: 0 - initiated action succesfully 1808 * returns: 0 - initiated action successfully
1809 * <0 - failed to initiate action 1809 * <0 - failed to initiate action
1810 */ 1810 */
1811int 1811int