aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block/dasd_eckd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/block/dasd_eckd.c')
-rw-r--r--drivers/s390/block/dasd_eckd.c53
1 files changed, 40 insertions, 13 deletions
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 2fb2b9ea97ec..108332b44d98 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -20,6 +20,7 @@
20#include <linux/compat.h> 20#include <linux/compat.h>
21#include <linux/init.h> 21#include <linux/init.h>
22 22
23#include <asm/css_chars.h>
23#include <asm/debug.h> 24#include <asm/debug.h>
24#include <asm/idals.h> 25#include <asm/idals.h>
25#include <asm/ebcdic.h> 26#include <asm/ebcdic.h>
@@ -31,8 +32,6 @@
31 32
32#include "dasd_int.h" 33#include "dasd_int.h"
33#include "dasd_eckd.h" 34#include "dasd_eckd.h"
34#include "../cio/chsc.h"
35
36 35
37#ifdef PRINTK_HEADER 36#ifdef PRINTK_HEADER
38#undef PRINTK_HEADER 37#undef PRINTK_HEADER
@@ -140,6 +139,10 @@ dasd_eckd_set_online(struct ccw_device *cdev)
140static const int sizes_trk0[] = { 28, 148, 84 }; 139static const int sizes_trk0[] = { 28, 148, 84 };
141#define LABEL_SIZE 140 140#define LABEL_SIZE 140
142 141
142/* head and record addresses of count_area read in analysis ccw */
143static const int count_area_head[] = { 0, 0, 0, 0, 2 };
144static const int count_area_rec[] = { 1, 2, 3, 4, 1 };
145
143static inline unsigned int 146static inline unsigned int
144round_up_multiple(unsigned int no, unsigned int mult) 147round_up_multiple(unsigned int no, unsigned int mult)
145{ 148{
@@ -212,7 +215,7 @@ check_XRC (struct ccw1 *de_ccw,
212 215
213 rc = get_sync_clock(&data->ep_sys_time); 216 rc = get_sync_clock(&data->ep_sys_time);
214 /* Ignore return code if sync clock is switched off. */ 217 /* Ignore return code if sync clock is switched off. */
215 if (rc == -ENOSYS || rc == -EACCES) 218 if (rc == -EOPNOTSUPP || rc == -EACCES)
216 rc = 0; 219 rc = 0;
217 220
218 de_ccw->count = sizeof(struct DE_eckd_data); 221 de_ccw->count = sizeof(struct DE_eckd_data);
@@ -323,7 +326,7 @@ static int check_XRC_on_prefix(struct PFX_eckd_data *pfxdata,
323 326
324 rc = get_sync_clock(&pfxdata->define_extent.ep_sys_time); 327 rc = get_sync_clock(&pfxdata->define_extent.ep_sys_time);
325 /* Ignore return code if sync clock is switched off. */ 328 /* Ignore return code if sync clock is switched off. */
326 if (rc == -ENOSYS || rc == -EACCES) 329 if (rc == -EOPNOTSUPP || rc == -EACCES)
327 rc = 0; 330 rc = 0;
328 return rc; 331 return rc;
329} 332}
@@ -1507,7 +1510,8 @@ static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device,
1507 * call might change behaviour of DASD devices. 1510 * call might change behaviour of DASD devices.
1508 */ 1511 */
1509static int 1512static int
1510dasd_eckd_psf_ssc(struct dasd_device *device, int enable_pav) 1513dasd_eckd_psf_ssc(struct dasd_device *device, int enable_pav,
1514 unsigned long flags)
1511{ 1515{
1512 struct dasd_ccw_req *cqr; 1516 struct dasd_ccw_req *cqr;
1513 int rc; 1517 int rc;
@@ -1516,10 +1520,19 @@ dasd_eckd_psf_ssc(struct dasd_device *device, int enable_pav)
1516 if (IS_ERR(cqr)) 1520 if (IS_ERR(cqr))
1517 return PTR_ERR(cqr); 1521 return PTR_ERR(cqr);
1518 1522
1523 /*
1524 * set flags e.g. turn on failfast, to prevent blocking
1525 * the calling function should handle failed requests
1526 */
1527 cqr->flags |= flags;
1528
1519 rc = dasd_sleep_on(cqr); 1529 rc = dasd_sleep_on(cqr);
1520 if (!rc) 1530 if (!rc)
1521 /* trigger CIO to reprobe devices */ 1531 /* trigger CIO to reprobe devices */
1522 css_schedule_reprobe(); 1532 css_schedule_reprobe();
1533 else if (cqr->intrc == -EAGAIN)
1534 rc = -EAGAIN;
1535
1523 dasd_sfree_request(cqr, cqr->memdev); 1536 dasd_sfree_request(cqr, cqr->memdev);
1524 return rc; 1537 return rc;
1525} 1538}
@@ -1527,7 +1540,8 @@ dasd_eckd_psf_ssc(struct dasd_device *device, int enable_pav)
1527/* 1540/*
1528 * Valide storage server of current device. 1541 * Valide storage server of current device.
1529 */ 1542 */
1530static void dasd_eckd_validate_server(struct dasd_device *device) 1543static int dasd_eckd_validate_server(struct dasd_device *device,
1544 unsigned long flags)
1531{ 1545{
1532 int rc; 1546 int rc;
1533 struct dasd_eckd_private *private; 1547 struct dasd_eckd_private *private;
@@ -1536,17 +1550,18 @@ static void dasd_eckd_validate_server(struct dasd_device *device)
1536 private = (struct dasd_eckd_private *) device->private; 1550 private = (struct dasd_eckd_private *) device->private;
1537 if (private->uid.type == UA_BASE_PAV_ALIAS || 1551 if (private->uid.type == UA_BASE_PAV_ALIAS ||
1538 private->uid.type == UA_HYPER_PAV_ALIAS) 1552 private->uid.type == UA_HYPER_PAV_ALIAS)
1539 return; 1553 return 0;
1540 if (dasd_nopav || MACHINE_IS_VM) 1554 if (dasd_nopav || MACHINE_IS_VM)
1541 enable_pav = 0; 1555 enable_pav = 0;
1542 else 1556 else
1543 enable_pav = 1; 1557 enable_pav = 1;
1544 rc = dasd_eckd_psf_ssc(device, enable_pav); 1558 rc = dasd_eckd_psf_ssc(device, enable_pav, flags);
1545 1559
1546 /* may be requested feature is not available on server, 1560 /* may be requested feature is not available on server,
1547 * therefore just report error and go ahead */ 1561 * therefore just report error and go ahead */
1548 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "PSF-SSC for SSID %04x " 1562 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "PSF-SSC for SSID %04x "
1549 "returned rc=%d", private->uid.ssid, rc); 1563 "returned rc=%d", private->uid.ssid, rc);
1564 return rc;
1550} 1565}
1551 1566
1552/* 1567/*
@@ -1556,7 +1571,13 @@ static void dasd_eckd_do_validate_server(struct work_struct *work)
1556{ 1571{
1557 struct dasd_device *device = container_of(work, struct dasd_device, 1572 struct dasd_device *device = container_of(work, struct dasd_device,
1558 kick_validate); 1573 kick_validate);
1559 dasd_eckd_validate_server(device); 1574 if (dasd_eckd_validate_server(device, DASD_CQR_FLAGS_FAILFAST)
1575 == -EAGAIN) {
1576 /* schedule worker again if failed */
1577 schedule_work(&device->kick_validate);
1578 return;
1579 }
1580
1560 dasd_put_device(device); 1581 dasd_put_device(device);
1561} 1582}
1562 1583
@@ -1685,7 +1706,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
1685 if (rc) 1706 if (rc)
1686 goto out_err2; 1707 goto out_err2;
1687 1708
1688 dasd_eckd_validate_server(device); 1709 dasd_eckd_validate_server(device, 0);
1689 1710
1690 /* device may report different configuration data after LCU setup */ 1711 /* device may report different configuration data after LCU setup */
1691 rc = dasd_eckd_read_conf(device); 1712 rc = dasd_eckd_read_conf(device);
@@ -1922,7 +1943,10 @@ static int dasd_eckd_end_analysis(struct dasd_block *block)
1922 count_area = NULL; 1943 count_area = NULL;
1923 for (i = 0; i < 3; i++) { 1944 for (i = 0; i < 3; i++) {
1924 if (private->count_area[i].kl != 4 || 1945 if (private->count_area[i].kl != 4 ||
1925 private->count_area[i].dl != dasd_eckd_cdl_reclen(i) - 4) { 1946 private->count_area[i].dl != dasd_eckd_cdl_reclen(i) - 4 ||
1947 private->count_area[i].cyl != 0 ||
1948 private->count_area[i].head != count_area_head[i] ||
1949 private->count_area[i].record != count_area_rec[i]) {
1926 private->uses_cdl = 0; 1950 private->uses_cdl = 0;
1927 break; 1951 break;
1928 } 1952 }
@@ -1934,7 +1958,10 @@ static int dasd_eckd_end_analysis(struct dasd_block *block)
1934 for (i = 0; i < 5; i++) { 1958 for (i = 0; i < 5; i++) {
1935 if ((private->count_area[i].kl != 0) || 1959 if ((private->count_area[i].kl != 0) ||
1936 (private->count_area[i].dl != 1960 (private->count_area[i].dl !=
1937 private->count_area[0].dl)) 1961 private->count_area[0].dl) ||
1962 private->count_area[i].cyl != 0 ||
1963 private->count_area[i].head != count_area_head[i] ||
1964 private->count_area[i].record != count_area_rec[i])
1938 break; 1965 break;
1939 } 1966 }
1940 if (i == 5) 1967 if (i == 5)
@@ -4153,7 +4180,7 @@ static int dasd_eckd_restore_device(struct dasd_device *device)
4153 rc = dasd_alias_make_device_known_to_lcu(device); 4180 rc = dasd_alias_make_device_known_to_lcu(device);
4154 if (rc) 4181 if (rc)
4155 return rc; 4182 return rc;
4156 dasd_eckd_validate_server(device); 4183 dasd_eckd_validate_server(device, DASD_CQR_FLAGS_FAILFAST);
4157 4184
4158 /* RE-Read Configuration Data */ 4185 /* RE-Read Configuration Data */
4159 rc = dasd_eckd_read_conf(device); 4186 rc = dasd_eckd_read_conf(device);