aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/s390/block
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/s390/block')
-rw-r--r--drivers/s390/block/Kconfig24
-rw-r--r--drivers/s390/block/dasd.c376
-rw-r--r--drivers/s390/block/dasd_3990_erp.c27
-rw-r--r--drivers/s390/block/dasd_alias.c10
-rw-r--r--drivers/s390/block/dasd_devmap.c187
-rw-r--r--drivers/s390/block/dasd_diag.c28
-rw-r--r--drivers/s390/block/dasd_diag.h4
-rw-r--r--drivers/s390/block/dasd_eckd.c810
-rw-r--r--drivers/s390/block/dasd_eckd.h18
-rw-r--r--drivers/s390/block/dasd_eer.c3
-rw-r--r--drivers/s390/block/dasd_erp.c3
-rw-r--r--drivers/s390/block/dasd_fba.c27
-rw-r--r--drivers/s390/block/dasd_genhd.c4
-rw-r--r--drivers/s390/block/dasd_int.h38
-rw-r--r--drivers/s390/block/dasd_ioctl.c143
-rw-r--r--drivers/s390/block/dasd_proc.c1
-rw-r--r--drivers/s390/block/dcssblk.c5
-rw-r--r--drivers/s390/block/xpram.c4
18 files changed, 1317 insertions, 395 deletions
diff --git a/drivers/s390/block/Kconfig b/drivers/s390/block/Kconfig
index 07883197f474..8e477bb1f3f6 100644
--- a/drivers/s390/block/Kconfig
+++ b/drivers/s390/block/Kconfig
@@ -2,7 +2,8 @@ comment "S/390 block device drivers"
2 depends on S390 && BLOCK 2 depends on S390 && BLOCK
3 3
4config BLK_DEV_XPRAM 4config BLK_DEV_XPRAM
5 tristate "XPRAM disk support" 5 def_tristate m
6 prompt "XPRAM disk support"
6 depends on S390 && BLOCK 7 depends on S390 && BLOCK
7 help 8 help
8 Select this option if you want to use your expanded storage on S/390 9 Select this option if you want to use your expanded storage on S/390
@@ -12,13 +13,15 @@ config BLK_DEV_XPRAM
12 xpram. If unsure, say "N". 13 xpram. If unsure, say "N".
13 14
14config DCSSBLK 15config DCSSBLK
15 tristate "DCSSBLK support" 16 def_tristate m
17 prompt "DCSSBLK support"
16 depends on S390 && BLOCK 18 depends on S390 && BLOCK
17 help 19 help
18 Support for dcss block device 20 Support for dcss block device
19 21
20config DASD 22config DASD
21 tristate "Support for DASD devices" 23 def_tristate y
24 prompt "Support for DASD devices"
22 depends on CCW && BLOCK 25 depends on CCW && BLOCK
23 select IOSCHED_DEADLINE 26 select IOSCHED_DEADLINE
24 help 27 help
@@ -27,28 +30,32 @@ config DASD
27 natively on a single image or an LPAR. 30 natively on a single image or an LPAR.
28 31
29config DASD_PROFILE 32config DASD_PROFILE
30 bool "Profiling support for dasd devices" 33 def_bool y
34 prompt "Profiling support for dasd devices"
31 depends on DASD 35 depends on DASD
32 help 36 help
33 Enable this option if you want to see profiling information 37 Enable this option if you want to see profiling information
34 in /proc/dasd/statistics. 38 in /proc/dasd/statistics.
35 39
36config DASD_ECKD 40config DASD_ECKD
37 tristate "Support for ECKD Disks" 41 def_tristate y
42 prompt "Support for ECKD Disks"
38 depends on DASD 43 depends on DASD
39 help 44 help
40 ECKD devices are the most commonly used devices. You should enable 45 ECKD devices are the most commonly used devices. You should enable
41 this option unless you are very sure to have no ECKD device. 46 this option unless you are very sure to have no ECKD device.
42 47
43config DASD_FBA 48config DASD_FBA
44 tristate "Support for FBA Disks" 49 def_tristate y
50 prompt "Support for FBA Disks"
45 depends on DASD 51 depends on DASD
46 help 52 help
47 Select this option to be able to access FBA devices. It is safe to 53 Select this option to be able to access FBA devices. It is safe to
48 say "Y". 54 say "Y".
49 55
50config DASD_DIAG 56config DASD_DIAG
51 tristate "Support for DIAG access to Disks" 57 def_tristate y
58 prompt "Support for DIAG access to Disks"
52 depends on DASD 59 depends on DASD
53 help 60 help
54 Select this option if you want to use Diagnose250 command to access 61 Select this option if you want to use Diagnose250 command to access
@@ -56,7 +63,8 @@ config DASD_DIAG
56 say "N". 63 say "N".
57 64
58config DASD_EER 65config DASD_EER
59 bool "Extended error reporting (EER)" 66 def_bool y
67 prompt "Extended error reporting (EER)"
60 depends on DASD 68 depends on DASD
61 help 69 help
62 This driver provides a character device interface to the 70 This driver provides a character device interface to the
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 8373ca0de8e0..86b6f1cc1b10 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -11,6 +11,7 @@
11#define KMSG_COMPONENT "dasd" 11#define KMSG_COMPONENT "dasd"
12#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 12#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
13 13
14#include <linux/kernel_stat.h>
14#include <linux/kmod.h> 15#include <linux/kmod.h>
15#include <linux/init.h> 16#include <linux/init.h>
16#include <linux/interrupt.h> 17#include <linux/interrupt.h>
@@ -21,7 +22,6 @@
21#include <linux/hdreg.h> 22#include <linux/hdreg.h>
22#include <linux/async.h> 23#include <linux/async.h>
23#include <linux/mutex.h> 24#include <linux/mutex.h>
24#include <linux/smp_lock.h>
25 25
26#include <asm/ccwdev.h> 26#include <asm/ccwdev.h>
27#include <asm/ebcdic.h> 27#include <asm/ebcdic.h>
@@ -369,6 +369,11 @@ dasd_state_ready_to_online(struct dasd_device * device)
369 device->state = DASD_STATE_ONLINE; 369 device->state = DASD_STATE_ONLINE;
370 if (device->block) { 370 if (device->block) {
371 dasd_schedule_block_bh(device->block); 371 dasd_schedule_block_bh(device->block);
372 if ((device->features & DASD_FEATURE_USERAW)) {
373 disk = device->block->gdp;
374 kobject_uevent(&disk_to_dev(disk)->kobj, KOBJ_CHANGE);
375 return 0;
376 }
372 disk = device->block->bdev->bd_disk; 377 disk = device->block->bdev->bd_disk;
373 disk_part_iter_init(&piter, disk, DISK_PITER_INCL_PART0); 378 disk_part_iter_init(&piter, disk, DISK_PITER_INCL_PART0);
374 while ((part = disk_part_iter_next(&piter))) 379 while ((part = disk_part_iter_next(&piter)))
@@ -394,7 +399,7 @@ static int dasd_state_online_to_ready(struct dasd_device *device)
394 return rc; 399 return rc;
395 } 400 }
396 device->state = DASD_STATE_READY; 401 device->state = DASD_STATE_READY;
397 if (device->block) { 402 if (device->block && !(device->features & DASD_FEATURE_USERAW)) {
398 disk = device->block->bdev->bd_disk; 403 disk = device->block->bdev->bd_disk;
399 disk_part_iter_init(&piter, disk, DISK_PITER_INCL_PART0); 404 disk_part_iter_init(&piter, disk, DISK_PITER_INCL_PART0);
400 while ((part = disk_part_iter_next(&piter))) 405 while ((part = disk_part_iter_next(&piter)))
@@ -745,10 +750,6 @@ struct dasd_ccw_req *dasd_smalloc_request(int magic, int cplength,
745 char *data; 750 char *data;
746 int size; 751 int size;
747 752
748 /* Sanity checks */
749 BUG_ON(datasize > PAGE_SIZE ||
750 (cplength*sizeof(struct ccw1)) > PAGE_SIZE);
751
752 size = (sizeof(struct dasd_ccw_req) + 7L) & -8L; 753 size = (sizeof(struct dasd_ccw_req) + 7L) & -8L;
753 if (cplength > 0) 754 if (cplength > 0)
754 size += cplength * sizeof(struct ccw1); 755 size += cplength * sizeof(struct ccw1);
@@ -854,7 +855,6 @@ int dasd_term_IO(struct dasd_ccw_req *cqr)
854 rc = ccw_device_clear(device->cdev, (long) cqr); 855 rc = ccw_device_clear(device->cdev, (long) cqr);
855 switch (rc) { 856 switch (rc) {
856 case 0: /* termination successful */ 857 case 0: /* termination successful */
857 cqr->retries--;
858 cqr->status = DASD_CQR_CLEAR_PENDING; 858 cqr->status = DASD_CQR_CLEAR_PENDING;
859 cqr->stopclk = get_clock(); 859 cqr->stopclk = get_clock();
860 cqr->starttime = 0; 860 cqr->starttime = 0;
@@ -906,6 +906,16 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
906 return rc; 906 return rc;
907 } 907 }
908 device = (struct dasd_device *) cqr->startdev; 908 device = (struct dasd_device *) cqr->startdev;
909 if (((cqr->block &&
910 test_bit(DASD_FLAG_LOCK_STOLEN, &cqr->block->base->flags)) ||
911 test_bit(DASD_FLAG_LOCK_STOLEN, &device->flags)) &&
912 !test_bit(DASD_CQR_ALLOW_SLOCK, &cqr->flags)) {
913 DBF_DEV_EVENT(DBF_DEBUG, device, "start_IO: return request %p "
914 "because of stolen lock", cqr);
915 cqr->status = DASD_CQR_ERROR;
916 cqr->intrc = -EPERM;
917 return -EPERM;
918 }
909 if (cqr->retries < 0) { 919 if (cqr->retries < 0) {
910 /* internal error 14 - start_IO run out of retries */ 920 /* internal error 14 - start_IO run out of retries */
911 sprintf(errorstring, "14 %p", cqr); 921 sprintf(errorstring, "14 %p", cqr);
@@ -917,6 +927,11 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
917 cqr->startclk = get_clock(); 927 cqr->startclk = get_clock();
918 cqr->starttime = jiffies; 928 cqr->starttime = jiffies;
919 cqr->retries--; 929 cqr->retries--;
930 if (!test_bit(DASD_CQR_VERIFY_PATH, &cqr->flags)) {
931 cqr->lpm &= device->path_data.opm;
932 if (!cqr->lpm)
933 cqr->lpm = device->path_data.opm;
934 }
920 if (cqr->cpmode == 1) { 935 if (cqr->cpmode == 1) {
921 rc = ccw_device_tm_start(device->cdev, cqr->cpaddr, 936 rc = ccw_device_tm_start(device->cdev, cqr->cpaddr,
922 (long) cqr, cqr->lpm); 937 (long) cqr, cqr->lpm);
@@ -929,35 +944,53 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
929 cqr->status = DASD_CQR_IN_IO; 944 cqr->status = DASD_CQR_IN_IO;
930 break; 945 break;
931 case -EBUSY: 946 case -EBUSY:
932 DBF_DEV_EVENT(DBF_DEBUG, device, "%s", 947 DBF_DEV_EVENT(DBF_WARNING, device, "%s",
933 "start_IO: device busy, retry later"); 948 "start_IO: device busy, retry later");
934 break; 949 break;
935 case -ETIMEDOUT: 950 case -ETIMEDOUT:
936 DBF_DEV_EVENT(DBF_DEBUG, device, "%s", 951 DBF_DEV_EVENT(DBF_WARNING, device, "%s",
937 "start_IO: request timeout, retry later"); 952 "start_IO: request timeout, retry later");
938 break; 953 break;
939 case -EACCES: 954 case -EACCES:
940 /* -EACCES indicates that the request used only a 955 /* -EACCES indicates that the request used only a subset of the
941 * subset of the available pathes and all these 956 * available paths and all these paths are gone. If the lpm of
942 * pathes are gone. 957 * this request was only a subset of the opm (e.g. the ppm) then
943 * Do a retry with all available pathes. 958 * we just do a retry with all available paths.
959 * If we already use the full opm, something is amiss, and we
960 * need a full path verification.
944 */ 961 */
945 cqr->lpm = LPM_ANYPATH; 962 if (test_bit(DASD_CQR_VERIFY_PATH, &cqr->flags)) {
946 DBF_DEV_EVENT(DBF_DEBUG, device, "%s", 963 DBF_DEV_EVENT(DBF_WARNING, device,
947 "start_IO: selected pathes gone," 964 "start_IO: selected paths gone (%x)",
948 " retry on all pathes"); 965 cqr->lpm);
966 } else if (cqr->lpm != device->path_data.opm) {
967 cqr->lpm = device->path_data.opm;
968 DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
969 "start_IO: selected paths gone,"
970 " retry on all paths");
971 } else {
972 DBF_DEV_EVENT(DBF_WARNING, device, "%s",
973 "start_IO: all paths in opm gone,"
974 " do path verification");
975 dasd_generic_last_path_gone(device);
976 device->path_data.opm = 0;
977 device->path_data.ppm = 0;
978 device->path_data.npm = 0;
979 device->path_data.tbvpm =
980 ccw_device_get_path_mask(device->cdev);
981 }
949 break; 982 break;
950 case -ENODEV: 983 case -ENODEV:
951 DBF_DEV_EVENT(DBF_DEBUG, device, "%s", 984 DBF_DEV_EVENT(DBF_WARNING, device, "%s",
952 "start_IO: -ENODEV device gone, retry"); 985 "start_IO: -ENODEV device gone, retry");
953 break; 986 break;
954 case -EIO: 987 case -EIO:
955 DBF_DEV_EVENT(DBF_DEBUG, device, "%s", 988 DBF_DEV_EVENT(DBF_WARNING, device, "%s",
956 "start_IO: -EIO device gone, retry"); 989 "start_IO: -EIO device gone, retry");
957 break; 990 break;
958 case -EINVAL: 991 case -EINVAL:
959 /* most likely caused in power management context */ 992 /* most likely caused in power management context */
960 DBF_DEV_EVENT(DBF_DEBUG, device, "%s", 993 DBF_DEV_EVENT(DBF_WARNING, device, "%s",
961 "start_IO: -EINVAL device currently " 994 "start_IO: -EINVAL device currently "
962 "not accessible"); 995 "not accessible");
963 break; 996 break;
@@ -1077,6 +1110,7 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
1077 unsigned long long now; 1110 unsigned long long now;
1078 int expires; 1111 int expires;
1079 1112
1113 kstat_cpu(smp_processor_id()).irqs[IOINT_DAS]++;
1080 if (IS_ERR(irb)) { 1114 if (IS_ERR(irb)) {
1081 switch (PTR_ERR(irb)) { 1115 switch (PTR_ERR(irb)) {
1082 case -EIO: 1116 case -EIO:
@@ -1095,23 +1129,29 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
1095 } 1129 }
1096 1130
1097 now = get_clock(); 1131 now = get_clock();
1098
1099 /* check for unsolicited interrupts */
1100 cqr = (struct dasd_ccw_req *) intparm; 1132 cqr = (struct dasd_ccw_req *) intparm;
1101 if (!cqr || ((scsw_cc(&irb->scsw) == 1) && 1133 /* check for conditions that should be handled immediately */
1102 (scsw_fctl(&irb->scsw) & SCSW_FCTL_START_FUNC) && 1134 if (!cqr ||
1103 (scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND))) { 1135 !(scsw_dstat(&irb->scsw) == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) &&
1104 if (cqr && cqr->status == DASD_CQR_IN_IO) 1136 scsw_cstat(&irb->scsw) == 0)) {
1105 cqr->status = DASD_CQR_QUEUED; 1137 if (cqr)
1138 memcpy(&cqr->irb, irb, sizeof(*irb));
1106 device = dasd_device_from_cdev_locked(cdev); 1139 device = dasd_device_from_cdev_locked(cdev);
1107 if (!IS_ERR(device)) { 1140 if (IS_ERR(device))
1108 dasd_device_clear_timer(device); 1141 return;
1109 device->discipline->handle_unsolicited_interrupt(device, 1142 /* ignore unsolicited interrupts for DIAG discipline */
1110 irb); 1143 if (device->discipline == dasd_diag_discipline_pointer) {
1111 dasd_put_device(device); 1144 dasd_put_device(device);
1145 return;
1112 } 1146 }
1113 return; 1147 device->discipline->dump_sense_dbf(device, irb, "int");
1148 if (device->features & DASD_FEATURE_ERPLOG)
1149 device->discipline->dump_sense(device, cqr, irb);
1150 device->discipline->check_for_device_change(device, cqr, irb);
1151 dasd_put_device(device);
1114 } 1152 }
1153 if (!cqr)
1154 return;
1115 1155
1116 device = (struct dasd_device *) cqr->startdev; 1156 device = (struct dasd_device *) cqr->startdev;
1117 if (!device || 1157 if (!device ||
@@ -1151,25 +1191,19 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
1151 struct dasd_ccw_req, devlist); 1191 struct dasd_ccw_req, devlist);
1152 } 1192 }
1153 } else { /* error */ 1193 } else { /* error */
1154 memcpy(&cqr->irb, irb, sizeof(struct irb));
1155 /* log sense for every failed I/O to s390 debugfeature */
1156 dasd_log_sense_dbf(cqr, irb);
1157 if (device->features & DASD_FEATURE_ERPLOG) {
1158 dasd_log_sense(cqr, irb);
1159 }
1160
1161 /* 1194 /*
1162 * If we don't want complex ERP for this request, then just 1195 * If we don't want complex ERP for this request, then just
1163 * reset this and retry it in the fastpath 1196 * reset this and retry it in the fastpath
1164 */ 1197 */
1165 if (!test_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags) && 1198 if (!test_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags) &&
1166 cqr->retries > 0) { 1199 cqr->retries > 0) {
1167 if (cqr->lpm == LPM_ANYPATH) 1200 if (cqr->lpm == device->path_data.opm)
1168 DBF_DEV_EVENT(DBF_DEBUG, device, 1201 DBF_DEV_EVENT(DBF_DEBUG, device,
1169 "default ERP in fastpath " 1202 "default ERP in fastpath "
1170 "(%i retries left)", 1203 "(%i retries left)",
1171 cqr->retries); 1204 cqr->retries);
1172 cqr->lpm = LPM_ANYPATH; 1205 if (!test_bit(DASD_CQR_VERIFY_PATH, &cqr->flags))
1206 cqr->lpm = device->path_data.opm;
1173 cqr->status = DASD_CQR_QUEUED; 1207 cqr->status = DASD_CQR_QUEUED;
1174 next = cqr; 1208 next = cqr;
1175 } else 1209 } else
@@ -1197,13 +1231,13 @@ enum uc_todo dasd_generic_uc_handler(struct ccw_device *cdev, struct irb *irb)
1197 goto out; 1231 goto out;
1198 if (test_bit(DASD_FLAG_OFFLINE, &device->flags) || 1232 if (test_bit(DASD_FLAG_OFFLINE, &device->flags) ||
1199 device->state != device->target || 1233 device->state != device->target ||
1200 !device->discipline->handle_unsolicited_interrupt){ 1234 !device->discipline->check_for_device_change){
1201 dasd_put_device(device); 1235 dasd_put_device(device);
1202 goto out; 1236 goto out;
1203 } 1237 }
1204 1238 if (device->discipline->dump_sense_dbf)
1205 dasd_device_clear_timer(device); 1239 device->discipline->dump_sense_dbf(device, irb, "uc");
1206 device->discipline->handle_unsolicited_interrupt(device, irb); 1240 device->discipline->check_for_device_change(device, NULL, irb);
1207 dasd_put_device(device); 1241 dasd_put_device(device);
1208out: 1242out:
1209 return UC_TODO_RETRY; 1243 return UC_TODO_RETRY;
@@ -1353,8 +1387,14 @@ static void __dasd_device_start_head(struct dasd_device *device)
1353 cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, devlist); 1387 cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, devlist);
1354 if (cqr->status != DASD_CQR_QUEUED) 1388 if (cqr->status != DASD_CQR_QUEUED)
1355 return; 1389 return;
1356 /* when device is stopped, return request to previous layer */ 1390 /* when device is stopped, return request to previous layer
1357 if (device->stopped) { 1391 * exception: only the disconnect or unresumed bits are set and the
1392 * cqr is a path verification request
1393 */
1394 if (device->stopped &&
1395 !(!(device->stopped & ~(DASD_STOPPED_DC_WAIT | DASD_UNRESUMED_PM))
1396 && test_bit(DASD_CQR_VERIFY_PATH, &cqr->flags))) {
1397 cqr->intrc = -EAGAIN;
1358 cqr->status = DASD_CQR_CLEARED; 1398 cqr->status = DASD_CQR_CLEARED;
1359 dasd_schedule_device_bh(device); 1399 dasd_schedule_device_bh(device);
1360 return; 1400 return;
@@ -1370,6 +1410,23 @@ static void __dasd_device_start_head(struct dasd_device *device)
1370 dasd_device_set_timer(device, 50); 1410 dasd_device_set_timer(device, 50);
1371} 1411}
1372 1412
1413static void __dasd_device_check_path_events(struct dasd_device *device)
1414{
1415 int rc;
1416
1417 if (device->path_data.tbvpm) {
1418 if (device->stopped & ~(DASD_STOPPED_DC_WAIT |
1419 DASD_UNRESUMED_PM))
1420 return;
1421 rc = device->discipline->verify_path(
1422 device, device->path_data.tbvpm);
1423 if (rc)
1424 dasd_device_set_timer(device, 50);
1425 else
1426 device->path_data.tbvpm = 0;
1427 }
1428};
1429
1373/* 1430/*
1374 * Go through all request on the dasd_device request queue, 1431 * Go through all request on the dasd_device request queue,
1375 * terminate them on the cdev if necessary, and return them to the 1432 * terminate them on the cdev if necessary, and return them to the
@@ -1444,6 +1501,7 @@ static void dasd_device_tasklet(struct dasd_device *device)
1444 __dasd_device_check_expire(device); 1501 __dasd_device_check_expire(device);
1445 /* find final requests on ccw queue */ 1502 /* find final requests on ccw queue */
1446 __dasd_device_process_ccw_queue(device, &final_queue); 1503 __dasd_device_process_ccw_queue(device, &final_queue);
1504 __dasd_device_check_path_events(device);
1447 spin_unlock_irq(get_ccwdev_lock(device->cdev)); 1505 spin_unlock_irq(get_ccwdev_lock(device->cdev));
1448 /* Now call the callback function of requests with final status */ 1506 /* Now call the callback function of requests with final status */
1449 __dasd_device_process_final_queue(device, &final_queue); 1507 __dasd_device_process_final_queue(device, &final_queue);
@@ -1600,7 +1658,12 @@ static int _dasd_sleep_on(struct dasd_ccw_req *maincqr, int interruptible)
1600 continue; 1658 continue;
1601 if (cqr->status != DASD_CQR_FILLED) /* could be failed */ 1659 if (cqr->status != DASD_CQR_FILLED) /* could be failed */
1602 continue; 1660 continue;
1603 1661 if (test_bit(DASD_FLAG_LOCK_STOLEN, &device->flags) &&
1662 !test_bit(DASD_CQR_ALLOW_SLOCK, &cqr->flags)) {
1663 cqr->status = DASD_CQR_FAILED;
1664 cqr->intrc = -EPERM;
1665 continue;
1666 }
1604 /* Non-temporary stop condition will trigger fail fast */ 1667 /* Non-temporary stop condition will trigger fail fast */
1605 if (device->stopped & ~DASD_STOPPED_PENDING && 1668 if (device->stopped & ~DASD_STOPPED_PENDING &&
1606 test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) && 1669 test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) &&
@@ -1608,7 +1671,6 @@ static int _dasd_sleep_on(struct dasd_ccw_req *maincqr, int interruptible)
1608 cqr->status = DASD_CQR_FAILED; 1671 cqr->status = DASD_CQR_FAILED;
1609 continue; 1672 continue;
1610 } 1673 }
1611
1612 /* Don't try to start requests if device is stopped */ 1674 /* Don't try to start requests if device is stopped */
1613 if (interruptible) { 1675 if (interruptible) {
1614 rc = wait_event_interruptible( 1676 rc = wait_event_interruptible(
@@ -1680,11 +1742,20 @@ int dasd_sleep_on_interruptible(struct dasd_ccw_req *cqr)
1680static inline int _dasd_term_running_cqr(struct dasd_device *device) 1742static inline int _dasd_term_running_cqr(struct dasd_device *device)
1681{ 1743{
1682 struct dasd_ccw_req *cqr; 1744 struct dasd_ccw_req *cqr;
1745 int rc;
1683 1746
1684 if (list_empty(&device->ccw_queue)) 1747 if (list_empty(&device->ccw_queue))
1685 return 0; 1748 return 0;
1686 cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, devlist); 1749 cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, devlist);
1687 return device->discipline->term_IO(cqr); 1750 rc = device->discipline->term_IO(cqr);
1751 if (!rc)
1752 /*
1753 * CQR terminated because a more important request is pending.
1754 * Undo decreasing of retry counter because this is
1755 * not an error case.
1756 */
1757 cqr->retries++;
1758 return rc;
1688} 1759}
1689 1760
1690int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr) 1761int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr)
@@ -1693,13 +1764,18 @@ int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr)
1693 int rc; 1764 int rc;
1694 1765
1695 device = cqr->startdev; 1766 device = cqr->startdev;
1767 if (test_bit(DASD_FLAG_LOCK_STOLEN, &device->flags) &&
1768 !test_bit(DASD_CQR_ALLOW_SLOCK, &cqr->flags)) {
1769 cqr->status = DASD_CQR_FAILED;
1770 cqr->intrc = -EPERM;
1771 return -EIO;
1772 }
1696 spin_lock_irq(get_ccwdev_lock(device->cdev)); 1773 spin_lock_irq(get_ccwdev_lock(device->cdev));
1697 rc = _dasd_term_running_cqr(device); 1774 rc = _dasd_term_running_cqr(device);
1698 if (rc) { 1775 if (rc) {
1699 spin_unlock_irq(get_ccwdev_lock(device->cdev)); 1776 spin_unlock_irq(get_ccwdev_lock(device->cdev));
1700 return rc; 1777 return rc;
1701 } 1778 }
1702
1703 cqr->callback = dasd_wakeup_cb; 1779 cqr->callback = dasd_wakeup_cb;
1704 cqr->callback_data = DASD_SLEEPON_START_TAG; 1780 cqr->callback_data = DASD_SLEEPON_START_TAG;
1705 cqr->status = DASD_CQR_QUEUED; 1781 cqr->status = DASD_CQR_QUEUED;
@@ -1850,7 +1926,7 @@ static void __dasd_process_request_queue(struct dasd_block *block)
1850 return; 1926 return;
1851 } 1927 }
1852 /* Now we try to fetch requests from the request queue */ 1928 /* Now we try to fetch requests from the request queue */
1853 while (!blk_queue_plugged(queue) && (req = blk_peek_request(queue))) { 1929 while ((req = blk_peek_request(queue))) {
1854 if (basedev->features & DASD_FEATURE_READONLY && 1930 if (basedev->features & DASD_FEATURE_READONLY &&
1855 rq_data_dir(req) == WRITE) { 1931 rq_data_dir(req) == WRITE) {
1856 DBF_DEV_EVENT(DBF_ERR, basedev, 1932 DBF_DEV_EVENT(DBF_ERR, basedev,
@@ -2003,6 +2079,13 @@ static void __dasd_block_start_head(struct dasd_block *block)
2003 list_for_each_entry(cqr, &block->ccw_queue, blocklist) { 2079 list_for_each_entry(cqr, &block->ccw_queue, blocklist) {
2004 if (cqr->status != DASD_CQR_FILLED) 2080 if (cqr->status != DASD_CQR_FILLED)
2005 continue; 2081 continue;
2082 if (test_bit(DASD_FLAG_LOCK_STOLEN, &block->base->flags) &&
2083 !test_bit(DASD_CQR_ALLOW_SLOCK, &cqr->flags)) {
2084 cqr->status = DASD_CQR_FAILED;
2085 cqr->intrc = -EPERM;
2086 dasd_schedule_block_bh(block);
2087 continue;
2088 }
2006 /* Non-temporary stop condition will trigger fail fast */ 2089 /* Non-temporary stop condition will trigger fail fast */
2007 if (block->base->stopped & ~DASD_STOPPED_PENDING && 2090 if (block->base->stopped & ~DASD_STOPPED_PENDING &&
2008 test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) && 2091 test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) &&
@@ -2188,8 +2271,20 @@ static void dasd_setup_queue(struct dasd_block *block)
2188{ 2271{
2189 int max; 2272 int max;
2190 2273
2191 blk_queue_logical_block_size(block->request_queue, block->bp_block); 2274 if (block->base->features & DASD_FEATURE_USERAW) {
2192 max = block->base->discipline->max_blocks << block->s2b_shift; 2275 /*
2276 * the max_blocks value for raw_track access is 256
2277 * it is higher than the native ECKD value because we
2278 * only need one ccw per track
2279 * so the max_hw_sectors are
2280 * 2048 x 512B = 1024kB = 16 tracks
2281 */
2282 max = 2048;
2283 } else {
2284 max = block->base->discipline->max_blocks << block->s2b_shift;
2285 }
2286 blk_queue_logical_block_size(block->request_queue,
2287 block->bp_block);
2193 blk_queue_max_hw_sectors(block->request_queue, max); 2288 blk_queue_max_hw_sectors(block->request_queue, max);
2194 blk_queue_max_segments(block->request_queue, -1L); 2289 blk_queue_max_segments(block->request_queue, -1L);
2195 /* with page sized segments we can translate each segement into 2290 /* with page sized segments we can translate each segement into
@@ -2197,7 +2292,6 @@ static void dasd_setup_queue(struct dasd_block *block)
2197 */ 2292 */
2198 blk_queue_max_segment_size(block->request_queue, PAGE_SIZE); 2293 blk_queue_max_segment_size(block->request_queue, PAGE_SIZE);
2199 blk_queue_segment_boundary(block->request_queue, PAGE_SIZE - 1); 2294 blk_queue_segment_boundary(block->request_queue, PAGE_SIZE - 1);
2200 blk_queue_ordered(block->request_queue, QUEUE_ORDERED_DRAIN);
2201} 2295}
2202 2296
2203/* 2297/*
@@ -2229,16 +2323,14 @@ static void dasd_flush_request_queue(struct dasd_block *block)
2229 2323
2230static int dasd_open(struct block_device *bdev, fmode_t mode) 2324static int dasd_open(struct block_device *bdev, fmode_t mode)
2231{ 2325{
2232 struct dasd_block *block = bdev->bd_disk->private_data;
2233 struct dasd_device *base; 2326 struct dasd_device *base;
2234 int rc; 2327 int rc;
2235 2328
2236 if (!block) 2329 base = dasd_device_from_gendisk(bdev->bd_disk);
2330 if (!base)
2237 return -ENODEV; 2331 return -ENODEV;
2238 2332
2239 lock_kernel(); 2333 atomic_inc(&base->block->open_count);
2240 base = block->base;
2241 atomic_inc(&block->open_count);
2242 if (test_bit(DASD_FLAG_OFFLINE, &base->flags)) { 2334 if (test_bit(DASD_FLAG_OFFLINE, &base->flags)) {
2243 rc = -ENODEV; 2335 rc = -ENODEV;
2244 goto unlock; 2336 goto unlock;
@@ -2271,25 +2363,28 @@ static int dasd_open(struct block_device *bdev, fmode_t mode)
2271 goto out; 2363 goto out;
2272 } 2364 }
2273 2365
2274 unlock_kernel(); 2366 dasd_put_device(base);
2275 return 0; 2367 return 0;
2276 2368
2277out: 2369out:
2278 module_put(base->discipline->owner); 2370 module_put(base->discipline->owner);
2279unlock: 2371unlock:
2280 atomic_dec(&block->open_count); 2372 atomic_dec(&base->block->open_count);
2281 unlock_kernel(); 2373 dasd_put_device(base);
2282 return rc; 2374 return rc;
2283} 2375}
2284 2376
2285static int dasd_release(struct gendisk *disk, fmode_t mode) 2377static int dasd_release(struct gendisk *disk, fmode_t mode)
2286{ 2378{
2287 struct dasd_block *block = disk->private_data; 2379 struct dasd_device *base;
2380
2381 base = dasd_device_from_gendisk(disk);
2382 if (!base)
2383 return -ENODEV;
2288 2384
2289 lock_kernel(); 2385 atomic_dec(&base->block->open_count);
2290 atomic_dec(&block->open_count); 2386 module_put(base->discipline->owner);
2291 module_put(block->base->discipline->owner); 2387 dasd_put_device(base);
2292 unlock_kernel();
2293 return 0; 2388 return 0;
2294} 2389}
2295 2390
@@ -2298,20 +2393,20 @@ static int dasd_release(struct gendisk *disk, fmode_t mode)
2298 */ 2393 */
2299static int dasd_getgeo(struct block_device *bdev, struct hd_geometry *geo) 2394static int dasd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
2300{ 2395{
2301 struct dasd_block *block;
2302 struct dasd_device *base; 2396 struct dasd_device *base;
2303 2397
2304 block = bdev->bd_disk->private_data; 2398 base = dasd_device_from_gendisk(bdev->bd_disk);
2305 if (!block) 2399 if (!base)
2306 return -ENODEV; 2400 return -ENODEV;
2307 base = block->base;
2308 2401
2309 if (!base->discipline || 2402 if (!base->discipline ||
2310 !base->discipline->fill_geometry) 2403 !base->discipline->fill_geometry) {
2404 dasd_put_device(base);
2311 return -EINVAL; 2405 return -EINVAL;
2312 2406 }
2313 base->discipline->fill_geometry(block, geo); 2407 base->discipline->fill_geometry(base->block, geo);
2314 geo->start = get_start_sect(bdev) >> block->s2b_shift; 2408 geo->start = get_start_sect(bdev) >> base->block->s2b_shift;
2409 dasd_put_device(base);
2315 return 0; 2410 return 0;
2316} 2411}
2317 2412
@@ -2448,7 +2543,6 @@ void dasd_generic_remove(struct ccw_device *cdev)
2448 dasd_set_target_state(device, DASD_STATE_NEW); 2543 dasd_set_target_state(device, DASD_STATE_NEW);
2449 /* dasd_delete_device destroys the device reference. */ 2544 /* dasd_delete_device destroys the device reference. */
2450 block = device->block; 2545 block = device->block;
2451 device->block = NULL;
2452 dasd_delete_device(device); 2546 dasd_delete_device(device);
2453 /* 2547 /*
2454 * life cycle of block is bound to device, so delete it after 2548 * life cycle of block is bound to device, so delete it after
@@ -2570,7 +2664,6 @@ int dasd_generic_set_offline(struct ccw_device *cdev)
2570 dasd_set_target_state(device, DASD_STATE_NEW); 2664 dasd_set_target_state(device, DASD_STATE_NEW);
2571 /* dasd_delete_device destroys the device reference. */ 2665 /* dasd_delete_device destroys the device reference. */
2572 block = device->block; 2666 block = device->block;
2573 device->block = NULL;
2574 dasd_delete_device(device); 2667 dasd_delete_device(device);
2575 /* 2668 /*
2576 * life cycle of block is bound to device, so delete it after 2669 * life cycle of block is bound to device, so delete it after
@@ -2581,10 +2674,53 @@ int dasd_generic_set_offline(struct ccw_device *cdev)
2581 return 0; 2674 return 0;
2582} 2675}
2583 2676
2677int dasd_generic_last_path_gone(struct dasd_device *device)
2678{
2679 struct dasd_ccw_req *cqr;
2680
2681 dev_warn(&device->cdev->dev, "No operational channel path is left "
2682 "for the device\n");
2683 DBF_DEV_EVENT(DBF_WARNING, device, "%s", "last path gone");
2684 /* First of all call extended error reporting. */
2685 dasd_eer_write(device, NULL, DASD_EER_NOPATH);
2686
2687 if (device->state < DASD_STATE_BASIC)
2688 return 0;
2689 /* Device is active. We want to keep it. */
2690 list_for_each_entry(cqr, &device->ccw_queue, devlist)
2691 if ((cqr->status == DASD_CQR_IN_IO) ||
2692 (cqr->status == DASD_CQR_CLEAR_PENDING)) {
2693 cqr->status = DASD_CQR_QUEUED;
2694 cqr->retries++;
2695 }
2696 dasd_device_set_stop_bits(device, DASD_STOPPED_DC_WAIT);
2697 dasd_device_clear_timer(device);
2698 dasd_schedule_device_bh(device);
2699 return 1;
2700}
2701EXPORT_SYMBOL_GPL(dasd_generic_last_path_gone);
2702
2703int dasd_generic_path_operational(struct dasd_device *device)
2704{
2705 dev_info(&device->cdev->dev, "A channel path to the device has become "
2706 "operational\n");
2707 DBF_DEV_EVENT(DBF_WARNING, device, "%s", "path operational");
2708 dasd_device_remove_stop_bits(device, DASD_STOPPED_DC_WAIT);
2709 if (device->stopped & DASD_UNRESUMED_PM) {
2710 dasd_device_remove_stop_bits(device, DASD_UNRESUMED_PM);
2711 dasd_restore_device(device);
2712 return 1;
2713 }
2714 dasd_schedule_device_bh(device);
2715 if (device->block)
2716 dasd_schedule_block_bh(device->block);
2717 return 1;
2718}
2719EXPORT_SYMBOL_GPL(dasd_generic_path_operational);
2720
2584int dasd_generic_notify(struct ccw_device *cdev, int event) 2721int dasd_generic_notify(struct ccw_device *cdev, int event)
2585{ 2722{
2586 struct dasd_device *device; 2723 struct dasd_device *device;
2587 struct dasd_ccw_req *cqr;
2588 int ret; 2724 int ret;
2589 2725
2590 device = dasd_device_from_cdev_locked(cdev); 2726 device = dasd_device_from_cdev_locked(cdev);
@@ -2595,41 +2731,64 @@ int dasd_generic_notify(struct ccw_device *cdev, int event)
2595 case CIO_GONE: 2731 case CIO_GONE:
2596 case CIO_BOXED: 2732 case CIO_BOXED:
2597 case CIO_NO_PATH: 2733 case CIO_NO_PATH:
2598 /* First of all call extended error reporting. */ 2734 device->path_data.opm = 0;
2599 dasd_eer_write(device, NULL, DASD_EER_NOPATH); 2735 device->path_data.ppm = 0;
2600 2736 device->path_data.npm = 0;
2601 if (device->state < DASD_STATE_BASIC) 2737 ret = dasd_generic_last_path_gone(device);
2602 break;
2603 /* Device is active. We want to keep it. */
2604 list_for_each_entry(cqr, &device->ccw_queue, devlist)
2605 if (cqr->status == DASD_CQR_IN_IO) {
2606 cqr->status = DASD_CQR_QUEUED;
2607 cqr->retries++;
2608 }
2609 dasd_device_set_stop_bits(device, DASD_STOPPED_DC_WAIT);
2610 dasd_device_clear_timer(device);
2611 dasd_schedule_device_bh(device);
2612 ret = 1;
2613 break; 2738 break;
2614 case CIO_OPER: 2739 case CIO_OPER:
2615 /* FIXME: add a sanity check. */
2616 dasd_device_remove_stop_bits(device, DASD_STOPPED_DC_WAIT);
2617 if (device->stopped & DASD_UNRESUMED_PM) {
2618 dasd_device_remove_stop_bits(device, DASD_UNRESUMED_PM);
2619 dasd_restore_device(device);
2620 ret = 1;
2621 break;
2622 }
2623 dasd_schedule_device_bh(device);
2624 if (device->block)
2625 dasd_schedule_block_bh(device->block);
2626 ret = 1; 2740 ret = 1;
2741 if (device->path_data.opm)
2742 ret = dasd_generic_path_operational(device);
2627 break; 2743 break;
2628 } 2744 }
2629 dasd_put_device(device); 2745 dasd_put_device(device);
2630 return ret; 2746 return ret;
2631} 2747}
2632 2748
2749void dasd_generic_path_event(struct ccw_device *cdev, int *path_event)
2750{
2751 int chp;
2752 __u8 oldopm, eventlpm;
2753 struct dasd_device *device;
2754
2755 device = dasd_device_from_cdev_locked(cdev);
2756 if (IS_ERR(device))
2757 return;
2758 for (chp = 0; chp < 8; chp++) {
2759 eventlpm = 0x80 >> chp;
2760 if (path_event[chp] & PE_PATH_GONE) {
2761 oldopm = device->path_data.opm;
2762 device->path_data.opm &= ~eventlpm;
2763 device->path_data.ppm &= ~eventlpm;
2764 device->path_data.npm &= ~eventlpm;
2765 if (oldopm && !device->path_data.opm)
2766 dasd_generic_last_path_gone(device);
2767 }
2768 if (path_event[chp] & PE_PATH_AVAILABLE) {
2769 device->path_data.opm &= ~eventlpm;
2770 device->path_data.ppm &= ~eventlpm;
2771 device->path_data.npm &= ~eventlpm;
2772 device->path_data.tbvpm |= eventlpm;
2773 dasd_schedule_device_bh(device);
2774 }
2775 }
2776 dasd_put_device(device);
2777}
2778EXPORT_SYMBOL_GPL(dasd_generic_path_event);
2779
2780int dasd_generic_verify_path(struct dasd_device *device, __u8 lpm)
2781{
2782 if (!device->path_data.opm && lpm) {
2783 device->path_data.opm = lpm;
2784 dasd_generic_path_operational(device);
2785 } else
2786 device->path_data.opm |= lpm;
2787 return 0;
2788}
2789EXPORT_SYMBOL_GPL(dasd_generic_verify_path);
2790
2791
2633int dasd_generic_pm_freeze(struct ccw_device *cdev) 2792int dasd_generic_pm_freeze(struct ccw_device *cdev)
2634{ 2793{
2635 struct dasd_ccw_req *cqr, *n; 2794 struct dasd_ccw_req *cqr, *n;
@@ -2639,6 +2798,10 @@ int dasd_generic_pm_freeze(struct ccw_device *cdev)
2639 2798
2640 if (IS_ERR(device)) 2799 if (IS_ERR(device))
2641 return PTR_ERR(device); 2800 return PTR_ERR(device);
2801
2802 if (device->discipline->freeze)
2803 rc = device->discipline->freeze(device);
2804
2642 /* disallow new I/O */ 2805 /* disallow new I/O */
2643 dasd_device_set_stop_bits(device, DASD_STOPPED_PM); 2806 dasd_device_set_stop_bits(device, DASD_STOPPED_PM);
2644 /* clear active requests */ 2807 /* clear active requests */
@@ -2675,9 +2838,6 @@ int dasd_generic_pm_freeze(struct ccw_device *cdev)
2675 list_splice_tail(&freeze_queue, &device->ccw_queue); 2838 list_splice_tail(&freeze_queue, &device->ccw_queue);
2676 spin_unlock_irq(get_ccwdev_lock(cdev)); 2839 spin_unlock_irq(get_ccwdev_lock(cdev));
2677 2840
2678 if (device->discipline->freeze)
2679 rc = device->discipline->freeze(device);
2680
2681 dasd_put_device(device); 2841 dasd_put_device(device);
2682 return rc; 2842 return rc;
2683} 2843}
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
index 85bfd8794856..87a0cf160fe5 100644
--- a/drivers/s390/block/dasd_3990_erp.c
+++ b/drivers/s390/block/dasd_3990_erp.c
@@ -152,9 +152,9 @@ dasd_3990_erp_alternate_path(struct dasd_ccw_req * erp)
152 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); 152 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
153 opm = ccw_device_get_path_mask(device->cdev); 153 opm = ccw_device_get_path_mask(device->cdev);
154 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); 154 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
155 //FIXME: start with get_opm ?
156 if (erp->lpm == 0) 155 if (erp->lpm == 0)
157 erp->lpm = LPM_ANYPATH & ~(erp->irb.esw.esw0.sublog.lpum); 156 erp->lpm = device->path_data.opm &
157 ~(erp->irb.esw.esw0.sublog.lpum);
158 else 158 else
159 erp->lpm &= ~(erp->irb.esw.esw0.sublog.lpum); 159 erp->lpm &= ~(erp->irb.esw.esw0.sublog.lpum);
160 160
@@ -221,6 +221,7 @@ dasd_3990_erp_DCTL(struct dasd_ccw_req * erp, char modifier)
221 ccw->cmd_code = CCW_CMD_DCTL; 221 ccw->cmd_code = CCW_CMD_DCTL;
222 ccw->count = 4; 222 ccw->count = 4;
223 ccw->cda = (__u32)(addr_t) DCTL_data; 223 ccw->cda = (__u32)(addr_t) DCTL_data;
224 dctl_cqr->flags = erp->flags;
224 dctl_cqr->function = dasd_3990_erp_DCTL; 225 dctl_cqr->function = dasd_3990_erp_DCTL;
225 dctl_cqr->refers = erp; 226 dctl_cqr->refers = erp;
226 dctl_cqr->startdev = device; 227 dctl_cqr->startdev = device;
@@ -269,10 +270,11 @@ static struct dasd_ccw_req *dasd_3990_erp_action_1(struct dasd_ccw_req *erp)
269{ 270{
270 erp->function = dasd_3990_erp_action_1; 271 erp->function = dasd_3990_erp_action_1;
271 dasd_3990_erp_alternate_path(erp); 272 dasd_3990_erp_alternate_path(erp);
272 if (erp->status == DASD_CQR_FAILED) { 273 if (erp->status == DASD_CQR_FAILED &&
274 !test_bit(DASD_CQR_VERIFY_PATH, &erp->flags)) {
273 erp->status = DASD_CQR_FILLED; 275 erp->status = DASD_CQR_FILLED;
274 erp->retries = 10; 276 erp->retries = 10;
275 erp->lpm = LPM_ANYPATH; 277 erp->lpm = erp->startdev->path_data.opm;
276 erp->function = dasd_3990_erp_action_1_sec; 278 erp->function = dasd_3990_erp_action_1_sec;
277 } 279 }
278 return erp; 280 return erp;
@@ -1710,6 +1712,7 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
1710 ccw->cda = cpa; 1712 ccw->cda = cpa;
1711 1713
1712 /* fill erp related fields */ 1714 /* fill erp related fields */
1715 erp->flags = default_erp->flags;
1713 erp->function = dasd_3990_erp_action_1B_32; 1716 erp->function = dasd_3990_erp_action_1B_32;
1714 erp->refers = default_erp->refers; 1717 erp->refers = default_erp->refers;
1715 erp->startdev = device; 1718 erp->startdev = device;
@@ -1905,15 +1908,14 @@ dasd_3990_erp_compound_retry(struct dasd_ccw_req * erp, char *sense)
1905static void 1908static void
1906dasd_3990_erp_compound_path(struct dasd_ccw_req * erp, char *sense) 1909dasd_3990_erp_compound_path(struct dasd_ccw_req * erp, char *sense)
1907{ 1910{
1908
1909 if (sense[25] & DASD_SENSE_BIT_3) { 1911 if (sense[25] & DASD_SENSE_BIT_3) {
1910 dasd_3990_erp_alternate_path(erp); 1912 dasd_3990_erp_alternate_path(erp);
1911 1913
1912 if (erp->status == DASD_CQR_FAILED) { 1914 if (erp->status == DASD_CQR_FAILED &&
1915 !test_bit(DASD_CQR_VERIFY_PATH, &erp->flags)) {
1913 /* reset the lpm and the status to be able to 1916 /* reset the lpm and the status to be able to
1914 * try further actions. */ 1917 * try further actions. */
1915 1918 erp->lpm = erp->startdev->path_data.opm;
1916 erp->lpm = 0;
1917 erp->status = DASD_CQR_NEED_ERP; 1919 erp->status = DASD_CQR_NEED_ERP;
1918 } 1920 }
1919 } 1921 }
@@ -2197,7 +2199,7 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
2197 2199
2198/* 2200/*
2199 ***************************************************************************** 2201 *****************************************************************************
2200 * main ERP control fuctions (24 and 32 byte sense) 2202 * main ERP control functions (24 and 32 byte sense)
2201 ***************************************************************************** 2203 *****************************************************************************
2202 */ 2204 */
2203 2205
@@ -2205,7 +2207,7 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense)
2205 * DASD_3990_ERP_CONTROL_CHECK 2207 * DASD_3990_ERP_CONTROL_CHECK
2206 * 2208 *
2207 * DESCRIPTION 2209 * DESCRIPTION
2208 * Does a generic inspection if a control check occured and sets up 2210 * Does a generic inspection if a control check occurred and sets up
2209 * the related error recovery procedure 2211 * the related error recovery procedure
2210 * 2212 *
2211 * PARAMETER 2213 * PARAMETER
@@ -2248,7 +2250,7 @@ dasd_3990_erp_inspect(struct dasd_ccw_req *erp)
2248 struct dasd_ccw_req *erp_new = NULL; 2250 struct dasd_ccw_req *erp_new = NULL;
2249 char *sense; 2251 char *sense;
2250 2252
2251 /* if this problem occured on an alias retry on base */ 2253 /* if this problem occurred on an alias retry on base */
2252 erp_new = dasd_3990_erp_inspect_alias(erp); 2254 erp_new = dasd_3990_erp_inspect_alias(erp);
2253 if (erp_new) 2255 if (erp_new)
2254 return erp_new; 2256 return erp_new;
@@ -2280,7 +2282,7 @@ dasd_3990_erp_inspect(struct dasd_ccw_req *erp)
2280 * DASD_3990_ERP_ADD_ERP 2282 * DASD_3990_ERP_ADD_ERP
2281 * 2283 *
2282 * DESCRIPTION 2284 * DESCRIPTION
2283 * This funtion adds an additional request block (ERP) to the head of 2285 * This function adds an additional request block (ERP) to the head of
2284 * the given cqr (or erp). 2286 * the given cqr (or erp).
2285 * For a command mode cqr the erp is initialized as an default erp 2287 * For a command mode cqr the erp is initialized as an default erp
2286 * (retry TIC). 2288 * (retry TIC).
@@ -2354,6 +2356,7 @@ static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req *cqr)
2354 ccw->cda = (long)(cqr->cpaddr); 2356 ccw->cda = (long)(cqr->cpaddr);
2355 } 2357 }
2356 2358
2359 erp->flags = cqr->flags;
2357 erp->function = dasd_3990_erp_add_erp; 2360 erp->function = dasd_3990_erp_add_erp;
2358 erp->refers = cqr; 2361 erp->refers = cqr;
2359 erp->startdev = device; 2362 erp->startdev = device;
diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c
index 4155805dcdff..c388eda1e2b1 100644
--- a/drivers/s390/block/dasd_alias.c
+++ b/drivers/s390/block/dasd_alias.c
@@ -253,13 +253,11 @@ int dasd_alias_make_device_known_to_lcu(struct dasd_device *device)
253 */ 253 */
254void dasd_alias_lcu_setup_complete(struct dasd_device *device) 254void dasd_alias_lcu_setup_complete(struct dasd_device *device)
255{ 255{
256 struct dasd_eckd_private *private;
257 unsigned long flags; 256 unsigned long flags;
258 struct alias_server *server; 257 struct alias_server *server;
259 struct alias_lcu *lcu; 258 struct alias_lcu *lcu;
260 struct dasd_uid uid; 259 struct dasd_uid uid;
261 260
262 private = (struct dasd_eckd_private *) device->private;
263 device->discipline->get_uid(device, &uid); 261 device->discipline->get_uid(device, &uid);
264 lcu = NULL; 262 lcu = NULL;
265 spin_lock_irqsave(&aliastree.lock, flags); 263 spin_lock_irqsave(&aliastree.lock, flags);
@@ -279,13 +277,11 @@ void dasd_alias_lcu_setup_complete(struct dasd_device *device)
279 277
280void dasd_alias_wait_for_lcu_setup(struct dasd_device *device) 278void dasd_alias_wait_for_lcu_setup(struct dasd_device *device)
281{ 279{
282 struct dasd_eckd_private *private;
283 unsigned long flags; 280 unsigned long flags;
284 struct alias_server *server; 281 struct alias_server *server;
285 struct alias_lcu *lcu; 282 struct alias_lcu *lcu;
286 struct dasd_uid uid; 283 struct dasd_uid uid;
287 284
288 private = (struct dasd_eckd_private *) device->private;
289 device->discipline->get_uid(device, &uid); 285 device->discipline->get_uid(device, &uid);
290 lcu = NULL; 286 lcu = NULL;
291 spin_lock_irqsave(&aliastree.lock, flags); 287 spin_lock_irqsave(&aliastree.lock, flags);
@@ -319,6 +315,9 @@ void dasd_alias_disconnect_device_from_lcu(struct dasd_device *device)
319 315
320 private = (struct dasd_eckd_private *) device->private; 316 private = (struct dasd_eckd_private *) device->private;
321 lcu = private->lcu; 317 lcu = private->lcu;
318 /* nothing to do if already disconnected */
319 if (!lcu)
320 return;
322 device->discipline->get_uid(device, &uid); 321 device->discipline->get_uid(device, &uid);
323 spin_lock_irqsave(&lcu->lock, flags); 322 spin_lock_irqsave(&lcu->lock, flags);
324 list_del_init(&device->alias_list); 323 list_del_init(&device->alias_list);
@@ -680,6 +679,9 @@ int dasd_alias_remove_device(struct dasd_device *device)
680 679
681 private = (struct dasd_eckd_private *) device->private; 680 private = (struct dasd_eckd_private *) device->private;
682 lcu = private->lcu; 681 lcu = private->lcu;
682 /* nothing to do if already removed */
683 if (!lcu)
684 return 0;
683 spin_lock_irqsave(&lcu->lock, flags); 685 spin_lock_irqsave(&lcu->lock, flags);
684 _remove_device_from_lcu(lcu, device); 686 _remove_device_from_lcu(lcu, device);
685 spin_unlock_irqrestore(&lcu->lock, flags); 687 spin_unlock_irqrestore(&lcu->lock, flags);
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index 8d41f3ed38d7..d71511c7850a 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -208,6 +208,8 @@ dasd_feature_list(char *str, char **endp)
208 features |= DASD_FEATURE_READONLY; 208 features |= DASD_FEATURE_READONLY;
209 else if (len == 4 && !strncmp(str, "diag", 4)) 209 else if (len == 4 && !strncmp(str, "diag", 4))
210 features |= DASD_FEATURE_USEDIAG; 210 features |= DASD_FEATURE_USEDIAG;
211 else if (len == 3 && !strncmp(str, "raw", 3))
212 features |= DASD_FEATURE_USERAW;
211 else if (len == 6 && !strncmp(str, "erplog", 6)) 213 else if (len == 6 && !strncmp(str, "erplog", 6))
212 features |= DASD_FEATURE_ERPLOG; 214 features |= DASD_FEATURE_ERPLOG;
213 else if (len == 8 && !strncmp(str, "failfast", 8)) 215 else if (len == 8 && !strncmp(str, "failfast", 8))
@@ -300,7 +302,7 @@ dasd_parse_keyword( char *parsestring ) {
300/* 302/*
301 * Try to interprete the first element on the comma separated parse string 303 * Try to interprete the first element on the comma separated parse string
302 * as a device number or a range of devices. If the interpretation is 304 * as a device number or a range of devices. If the interpretation is
303 * successfull, create the matching dasd_devmap entries and return a pointer 305 * successful, create the matching dasd_devmap entries and return a pointer
304 * to the residual string. 306 * to the residual string.
305 * If interpretation fails or in case of an error, return an error code. 307 * If interpretation fails or in case of an error, return an error code.
306 */ 308 */
@@ -639,6 +641,7 @@ dasd_put_device_wake(struct dasd_device *device)
639{ 641{
640 wake_up(&dasd_delete_wq); 642 wake_up(&dasd_delete_wq);
641} 643}
644EXPORT_SYMBOL_GPL(dasd_put_device_wake);
642 645
643/* 646/*
644 * Return dasd_device structure associated with cdev. 647 * Return dasd_device structure associated with cdev.
@@ -671,6 +674,36 @@ dasd_device_from_cdev(struct ccw_device *cdev)
671 return device; 674 return device;
672} 675}
673 676
677void dasd_add_link_to_gendisk(struct gendisk *gdp, struct dasd_device *device)
678{
679 struct dasd_devmap *devmap;
680
681 devmap = dasd_find_busid(dev_name(&device->cdev->dev));
682 if (IS_ERR(devmap))
683 return;
684 spin_lock(&dasd_devmap_lock);
685 gdp->private_data = devmap;
686 spin_unlock(&dasd_devmap_lock);
687}
688
689struct dasd_device *dasd_device_from_gendisk(struct gendisk *gdp)
690{
691 struct dasd_device *device;
692 struct dasd_devmap *devmap;
693
694 if (!gdp->private_data)
695 return NULL;
696 device = NULL;
697 spin_lock(&dasd_devmap_lock);
698 devmap = gdp->private_data;
699 if (devmap && devmap->device) {
700 device = devmap->device;
701 dasd_get_device(device);
702 }
703 spin_unlock(&dasd_devmap_lock);
704 return device;
705}
706
674/* 707/*
675 * SECTION: files in sysfs 708 * SECTION: files in sysfs
676 */ 709 */
@@ -856,7 +889,7 @@ dasd_use_diag_store(struct device *dev, struct device_attribute *attr,
856 spin_lock(&dasd_devmap_lock); 889 spin_lock(&dasd_devmap_lock);
857 /* Changing diag discipline flag is only allowed in offline state. */ 890 /* Changing diag discipline flag is only allowed in offline state. */
858 rc = count; 891 rc = count;
859 if (!devmap->device) { 892 if (!devmap->device && !(devmap->features & DASD_FEATURE_USERAW)) {
860 if (val) 893 if (val)
861 devmap->features |= DASD_FEATURE_USEDIAG; 894 devmap->features |= DASD_FEATURE_USEDIAG;
862 else 895 else
@@ -869,6 +902,56 @@ dasd_use_diag_store(struct device *dev, struct device_attribute *attr,
869 902
870static DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store); 903static DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store);
871 904
905/*
906 * use_raw controls whether the driver should give access to raw eckd data or
907 * operate in standard mode
908 */
909static ssize_t
910dasd_use_raw_show(struct device *dev, struct device_attribute *attr, char *buf)
911{
912 struct dasd_devmap *devmap;
913 int use_raw;
914
915 devmap = dasd_find_busid(dev_name(dev));
916 if (!IS_ERR(devmap))
917 use_raw = (devmap->features & DASD_FEATURE_USERAW) != 0;
918 else
919 use_raw = (DASD_FEATURE_DEFAULT & DASD_FEATURE_USERAW) != 0;
920 return sprintf(buf, use_raw ? "1\n" : "0\n");
921}
922
923static ssize_t
924dasd_use_raw_store(struct device *dev, struct device_attribute *attr,
925 const char *buf, size_t count)
926{
927 struct dasd_devmap *devmap;
928 ssize_t rc;
929 unsigned long val;
930
931 devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
932 if (IS_ERR(devmap))
933 return PTR_ERR(devmap);
934
935 if ((strict_strtoul(buf, 10, &val) != 0) || val > 1)
936 return -EINVAL;
937
938 spin_lock(&dasd_devmap_lock);
939 /* Changing diag discipline flag is only allowed in offline state. */
940 rc = count;
941 if (!devmap->device && !(devmap->features & DASD_FEATURE_USEDIAG)) {
942 if (val)
943 devmap->features |= DASD_FEATURE_USERAW;
944 else
945 devmap->features &= ~DASD_FEATURE_USERAW;
946 } else
947 rc = -EPERM;
948 spin_unlock(&dasd_devmap_lock);
949 return rc;
950}
951
952static DEVICE_ATTR(raw_track_access, 0644, dasd_use_raw_show,
953 dasd_use_raw_store);
954
872static ssize_t 955static ssize_t
873dasd_discipline_show(struct device *dev, struct device_attribute *attr, 956dasd_discipline_show(struct device *dev, struct device_attribute *attr,
874 char *buf) 957 char *buf)
@@ -1126,6 +1209,103 @@ dasd_expires_store(struct device *dev, struct device_attribute *attr,
1126 1209
1127static DEVICE_ATTR(expires, 0644, dasd_expires_show, dasd_expires_store); 1210static DEVICE_ATTR(expires, 0644, dasd_expires_show, dasd_expires_store);
1128 1211
1212static ssize_t dasd_reservation_policy_show(struct device *dev,
1213 struct device_attribute *attr,
1214 char *buf)
1215{
1216 struct dasd_devmap *devmap;
1217 int rc = 0;
1218
1219 devmap = dasd_find_busid(dev_name(dev));
1220 if (IS_ERR(devmap)) {
1221 rc = snprintf(buf, PAGE_SIZE, "ignore\n");
1222 } else {
1223 spin_lock(&dasd_devmap_lock);
1224 if (devmap->features & DASD_FEATURE_FAILONSLCK)
1225 rc = snprintf(buf, PAGE_SIZE, "fail\n");
1226 else
1227 rc = snprintf(buf, PAGE_SIZE, "ignore\n");
1228 spin_unlock(&dasd_devmap_lock);
1229 }
1230 return rc;
1231}
1232
1233static ssize_t dasd_reservation_policy_store(struct device *dev,
1234 struct device_attribute *attr,
1235 const char *buf, size_t count)
1236{
1237 struct dasd_devmap *devmap;
1238 int rc;
1239
1240 devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
1241 if (IS_ERR(devmap))
1242 return PTR_ERR(devmap);
1243 rc = 0;
1244 spin_lock(&dasd_devmap_lock);
1245 if (sysfs_streq("ignore", buf))
1246 devmap->features &= ~DASD_FEATURE_FAILONSLCK;
1247 else if (sysfs_streq("fail", buf))
1248 devmap->features |= DASD_FEATURE_FAILONSLCK;
1249 else
1250 rc = -EINVAL;
1251 if (devmap->device)
1252 devmap->device->features = devmap->features;
1253 spin_unlock(&dasd_devmap_lock);
1254 if (rc)
1255 return rc;
1256 else
1257 return count;
1258}
1259
1260static DEVICE_ATTR(reservation_policy, 0644,
1261 dasd_reservation_policy_show, dasd_reservation_policy_store);
1262
1263static ssize_t dasd_reservation_state_show(struct device *dev,
1264 struct device_attribute *attr,
1265 char *buf)
1266{
1267 struct dasd_device *device;
1268 int rc = 0;
1269
1270 device = dasd_device_from_cdev(to_ccwdev(dev));
1271 if (IS_ERR(device))
1272 return snprintf(buf, PAGE_SIZE, "none\n");
1273
1274 if (test_bit(DASD_FLAG_IS_RESERVED, &device->flags))
1275 rc = snprintf(buf, PAGE_SIZE, "reserved\n");
1276 else if (test_bit(DASD_FLAG_LOCK_STOLEN, &device->flags))
1277 rc = snprintf(buf, PAGE_SIZE, "lost\n");
1278 else
1279 rc = snprintf(buf, PAGE_SIZE, "none\n");
1280 dasd_put_device(device);
1281 return rc;
1282}
1283
1284static ssize_t dasd_reservation_state_store(struct device *dev,
1285 struct device_attribute *attr,
1286 const char *buf, size_t count)
1287{
1288 struct dasd_device *device;
1289 int rc = 0;
1290
1291 device = dasd_device_from_cdev(to_ccwdev(dev));
1292 if (IS_ERR(device))
1293 return -ENODEV;
1294 if (sysfs_streq("reset", buf))
1295 clear_bit(DASD_FLAG_LOCK_STOLEN, &device->flags);
1296 else
1297 rc = -EINVAL;
1298 dasd_put_device(device);
1299
1300 if (rc)
1301 return rc;
1302 else
1303 return count;
1304}
1305
1306static DEVICE_ATTR(last_known_reservation_state, 0644,
1307 dasd_reservation_state_show, dasd_reservation_state_store);
1308
1129static struct attribute * dasd_attrs[] = { 1309static struct attribute * dasd_attrs[] = {
1130 &dev_attr_readonly.attr, 1310 &dev_attr_readonly.attr,
1131 &dev_attr_discipline.attr, 1311 &dev_attr_discipline.attr,
@@ -1134,10 +1314,13 @@ static struct attribute * dasd_attrs[] = {
1134 &dev_attr_vendor.attr, 1314 &dev_attr_vendor.attr,
1135 &dev_attr_uid.attr, 1315 &dev_attr_uid.attr,
1136 &dev_attr_use_diag.attr, 1316 &dev_attr_use_diag.attr,
1317 &dev_attr_raw_track_access.attr,
1137 &dev_attr_eer_enabled.attr, 1318 &dev_attr_eer_enabled.attr,
1138 &dev_attr_erplog.attr, 1319 &dev_attr_erplog.attr,
1139 &dev_attr_failfast.attr, 1320 &dev_attr_failfast.attr,
1140 &dev_attr_expires.attr, 1321 &dev_attr_expires.attr,
1322 &dev_attr_reservation_policy.attr,
1323 &dev_attr_last_known_reservation_state.attr,
1141 NULL, 1324 NULL,
1142}; 1325};
1143 1326
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index 2b3bc3ec0541..46784b83c5c4 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -10,6 +10,7 @@
10 10
11#define KMSG_COMPONENT "dasd" 11#define KMSG_COMPONENT "dasd"
12 12
13#include <linux/kernel_stat.h>
13#include <linux/stddef.h> 14#include <linux/stddef.h>
14#include <linux/kernel.h> 15#include <linux/kernel.h>
15#include <linux/slab.h> 16#include <linux/slab.h>
@@ -23,7 +24,7 @@
23#include <asm/debug.h> 24#include <asm/debug.h>
24#include <asm/ebcdic.h> 25#include <asm/ebcdic.h>
25#include <asm/io.h> 26#include <asm/io.h>
26#include <asm/s390_ext.h> 27#include <asm/irq.h>
27#include <asm/vtoc.h> 28#include <asm/vtoc.h>
28#include <asm/diag.h> 29#include <asm/diag.h>
29 30
@@ -228,29 +229,27 @@ dasd_diag_term_IO(struct dasd_ccw_req * cqr)
228} 229}
229 230
230/* Handle external interruption. */ 231/* Handle external interruption. */
231static void 232static void dasd_ext_handler(unsigned int ext_int_code,
232dasd_ext_handler(__u16 code) 233 unsigned int param32, unsigned long param64)
233{ 234{
234 struct dasd_ccw_req *cqr, *next; 235 struct dasd_ccw_req *cqr, *next;
235 struct dasd_device *device; 236 struct dasd_device *device;
236 unsigned long long expires; 237 unsigned long long expires;
237 unsigned long flags; 238 unsigned long flags;
238 u8 int_code, status;
239 addr_t ip; 239 addr_t ip;
240 int rc; 240 int rc;
241 241
242 int_code = *((u8 *) DASD_DIAG_LC_INT_CODE); 242 switch (ext_int_code >> 24) {
243 status = *((u8 *) DASD_DIAG_LC_INT_STATUS);
244 switch (int_code) {
245 case DASD_DIAG_CODE_31BIT: 243 case DASD_DIAG_CODE_31BIT:
246 ip = (addr_t) *((u32 *) DASD_DIAG_LC_INT_PARM_31BIT); 244 ip = (addr_t) param32;
247 break; 245 break;
248 case DASD_DIAG_CODE_64BIT: 246 case DASD_DIAG_CODE_64BIT:
249 ip = (addr_t) *((u64 *) DASD_DIAG_LC_INT_PARM_64BIT); 247 ip = (addr_t) param64;
250 break; 248 break;
251 default: 249 default:
252 return; 250 return;
253 } 251 }
252 kstat_cpu(smp_processor_id()).irqs[EXTINT_DSD]++;
254 if (!ip) { /* no intparm: unsolicited interrupt */ 253 if (!ip) { /* no intparm: unsolicited interrupt */
255 DBF_EVENT(DBF_NOTICE, "%s", "caught unsolicited " 254 DBF_EVENT(DBF_NOTICE, "%s", "caught unsolicited "
256 "interrupt"); 255 "interrupt");
@@ -281,7 +280,7 @@ dasd_ext_handler(__u16 code)
281 cqr->stopclk = get_clock(); 280 cqr->stopclk = get_clock();
282 281
283 expires = 0; 282 expires = 0;
284 if (status == 0) { 283 if ((ext_int_code & 0xff0000) == 0) {
285 cqr->status = DASD_CQR_SUCCESS; 284 cqr->status = DASD_CQR_SUCCESS;
286 /* Start first request on queue if possible -> fast_io. */ 285 /* Start first request on queue if possible -> fast_io. */
287 if (!list_empty(&device->ccw_queue)) { 286 if (!list_empty(&device->ccw_queue)) {
@@ -296,8 +295,8 @@ dasd_ext_handler(__u16 code)
296 } else { 295 } else {
297 cqr->status = DASD_CQR_QUEUED; 296 cqr->status = DASD_CQR_QUEUED;
298 DBF_DEV_EVENT(DBF_DEBUG, device, "interrupt status for " 297 DBF_DEV_EVENT(DBF_DEBUG, device, "interrupt status for "
299 "request %p was %d (%d retries left)", cqr, status, 298 "request %p was %d (%d retries left)", cqr,
300 cqr->retries); 299 (ext_int_code >> 16) & 0xff, cqr->retries);
301 dasd_diag_erp(device); 300 dasd_diag_erp(device);
302 } 301 }
303 302
@@ -620,6 +619,7 @@ static struct dasd_discipline dasd_diag_discipline = {
620 .ebcname = "DIAG", 619 .ebcname = "DIAG",
621 .max_blocks = DIAG_MAX_BLOCKS, 620 .max_blocks = DIAG_MAX_BLOCKS,
622 .check_device = dasd_diag_check_device, 621 .check_device = dasd_diag_check_device,
622 .verify_path = dasd_generic_verify_path,
623 .fill_geometry = dasd_diag_fill_geometry, 623 .fill_geometry = dasd_diag_fill_geometry,
624 .start_IO = dasd_start_diag, 624 .start_IO = dasd_start_diag,
625 .term_IO = dasd_diag_term_IO, 625 .term_IO = dasd_diag_term_IO,
@@ -642,7 +642,7 @@ dasd_diag_init(void)
642 } 642 }
643 ASCEBC(dasd_diag_discipline.ebcname, 4); 643 ASCEBC(dasd_diag_discipline.ebcname, 4);
644 644
645 ctl_set_bit(0, 9); 645 service_subclass_irq_register();
646 register_external_interrupt(0x2603, dasd_ext_handler); 646 register_external_interrupt(0x2603, dasd_ext_handler);
647 dasd_diag_discipline_pointer = &dasd_diag_discipline; 647 dasd_diag_discipline_pointer = &dasd_diag_discipline;
648 return 0; 648 return 0;
@@ -652,7 +652,7 @@ static void __exit
652dasd_diag_cleanup(void) 652dasd_diag_cleanup(void)
653{ 653{
654 unregister_external_interrupt(0x2603, dasd_ext_handler); 654 unregister_external_interrupt(0x2603, dasd_ext_handler);
655 ctl_clear_bit(0, 9); 655 service_subclass_irq_unregister();
656 dasd_diag_discipline_pointer = NULL; 656 dasd_diag_discipline_pointer = NULL;
657} 657}
658 658
diff --git a/drivers/s390/block/dasd_diag.h b/drivers/s390/block/dasd_diag.h
index b8c78267ff3e..4f71fbe60c82 100644
--- a/drivers/s390/block/dasd_diag.h
+++ b/drivers/s390/block/dasd_diag.h
@@ -18,10 +18,6 @@
18#define DEV_CLASS_FBA 0x01 18#define DEV_CLASS_FBA 0x01
19#define DEV_CLASS_ECKD 0x04 19#define DEV_CLASS_ECKD 0x04
20 20
21#define DASD_DIAG_LC_INT_CODE 132
22#define DASD_DIAG_LC_INT_STATUS 133
23#define DASD_DIAG_LC_INT_PARM_31BIT 128
24#define DASD_DIAG_LC_INT_PARM_64BIT 4536
25#define DASD_DIAG_CODE_31BIT 0x03 21#define DASD_DIAG_CODE_31BIT 0x03
26#define DASD_DIAG_CODE_64BIT 0x07 22#define DASD_DIAG_CODE_64BIT 0x07
27 23
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 66360c24bd48..30fb979d684d 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -54,6 +54,15 @@
54#define ECKD_F7(i) (i->factor7) 54#define ECKD_F7(i) (i->factor7)
55#define ECKD_F8(i) (i->factor8) 55#define ECKD_F8(i) (i->factor8)
56 56
57/*
58 * raw track access always map to 64k in memory
59 * so it maps to 16 blocks of 4k per track
60 */
61#define DASD_RAW_BLOCK_PER_TRACK 16
62#define DASD_RAW_BLOCKSIZE 4096
63/* 64k are 128 x 512 byte sectors */
64#define DASD_RAW_SECTORS_PER_TRACK 128
65
57MODULE_LICENSE("GPL"); 66MODULE_LICENSE("GPL");
58 67
59static struct dasd_discipline dasd_eckd_discipline; 68static struct dasd_discipline dasd_eckd_discipline;
@@ -63,7 +72,7 @@ static struct dasd_discipline dasd_eckd_discipline;
63static struct ccw_device_id dasd_eckd_ids[] = { 72static struct ccw_device_id dasd_eckd_ids[] = {
64 { CCW_DEVICE_DEVTYPE (0x3990, 0, 0x3390, 0), .driver_info = 0x1}, 73 { CCW_DEVICE_DEVTYPE (0x3990, 0, 0x3390, 0), .driver_info = 0x1},
65 { CCW_DEVICE_DEVTYPE (0x2105, 0, 0x3390, 0), .driver_info = 0x2}, 74 { CCW_DEVICE_DEVTYPE (0x2105, 0, 0x3390, 0), .driver_info = 0x2},
66 { CCW_DEVICE_DEVTYPE (0x3880, 0, 0x3390, 0), .driver_info = 0x3}, 75 { CCW_DEVICE_DEVTYPE (0x3880, 0, 0x3380, 0), .driver_info = 0x3},
67 { CCW_DEVICE_DEVTYPE (0x3990, 0, 0x3380, 0), .driver_info = 0x4}, 76 { CCW_DEVICE_DEVTYPE (0x3990, 0, 0x3380, 0), .driver_info = 0x4},
68 { CCW_DEVICE_DEVTYPE (0x2105, 0, 0x3380, 0), .driver_info = 0x5}, 77 { CCW_DEVICE_DEVTYPE (0x2105, 0, 0x3380, 0), .driver_info = 0x5},
69 { CCW_DEVICE_DEVTYPE (0x9343, 0, 0x9345, 0), .driver_info = 0x6}, 78 { CCW_DEVICE_DEVTYPE (0x9343, 0, 0x9345, 0), .driver_info = 0x6},
@@ -90,6 +99,18 @@ static struct {
90} *dasd_reserve_req; 99} *dasd_reserve_req;
91static DEFINE_MUTEX(dasd_reserve_mutex); 100static DEFINE_MUTEX(dasd_reserve_mutex);
92 101
102/* definitions for the path verification worker */
103struct path_verification_work_data {
104 struct work_struct worker;
105 struct dasd_device *device;
106 struct dasd_ccw_req cqr;
107 struct ccw1 ccw;
108 __u8 rcd_buffer[DASD_ECKD_RCD_DATA_SIZE];
109 int isglobal;
110 __u8 tbvpm;
111};
112static struct path_verification_work_data *path_verification_worker;
113static DEFINE_MUTEX(dasd_path_verification_mutex);
93 114
94/* initial attempt at a probe function. this can be simplified once 115/* initial attempt at a probe function. this can be simplified once
95 * the other detection code is gone */ 116 * the other detection code is gone */
@@ -373,6 +394,23 @@ static void fill_LRE_data(struct LRE_eckd_data *data, unsigned int trk,
373 data->length = reclen; 394 data->length = reclen;
374 data->operation.operation = 0x03; 395 data->operation.operation = 0x03;
375 break; 396 break;
397 case DASD_ECKD_CCW_WRITE_FULL_TRACK:
398 data->operation.orientation = 0x0;
399 data->operation.operation = 0x3F;
400 data->extended_operation = 0x11;
401 data->length = 0;
402 data->extended_parameter_length = 0x02;
403 if (data->count > 8) {
404 data->extended_parameter[0] = 0xFF;
405 data->extended_parameter[1] = 0xFF;
406 data->extended_parameter[1] <<= (16 - count);
407 } else {
408 data->extended_parameter[0] = 0xFF;
409 data->extended_parameter[0] <<= (8 - count);
410 data->extended_parameter[1] = 0x00;
411 }
412 data->sector = 0xFF;
413 break;
376 case DASD_ECKD_CCW_WRITE_TRACK_DATA: 414 case DASD_ECKD_CCW_WRITE_TRACK_DATA:
377 data->auxiliary.length_valid = 0x1; 415 data->auxiliary.length_valid = 0x1;
378 data->length = reclen; /* not tlf, as one might think */ 416 data->length = reclen; /* not tlf, as one might think */
@@ -396,6 +434,12 @@ static void fill_LRE_data(struct LRE_eckd_data *data, unsigned int trk,
396 case DASD_ECKD_CCW_READ_COUNT: 434 case DASD_ECKD_CCW_READ_COUNT:
397 data->operation.operation = 0x06; 435 data->operation.operation = 0x06;
398 break; 436 break;
437 case DASD_ECKD_CCW_READ_TRACK:
438 data->operation.orientation = 0x1;
439 data->operation.operation = 0x0C;
440 data->extended_parameter_length = 0;
441 data->sector = 0xFF;
442 break;
399 case DASD_ECKD_CCW_READ_TRACK_DATA: 443 case DASD_ECKD_CCW_READ_TRACK_DATA:
400 data->auxiliary.length_valid = 0x1; 444 data->auxiliary.length_valid = 0x1;
401 data->length = tlf; 445 data->length = tlf;
@@ -439,10 +483,16 @@ static int prefix_LRE(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
439 483
440 ccw->cmd_code = DASD_ECKD_CCW_PFX; 484 ccw->cmd_code = DASD_ECKD_CCW_PFX;
441 ccw->flags = 0; 485 ccw->flags = 0;
442 ccw->count = sizeof(*pfxdata); 486 if (cmd == DASD_ECKD_CCW_WRITE_FULL_TRACK) {
443 ccw->cda = (__u32) __pa(pfxdata); 487 ccw->count = sizeof(*pfxdata) + 2;
488 ccw->cda = (__u32) __pa(pfxdata);
489 memset(pfxdata, 0, sizeof(*pfxdata) + 2);
490 } else {
491 ccw->count = sizeof(*pfxdata);
492 ccw->cda = (__u32) __pa(pfxdata);
493 memset(pfxdata, 0, sizeof(*pfxdata));
494 }
444 495
445 memset(pfxdata, 0, sizeof(*pfxdata));
446 /* prefix data */ 496 /* prefix data */
447 if (format > 1) { 497 if (format > 1) {
448 DBF_DEV_EVENT(DBF_ERR, basedev, 498 DBF_DEV_EVENT(DBF_ERR, basedev,
@@ -476,6 +526,7 @@ static int prefix_LRE(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
476 dedata->mask.perm = 0x1; 526 dedata->mask.perm = 0x1;
477 dedata->attributes.operation = basepriv->attrib.operation; 527 dedata->attributes.operation = basepriv->attrib.operation;
478 break; 528 break;
529 case DASD_ECKD_CCW_READ_TRACK:
479 case DASD_ECKD_CCW_READ_TRACK_DATA: 530 case DASD_ECKD_CCW_READ_TRACK_DATA:
480 dedata->mask.perm = 0x1; 531 dedata->mask.perm = 0x1;
481 dedata->attributes.operation = basepriv->attrib.operation; 532 dedata->attributes.operation = basepriv->attrib.operation;
@@ -502,6 +553,11 @@ static int prefix_LRE(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
502 dedata->attributes.operation = DASD_BYPASS_CACHE; 553 dedata->attributes.operation = DASD_BYPASS_CACHE;
503 rc = check_XRC_on_prefix(pfxdata, basedev); 554 rc = check_XRC_on_prefix(pfxdata, basedev);
504 break; 555 break;
556 case DASD_ECKD_CCW_WRITE_FULL_TRACK:
557 dedata->mask.perm = 0x03;
558 dedata->attributes.operation = basepriv->attrib.operation;
559 dedata->blk_size = 0;
560 break;
505 case DASD_ECKD_CCW_WRITE_TRACK_DATA: 561 case DASD_ECKD_CCW_WRITE_TRACK_DATA:
506 dedata->mask.perm = 0x02; 562 dedata->mask.perm = 0x02;
507 dedata->attributes.operation = basepriv->attrib.operation; 563 dedata->attributes.operation = basepriv->attrib.operation;
@@ -755,26 +811,27 @@ static int dasd_eckd_get_uid(struct dasd_device *device, struct dasd_uid *uid)
755 return -EINVAL; 811 return -EINVAL;
756} 812}
757 813
758static struct dasd_ccw_req *dasd_eckd_build_rcd_lpm(struct dasd_device *device, 814static void dasd_eckd_fill_rcd_cqr(struct dasd_device *device,
759 void *rcd_buffer, 815 struct dasd_ccw_req *cqr,
760 struct ciw *ciw, __u8 lpm) 816 __u8 *rcd_buffer,
817 __u8 lpm)
761{ 818{
762 struct dasd_ccw_req *cqr;
763 struct ccw1 *ccw; 819 struct ccw1 *ccw;
764 820 /*
765 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1 /* RCD */, ciw->count, 821 * buffer has to start with EBCDIC "V1.0" to show
766 device); 822 * support for virtual device SNEQ
767 823 */
768 if (IS_ERR(cqr)) { 824 rcd_buffer[0] = 0xE5;
769 DBF_DEV_EVENT(DBF_WARNING, device, "%s", 825 rcd_buffer[1] = 0xF1;
770 "Could not allocate RCD request"); 826 rcd_buffer[2] = 0x4B;
771 return cqr; 827 rcd_buffer[3] = 0xF0;
772 }
773 828
774 ccw = cqr->cpaddr; 829 ccw = cqr->cpaddr;
775 ccw->cmd_code = ciw->cmd; 830 ccw->cmd_code = DASD_ECKD_CCW_RCD;
831 ccw->flags = 0;
776 ccw->cda = (__u32)(addr_t)rcd_buffer; 832 ccw->cda = (__u32)(addr_t)rcd_buffer;
777 ccw->count = ciw->count; 833 ccw->count = DASD_ECKD_RCD_DATA_SIZE;
834 cqr->magic = DASD_ECKD_MAGIC;
778 835
779 cqr->startdev = device; 836 cqr->startdev = device;
780 cqr->memdev = device; 837 cqr->memdev = device;
@@ -784,7 +841,30 @@ static struct dasd_ccw_req *dasd_eckd_build_rcd_lpm(struct dasd_device *device,
784 cqr->retries = 256; 841 cqr->retries = 256;
785 cqr->buildclk = get_clock(); 842 cqr->buildclk = get_clock();
786 cqr->status = DASD_CQR_FILLED; 843 cqr->status = DASD_CQR_FILLED;
787 return cqr; 844 set_bit(DASD_CQR_VERIFY_PATH, &cqr->flags);
845}
846
847static int dasd_eckd_read_conf_immediately(struct dasd_device *device,
848 struct dasd_ccw_req *cqr,
849 __u8 *rcd_buffer,
850 __u8 lpm)
851{
852 struct ciw *ciw;
853 int rc;
854 /*
855 * sanity check: scan for RCD command in extended SenseID data
856 * some devices do not support RCD
857 */
858 ciw = ccw_device_get_ciw(device->cdev, CIW_TYPE_RCD);
859 if (!ciw || ciw->cmd != DASD_ECKD_CCW_RCD)
860 return -EOPNOTSUPP;
861
862 dasd_eckd_fill_rcd_cqr(device, cqr, rcd_buffer, lpm);
863 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
864 set_bit(DASD_CQR_ALLOW_SLOCK, &cqr->flags);
865 cqr->retries = 5;
866 rc = dasd_sleep_on_immediatly(cqr);
867 return rc;
788} 868}
789 869
790static int dasd_eckd_read_conf_lpm(struct dasd_device *device, 870static int dasd_eckd_read_conf_lpm(struct dasd_device *device,
@@ -797,32 +877,29 @@ static int dasd_eckd_read_conf_lpm(struct dasd_device *device,
797 struct dasd_ccw_req *cqr; 877 struct dasd_ccw_req *cqr;
798 878
799 /* 879 /*
800 * scan for RCD command in extended SenseID data 880 * sanity check: scan for RCD command in extended SenseID data
881 * some devices do not support RCD
801 */ 882 */
802 ciw = ccw_device_get_ciw(device->cdev, CIW_TYPE_RCD); 883 ciw = ccw_device_get_ciw(device->cdev, CIW_TYPE_RCD);
803 if (!ciw || ciw->cmd == 0) { 884 if (!ciw || ciw->cmd != DASD_ECKD_CCW_RCD) {
804 ret = -EOPNOTSUPP; 885 ret = -EOPNOTSUPP;
805 goto out_error; 886 goto out_error;
806 } 887 }
807 rcd_buf = kzalloc(ciw->count, GFP_KERNEL | GFP_DMA); 888 rcd_buf = kzalloc(DASD_ECKD_RCD_DATA_SIZE, GFP_KERNEL | GFP_DMA);
808 if (!rcd_buf) { 889 if (!rcd_buf) {
809 ret = -ENOMEM; 890 ret = -ENOMEM;
810 goto out_error; 891 goto out_error;
811 } 892 }
812 893 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1 /* RCD */,
813 /* 894 0, /* use rcd_buf as data ara */
814 * buffer has to start with EBCDIC "V1.0" to show 895 device);
815 * support for virtual device SNEQ
816 */
817 rcd_buf[0] = 0xE5;
818 rcd_buf[1] = 0xF1;
819 rcd_buf[2] = 0x4B;
820 rcd_buf[3] = 0xF0;
821 cqr = dasd_eckd_build_rcd_lpm(device, rcd_buf, ciw, lpm);
822 if (IS_ERR(cqr)) { 896 if (IS_ERR(cqr)) {
823 ret = PTR_ERR(cqr); 897 DBF_DEV_EVENT(DBF_WARNING, device, "%s",
898 "Could not allocate RCD request");
899 ret = -ENOMEM;
824 goto out_error; 900 goto out_error;
825 } 901 }
902 dasd_eckd_fill_rcd_cqr(device, cqr, rcd_buf, lpm);
826 ret = dasd_sleep_on(cqr); 903 ret = dasd_sleep_on(cqr);
827 /* 904 /*
828 * on success we update the user input parms 905 * on success we update the user input parms
@@ -831,7 +908,7 @@ static int dasd_eckd_read_conf_lpm(struct dasd_device *device,
831 if (ret) 908 if (ret)
832 goto out_error; 909 goto out_error;
833 910
834 *rcd_buffer_size = ciw->count; 911 *rcd_buffer_size = DASD_ECKD_RCD_DATA_SIZE;
835 *rcd_buffer = rcd_buf; 912 *rcd_buffer = rcd_buf;
836 return 0; 913 return 0;
837out_error: 914out_error:
@@ -901,18 +978,18 @@ static int dasd_eckd_read_conf(struct dasd_device *device)
901 void *conf_data; 978 void *conf_data;
902 int conf_len, conf_data_saved; 979 int conf_len, conf_data_saved;
903 int rc; 980 int rc;
904 __u8 lpm; 981 __u8 lpm, opm;
905 struct dasd_eckd_private *private; 982 struct dasd_eckd_private *private;
906 struct dasd_eckd_path *path_data; 983 struct dasd_path *path_data;
907 984
908 private = (struct dasd_eckd_private *) device->private; 985 private = (struct dasd_eckd_private *) device->private;
909 path_data = (struct dasd_eckd_path *) &private->path_data; 986 path_data = &device->path_data;
910 path_data->opm = ccw_device_get_path_mask(device->cdev); 987 opm = ccw_device_get_path_mask(device->cdev);
911 lpm = 0x80; 988 lpm = 0x80;
912 conf_data_saved = 0; 989 conf_data_saved = 0;
913 /* get configuration data per operational path */ 990 /* get configuration data per operational path */
914 for (lpm = 0x80; lpm; lpm>>= 1) { 991 for (lpm = 0x80; lpm; lpm>>= 1) {
915 if (lpm & path_data->opm){ 992 if (lpm & opm) {
916 rc = dasd_eckd_read_conf_lpm(device, &conf_data, 993 rc = dasd_eckd_read_conf_lpm(device, &conf_data,
917 &conf_len, lpm); 994 &conf_len, lpm);
918 if (rc && rc != -EOPNOTSUPP) { /* -EOPNOTSUPP is ok */ 995 if (rc && rc != -EOPNOTSUPP) { /* -EOPNOTSUPP is ok */
@@ -925,6 +1002,8 @@ static int dasd_eckd_read_conf(struct dasd_device *device)
925 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s", 1002 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
926 "No configuration data " 1003 "No configuration data "
927 "retrieved"); 1004 "retrieved");
1005 /* no further analysis possible */
1006 path_data->opm |= lpm;
928 continue; /* no error */ 1007 continue; /* no error */
929 } 1008 }
930 /* save first valid configuration data */ 1009 /* save first valid configuration data */
@@ -948,6 +1027,7 @@ static int dasd_eckd_read_conf(struct dasd_device *device)
948 path_data->ppm |= lpm; 1027 path_data->ppm |= lpm;
949 break; 1028 break;
950 } 1029 }
1030 path_data->opm |= lpm;
951 if (conf_data != private->conf_data) 1031 if (conf_data != private->conf_data)
952 kfree(conf_data); 1032 kfree(conf_data);
953 } 1033 }
@@ -955,6 +1035,140 @@ static int dasd_eckd_read_conf(struct dasd_device *device)
955 return 0; 1035 return 0;
956} 1036}
957 1037
1038static int verify_fcx_max_data(struct dasd_device *device, __u8 lpm)
1039{
1040 struct dasd_eckd_private *private;
1041 int mdc;
1042 u32 fcx_max_data;
1043
1044 private = (struct dasd_eckd_private *) device->private;
1045 if (private->fcx_max_data) {
1046 mdc = ccw_device_get_mdc(device->cdev, lpm);
1047 if ((mdc < 0)) {
1048 dev_warn(&device->cdev->dev,
1049 "Detecting the maximum data size for zHPF "
1050 "requests failed (rc=%d) for a new path %x\n",
1051 mdc, lpm);
1052 return mdc;
1053 }
1054 fcx_max_data = mdc * FCX_MAX_DATA_FACTOR;
1055 if (fcx_max_data < private->fcx_max_data) {
1056 dev_warn(&device->cdev->dev,
1057 "The maximum data size for zHPF requests %u "
1058 "on a new path %x is below the active maximum "
1059 "%u\n", fcx_max_data, lpm,
1060 private->fcx_max_data);
1061 return -EACCES;
1062 }
1063 }
1064 return 0;
1065}
1066
1067static void do_path_verification_work(struct work_struct *work)
1068{
1069 struct path_verification_work_data *data;
1070 struct dasd_device *device;
1071 __u8 lpm, opm, npm, ppm, epm;
1072 unsigned long flags;
1073 int rc;
1074
1075 data = container_of(work, struct path_verification_work_data, worker);
1076 device = data->device;
1077
1078 opm = 0;
1079 npm = 0;
1080 ppm = 0;
1081 epm = 0;
1082 for (lpm = 0x80; lpm; lpm >>= 1) {
1083 if (lpm & data->tbvpm) {
1084 memset(data->rcd_buffer, 0, sizeof(data->rcd_buffer));
1085 memset(&data->cqr, 0, sizeof(data->cqr));
1086 data->cqr.cpaddr = &data->ccw;
1087 rc = dasd_eckd_read_conf_immediately(device, &data->cqr,
1088 data->rcd_buffer,
1089 lpm);
1090 if (!rc) {
1091 switch (dasd_eckd_path_access(data->rcd_buffer,
1092 DASD_ECKD_RCD_DATA_SIZE)) {
1093 case 0x02:
1094 npm |= lpm;
1095 break;
1096 case 0x03:
1097 ppm |= lpm;
1098 break;
1099 }
1100 opm |= lpm;
1101 } else if (rc == -EOPNOTSUPP) {
1102 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
1103 "path verification: No configuration "
1104 "data retrieved");
1105 opm |= lpm;
1106 } else if (rc == -EAGAIN) {
1107 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",
1108 "path verification: device is stopped,"
1109 " try again later");
1110 epm |= lpm;
1111 } else {
1112 dev_warn(&device->cdev->dev,
1113 "Reading device feature codes failed "
1114 "(rc=%d) for new path %x\n", rc, lpm);
1115 continue;
1116 }
1117 if (verify_fcx_max_data(device, lpm)) {
1118 opm &= ~lpm;
1119 npm &= ~lpm;
1120 ppm &= ~lpm;
1121 }
1122 }
1123 }
1124 /*
1125 * There is a small chance that a path is lost again between
1126 * above path verification and the following modification of
1127 * the device opm mask. We could avoid that race here by using
1128 * yet another path mask, but we rather deal with this unlikely
1129 * situation in dasd_start_IO.
1130 */
1131 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
1132 if (!device->path_data.opm && opm) {
1133 device->path_data.opm = opm;
1134 dasd_generic_path_operational(device);
1135 } else
1136 device->path_data.opm |= opm;
1137 device->path_data.npm |= npm;
1138 device->path_data.ppm |= ppm;
1139 device->path_data.tbvpm |= epm;
1140 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
1141
1142 dasd_put_device(device);
1143 if (data->isglobal)
1144 mutex_unlock(&dasd_path_verification_mutex);
1145 else
1146 kfree(data);
1147}
1148
1149static int dasd_eckd_verify_path(struct dasd_device *device, __u8 lpm)
1150{
1151 struct path_verification_work_data *data;
1152
1153 data = kmalloc(sizeof(*data), GFP_ATOMIC | GFP_DMA);
1154 if (!data) {
1155 if (mutex_trylock(&dasd_path_verification_mutex)) {
1156 data = path_verification_worker;
1157 data->isglobal = 1;
1158 } else
1159 return -ENOMEM;
1160 } else {
1161 memset(data, 0, sizeof(*data));
1162 data->isglobal = 0;
1163 }
1164 INIT_WORK(&data->worker, do_path_verification_work);
1165 dasd_get_device(device);
1166 data->device = device;
1167 data->tbvpm = lpm;
1168 schedule_work(&data->worker);
1169 return 0;
1170}
1171
958static int dasd_eckd_read_features(struct dasd_device *device) 1172static int dasd_eckd_read_features(struct dasd_device *device)
959{ 1173{
960 struct dasd_psf_prssd_data *prssdp; 1174 struct dasd_psf_prssd_data *prssdp;
@@ -1105,6 +1319,37 @@ static void dasd_eckd_validate_server(struct dasd_device *device)
1105 "returned rc=%d", private->uid.ssid, rc); 1319 "returned rc=%d", private->uid.ssid, rc);
1106} 1320}
1107 1321
1322static u32 get_fcx_max_data(struct dasd_device *device)
1323{
1324#if defined(CONFIG_64BIT)
1325 int tpm, mdc;
1326 int fcx_in_css, fcx_in_gneq, fcx_in_features;
1327 struct dasd_eckd_private *private;
1328
1329 if (dasd_nofcx)
1330 return 0;
1331 /* is transport mode supported? */
1332 private = (struct dasd_eckd_private *) device->private;
1333 fcx_in_css = css_general_characteristics.fcx;
1334 fcx_in_gneq = private->gneq->reserved2[7] & 0x04;
1335 fcx_in_features = private->features.feature[40] & 0x80;
1336 tpm = fcx_in_css && fcx_in_gneq && fcx_in_features;
1337
1338 if (!tpm)
1339 return 0;
1340
1341 mdc = ccw_device_get_mdc(device->cdev, 0);
1342 if (mdc < 0) {
1343 dev_warn(&device->cdev->dev, "Detecting the maximum supported"
1344 " data size for zHPF requests failed\n");
1345 return 0;
1346 } else
1347 return mdc * FCX_MAX_DATA_FACTOR;
1348#else
1349 return 0;
1350#endif
1351}
1352
1108/* 1353/*
1109 * Check device characteristics. 1354 * Check device characteristics.
1110 * If the device is accessible using ECKD discipline, the device is enabled. 1355 * If the device is accessible using ECKD discipline, the device is enabled.
@@ -1190,7 +1435,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
1190 goto out_err2; 1435 goto out_err2;
1191 } 1436 }
1192 /* 1437 /*
1193 * dasd_eckd_vaildate_server is done on the first device that 1438 * dasd_eckd_validate_server is done on the first device that
1194 * is found for an LCU. All later other devices have to wait 1439 * is found for an LCU. All later other devices have to wait
1195 * for it, so they will read the correct feature codes. 1440 * for it, so they will read the correct feature codes.
1196 */ 1441 */
@@ -1216,13 +1461,15 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
1216 "Read device characteristic failed, rc=%d", rc); 1461 "Read device characteristic failed, rc=%d", rc);
1217 goto out_err3; 1462 goto out_err3;
1218 } 1463 }
1219 /* find the vaild cylinder size */ 1464 /* find the valid cylinder size */
1220 if (private->rdc_data.no_cyl == LV_COMPAT_CYL && 1465 if (private->rdc_data.no_cyl == LV_COMPAT_CYL &&
1221 private->rdc_data.long_no_cyl) 1466 private->rdc_data.long_no_cyl)
1222 private->real_cyl = private->rdc_data.long_no_cyl; 1467 private->real_cyl = private->rdc_data.long_no_cyl;
1223 else 1468 else
1224 private->real_cyl = private->rdc_data.no_cyl; 1469 private->real_cyl = private->rdc_data.no_cyl;
1225 1470
1471 private->fcx_max_data = get_fcx_max_data(device);
1472
1226 readonly = dasd_device_is_ro(device); 1473 readonly = dasd_device_is_ro(device);
1227 if (readonly) 1474 if (readonly)
1228 set_bit(DASD_FLAG_DEVICE_RO, &device->flags); 1475 set_bit(DASD_FLAG_DEVICE_RO, &device->flags);
@@ -1364,10 +1611,8 @@ static void dasd_eckd_analysis_callback(struct dasd_ccw_req *init_cqr,
1364 1611
1365static int dasd_eckd_start_analysis(struct dasd_block *block) 1612static int dasd_eckd_start_analysis(struct dasd_block *block)
1366{ 1613{
1367 struct dasd_eckd_private *private;
1368 struct dasd_ccw_req *init_cqr; 1614 struct dasd_ccw_req *init_cqr;
1369 1615
1370 private = (struct dasd_eckd_private *) block->base->private;
1371 init_cqr = dasd_eckd_analysis_ccw(block->base); 1616 init_cqr = dasd_eckd_analysis_ccw(block->base);
1372 if (IS_ERR(init_cqr)) 1617 if (IS_ERR(init_cqr))
1373 return PTR_ERR(init_cqr); 1618 return PTR_ERR(init_cqr);
@@ -1404,6 +1649,13 @@ static int dasd_eckd_end_analysis(struct dasd_block *block)
1404 dasd_sfree_request(init_cqr, device); 1649 dasd_sfree_request(init_cqr, device);
1405 } 1650 }
1406 1651
1652 if (device->features & DASD_FEATURE_USERAW) {
1653 block->bp_block = DASD_RAW_BLOCKSIZE;
1654 blk_per_trk = DASD_RAW_BLOCK_PER_TRACK;
1655 block->s2b_shift = 3;
1656 goto raw;
1657 }
1658
1407 if (status == INIT_CQR_UNFORMATTED) { 1659 if (status == INIT_CQR_UNFORMATTED) {
1408 dev_warn(&device->cdev->dev, "The DASD is not formatted\n"); 1660 dev_warn(&device->cdev->dev, "The DASD is not formatted\n");
1409 return -EMEDIUMTYPE; 1661 return -EMEDIUMTYPE;
@@ -1441,6 +1693,7 @@ static int dasd_eckd_end_analysis(struct dasd_block *block)
1441 dev_warn(&device->cdev->dev, 1693 dev_warn(&device->cdev->dev,
1442 "Track 0 has no records following the VTOC\n"); 1694 "Track 0 has no records following the VTOC\n");
1443 } 1695 }
1696
1444 if (count_area != NULL && count_area->kl == 0) { 1697 if (count_area != NULL && count_area->kl == 0) {
1445 /* we found notthing violating our disk layout */ 1698 /* we found notthing violating our disk layout */
1446 if (dasd_check_blocksize(count_area->dl) == 0) 1699 if (dasd_check_blocksize(count_area->dl) == 0)
@@ -1456,6 +1709,8 @@ static int dasd_eckd_end_analysis(struct dasd_block *block)
1456 block->s2b_shift++; 1709 block->s2b_shift++;
1457 1710
1458 blk_per_trk = recs_per_track(&private->rdc_data, 0, block->bp_block); 1711 blk_per_trk = recs_per_track(&private->rdc_data, 0, block->bp_block);
1712
1713raw:
1459 block->blocks = (private->real_cyl * 1714 block->blocks = (private->real_cyl *
1460 private->rdc_data.trk_per_cyl * 1715 private->rdc_data.trk_per_cyl *
1461 blk_per_trk); 1716 blk_per_trk);
@@ -1716,6 +1971,7 @@ static void dasd_eckd_handle_terminated_request(struct dasd_ccw_req *cqr)
1716 if (cqr->block && (cqr->startdev != cqr->block->base)) { 1971 if (cqr->block && (cqr->startdev != cqr->block->base)) {
1717 dasd_eckd_reset_ccw_to_base_io(cqr); 1972 dasd_eckd_reset_ccw_to_base_io(cqr);
1718 cqr->startdev = cqr->block->base; 1973 cqr->startdev = cqr->block->base;
1974 cqr->lpm = cqr->block->base->path_data.opm;
1719 } 1975 }
1720}; 1976};
1721 1977
@@ -1744,9 +2000,9 @@ dasd_eckd_erp_postaction(struct dasd_ccw_req * cqr)
1744 return dasd_default_erp_postaction; 2000 return dasd_default_erp_postaction;
1745} 2001}
1746 2002
1747 2003static void dasd_eckd_check_for_device_change(struct dasd_device *device,
1748static void dasd_eckd_handle_unsolicited_interrupt(struct dasd_device *device, 2004 struct dasd_ccw_req *cqr,
1749 struct irb *irb) 2005 struct irb *irb)
1750{ 2006{
1751 char mask; 2007 char mask;
1752 char *sense = NULL; 2008 char *sense = NULL;
@@ -1770,51 +2026,42 @@ static void dasd_eckd_handle_unsolicited_interrupt(struct dasd_device *device,
1770 /* schedule worker to reload device */ 2026 /* schedule worker to reload device */
1771 dasd_reload_device(device); 2027 dasd_reload_device(device);
1772 } 2028 }
1773
1774 dasd_generic_handle_state_change(device); 2029 dasd_generic_handle_state_change(device);
1775 return; 2030 return;
1776 } 2031 }
1777 2032
2033 sense = dasd_get_sense(irb);
2034 if (!sense)
2035 return;
2036
1778 /* summary unit check */ 2037 /* summary unit check */
1779 if ((scsw_dstat(&irb->scsw) & DEV_STAT_UNIT_CHECK) && 2038 if ((sense[27] & DASD_SENSE_BIT_0) && (sense[7] == 0x0D) &&
1780 (irb->ecw[7] == 0x0D)) { 2039 (scsw_dstat(&irb->scsw) & DEV_STAT_UNIT_CHECK)) {
1781 dasd_alias_handle_summary_unit_check(device, irb); 2040 dasd_alias_handle_summary_unit_check(device, irb);
1782 return; 2041 return;
1783 } 2042 }
1784 2043
1785 sense = dasd_get_sense(irb);
1786 /* service information message SIM */ 2044 /* service information message SIM */
1787 if (sense && !(sense[27] & DASD_SENSE_BIT_0) && 2045 if (!cqr && !(sense[27] & DASD_SENSE_BIT_0) &&
1788 ((sense[6] & DASD_SIM_SENSE) == DASD_SIM_SENSE)) { 2046 ((sense[6] & DASD_SIM_SENSE) == DASD_SIM_SENSE)) {
1789 dasd_3990_erp_handle_sim(device, sense); 2047 dasd_3990_erp_handle_sim(device, sense);
1790 dasd_schedule_device_bh(device);
1791 return; 2048 return;
1792 } 2049 }
1793 2050
1794 if ((scsw_cc(&irb->scsw) == 1) && 2051 /* loss of device reservation is handled via base devices only
1795 (scsw_fctl(&irb->scsw) & SCSW_FCTL_START_FUNC) && 2052 * as alias devices may be used with several bases
1796 (scsw_actl(&irb->scsw) & SCSW_ACTL_START_PEND) && 2053 */
1797 (scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND)) { 2054 if (device->block && (sense[27] & DASD_SENSE_BIT_0) &&
1798 /* fake irb do nothing, they are handled elsewhere */ 2055 (sense[7] == 0x3F) &&
1799 dasd_schedule_device_bh(device); 2056 (scsw_dstat(&irb->scsw) & DEV_STAT_UNIT_CHECK) &&
1800 return; 2057 test_bit(DASD_FLAG_IS_RESERVED, &device->flags)) {
1801 } 2058 if (device->features & DASD_FEATURE_FAILONSLCK)
1802 2059 set_bit(DASD_FLAG_LOCK_STOLEN, &device->flags);
1803 if (!sense) { 2060 clear_bit(DASD_FLAG_IS_RESERVED, &device->flags);
1804 /* just report other unsolicited interrupts */ 2061 dev_err(&device->cdev->dev,
1805 DBF_DEV_EVENT(DBF_ERR, device, "%s", 2062 "The device reservation was lost\n");
1806 "unsolicited interrupt received");
1807 } else {
1808 DBF_DEV_EVENT(DBF_ERR, device, "%s",
1809 "unsolicited interrupt received "
1810 "(sense available)");
1811 device->discipline->dump_sense_dbf(device, irb, "unsolicited");
1812 } 2063 }
1813 2064}
1814 dasd_schedule_device_bh(device);
1815 return;
1816};
1817
1818 2065
1819static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single( 2066static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single(
1820 struct dasd_device *startdev, 2067 struct dasd_device *startdev,
@@ -1995,7 +2242,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single(
1995 cqr->memdev = startdev; 2242 cqr->memdev = startdev;
1996 cqr->block = block; 2243 cqr->block = block;
1997 cqr->expires = startdev->default_expires * HZ; /* default 5 minutes */ 2244 cqr->expires = startdev->default_expires * HZ; /* default 5 minutes */
1998 cqr->lpm = private->path_data.ppm; 2245 cqr->lpm = startdev->path_data.ppm;
1999 cqr->retries = 256; 2246 cqr->retries = 256;
2000 cqr->buildclk = get_clock(); 2247 cqr->buildclk = get_clock();
2001 cqr->status = DASD_CQR_FILLED; 2248 cqr->status = DASD_CQR_FILLED;
@@ -2015,7 +2262,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_track(
2015 unsigned int blk_per_trk, 2262 unsigned int blk_per_trk,
2016 unsigned int blksize) 2263 unsigned int blksize)
2017{ 2264{
2018 struct dasd_eckd_private *private;
2019 unsigned long *idaws; 2265 unsigned long *idaws;
2020 struct dasd_ccw_req *cqr; 2266 struct dasd_ccw_req *cqr;
2021 struct ccw1 *ccw; 2267 struct ccw1 *ccw;
@@ -2034,7 +2280,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_track(
2034 unsigned int recoffs; 2280 unsigned int recoffs;
2035 2281
2036 basedev = block->base; 2282 basedev = block->base;
2037 private = (struct dasd_eckd_private *) basedev->private;
2038 if (rq_data_dir(req) == READ) 2283 if (rq_data_dir(req) == READ)
2039 cmd = DASD_ECKD_CCW_READ_TRACK_DATA; 2284 cmd = DASD_ECKD_CCW_READ_TRACK_DATA;
2040 else if (rq_data_dir(req) == WRITE) 2285 else if (rq_data_dir(req) == WRITE)
@@ -2172,7 +2417,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_track(
2172 cqr->memdev = startdev; 2417 cqr->memdev = startdev;
2173 cqr->block = block; 2418 cqr->block = block;
2174 cqr->expires = startdev->default_expires * HZ; /* default 5 minutes */ 2419 cqr->expires = startdev->default_expires * HZ; /* default 5 minutes */
2175 cqr->lpm = private->path_data.ppm; 2420 cqr->lpm = startdev->path_data.ppm;
2176 cqr->retries = 256; 2421 cqr->retries = 256;
2177 cqr->buildclk = get_clock(); 2422 cqr->buildclk = get_clock();
2178 cqr->status = DASD_CQR_FILLED; 2423 cqr->status = DASD_CQR_FILLED;
@@ -2307,8 +2552,7 @@ static int prepare_itcw(struct itcw *itcw,
2307 2552
2308 dcw = itcw_add_dcw(itcw, pfx_cmd, 0, 2553 dcw = itcw_add_dcw(itcw, pfx_cmd, 0,
2309 &pfxdata, sizeof(pfxdata), total_data_size); 2554 &pfxdata, sizeof(pfxdata), total_data_size);
2310 2555 return IS_ERR(dcw) ? PTR_ERR(dcw) : 0;
2311 return rc;
2312} 2556}
2313 2557
2314static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( 2558static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
@@ -2324,7 +2568,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
2324 unsigned int blk_per_trk, 2568 unsigned int blk_per_trk,
2325 unsigned int blksize) 2569 unsigned int blksize)
2326{ 2570{
2327 struct dasd_eckd_private *private;
2328 struct dasd_ccw_req *cqr; 2571 struct dasd_ccw_req *cqr;
2329 struct req_iterator iter; 2572 struct req_iterator iter;
2330 struct bio_vec *bv; 2573 struct bio_vec *bv;
@@ -2337,9 +2580,14 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
2337 struct tidaw *last_tidaw = NULL; 2580 struct tidaw *last_tidaw = NULL;
2338 int itcw_op; 2581 int itcw_op;
2339 size_t itcw_size; 2582 size_t itcw_size;
2583 u8 tidaw_flags;
2584 unsigned int seg_len, part_len, len_to_track_end;
2585 unsigned char new_track;
2586 sector_t recid, trkid;
2587 unsigned int offs;
2588 unsigned int count, count_to_trk_end;
2340 2589
2341 basedev = block->base; 2590 basedev = block->base;
2342 private = (struct dasd_eckd_private *) basedev->private;
2343 if (rq_data_dir(req) == READ) { 2591 if (rq_data_dir(req) == READ) {
2344 cmd = DASD_ECKD_CCW_READ_TRACK_DATA; 2592 cmd = DASD_ECKD_CCW_READ_TRACK_DATA;
2345 itcw_op = ITCW_OP_READ; 2593 itcw_op = ITCW_OP_READ;
@@ -2352,12 +2600,16 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
2352 /* trackbased I/O needs address all memory via TIDAWs, 2600 /* trackbased I/O needs address all memory via TIDAWs,
2353 * not just for 64 bit addresses. This allows us to map 2601 * not just for 64 bit addresses. This allows us to map
2354 * each segment directly to one tidaw. 2602 * each segment directly to one tidaw.
2603 * In the case of write requests, additional tidaws may
2604 * be needed when a segment crosses a track boundary.
2355 */ 2605 */
2356 trkcount = last_trk - first_trk + 1; 2606 trkcount = last_trk - first_trk + 1;
2357 ctidaw = 0; 2607 ctidaw = 0;
2358 rq_for_each_segment(bv, req, iter) { 2608 rq_for_each_segment(bv, req, iter) {
2359 ++ctidaw; 2609 ++ctidaw;
2360 } 2610 }
2611 if (rq_data_dir(req) == WRITE)
2612 ctidaw += (last_trk - first_trk);
2361 2613
2362 /* Allocate the ccw request. */ 2614 /* Allocate the ccw request. */
2363 itcw_size = itcw_calc_size(0, ctidaw, 0); 2615 itcw_size = itcw_calc_size(0, ctidaw, 0);
@@ -2365,15 +2617,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
2365 if (IS_ERR(cqr)) 2617 if (IS_ERR(cqr))
2366 return cqr; 2618 return cqr;
2367 2619
2368 cqr->cpmode = 1;
2369 cqr->startdev = startdev;
2370 cqr->memdev = startdev;
2371 cqr->block = block;
2372 cqr->expires = 100*HZ;
2373 cqr->buildclk = get_clock();
2374 cqr->status = DASD_CQR_FILLED;
2375 cqr->retries = 10;
2376
2377 /* transfer length factor: how many bytes to read from the last track */ 2620 /* transfer length factor: how many bytes to read from the last track */
2378 if (first_trk == last_trk) 2621 if (first_trk == last_trk)
2379 tlf = last_offs - first_offs + 1; 2622 tlf = last_offs - first_offs + 1;
@@ -2382,8 +2625,11 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
2382 tlf *= blksize; 2625 tlf *= blksize;
2383 2626
2384 itcw = itcw_init(cqr->data, itcw_size, itcw_op, 0, ctidaw, 0); 2627 itcw = itcw_init(cqr->data, itcw_size, itcw_op, 0, ctidaw, 0);
2628 if (IS_ERR(itcw)) {
2629 dasd_sfree_request(cqr, startdev);
2630 return ERR_PTR(-EINVAL);
2631 }
2385 cqr->cpaddr = itcw_get_tcw(itcw); 2632 cqr->cpaddr = itcw_get_tcw(itcw);
2386
2387 if (prepare_itcw(itcw, first_trk, last_trk, 2633 if (prepare_itcw(itcw, first_trk, last_trk,
2388 cmd, basedev, startdev, 2634 cmd, basedev, startdev,
2389 first_offs + 1, 2635 first_offs + 1,
@@ -2396,31 +2642,70 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
2396 dasd_sfree_request(cqr, startdev); 2642 dasd_sfree_request(cqr, startdev);
2397 return ERR_PTR(-EAGAIN); 2643 return ERR_PTR(-EAGAIN);
2398 } 2644 }
2399 2645 len_to_track_end = 0;
2400 /* 2646 /*
2401 * A tidaw can address 4k of memory, but must not cross page boundaries 2647 * A tidaw can address 4k of memory, but must not cross page boundaries
2402 * We can let the block layer handle this by setting 2648 * We can let the block layer handle this by setting
2403 * blk_queue_segment_boundary to page boundaries and 2649 * blk_queue_segment_boundary to page boundaries and
2404 * blk_max_segment_size to page size when setting up the request queue. 2650 * blk_max_segment_size to page size when setting up the request queue.
2651 * For write requests, a TIDAW must not cross track boundaries, because
2652 * we have to set the CBC flag on the last tidaw for each track.
2405 */ 2653 */
2406 rq_for_each_segment(bv, req, iter) { 2654 if (rq_data_dir(req) == WRITE) {
2407 dst = page_address(bv->bv_page) + bv->bv_offset; 2655 new_track = 1;
2408 last_tidaw = itcw_add_tidaw(itcw, 0x00, dst, bv->bv_len); 2656 recid = first_rec;
2409 if (IS_ERR(last_tidaw)) 2657 rq_for_each_segment(bv, req, iter) {
2410 return (struct dasd_ccw_req *)last_tidaw; 2658 dst = page_address(bv->bv_page) + bv->bv_offset;
2659 seg_len = bv->bv_len;
2660 while (seg_len) {
2661 if (new_track) {
2662 trkid = recid;
2663 offs = sector_div(trkid, blk_per_trk);
2664 count_to_trk_end = blk_per_trk - offs;
2665 count = min((last_rec - recid + 1),
2666 (sector_t)count_to_trk_end);
2667 len_to_track_end = count * blksize;
2668 recid += count;
2669 new_track = 0;
2670 }
2671 part_len = min(seg_len, len_to_track_end);
2672 seg_len -= part_len;
2673 len_to_track_end -= part_len;
2674 /* We need to end the tidaw at track end */
2675 if (!len_to_track_end) {
2676 new_track = 1;
2677 tidaw_flags = TIDAW_FLAGS_INSERT_CBC;
2678 } else
2679 tidaw_flags = 0;
2680 last_tidaw = itcw_add_tidaw(itcw, tidaw_flags,
2681 dst, part_len);
2682 if (IS_ERR(last_tidaw))
2683 return ERR_PTR(-EINVAL);
2684 dst += part_len;
2685 }
2686 }
2687 } else {
2688 rq_for_each_segment(bv, req, iter) {
2689 dst = page_address(bv->bv_page) + bv->bv_offset;
2690 last_tidaw = itcw_add_tidaw(itcw, 0x00,
2691 dst, bv->bv_len);
2692 if (IS_ERR(last_tidaw))
2693 return ERR_PTR(-EINVAL);
2694 }
2411 } 2695 }
2412 2696 last_tidaw->flags |= TIDAW_FLAGS_LAST;
2413 last_tidaw->flags |= 0x80; 2697 last_tidaw->flags &= ~TIDAW_FLAGS_INSERT_CBC;
2414 itcw_finalize(itcw); 2698 itcw_finalize(itcw);
2415 2699
2416 if (blk_noretry_request(req) || 2700 if (blk_noretry_request(req) ||
2417 block->base->features & DASD_FEATURE_FAILFAST) 2701 block->base->features & DASD_FEATURE_FAILFAST)
2418 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); 2702 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
2703 cqr->cpmode = 1;
2419 cqr->startdev = startdev; 2704 cqr->startdev = startdev;
2420 cqr->memdev = startdev; 2705 cqr->memdev = startdev;
2421 cqr->block = block; 2706 cqr->block = block;
2422 cqr->expires = startdev->default_expires * HZ; /* default 5 minutes */ 2707 cqr->expires = startdev->default_expires * HZ; /* default 5 minutes */
2423 cqr->lpm = private->path_data.ppm; 2708 cqr->lpm = startdev->path_data.ppm;
2424 cqr->retries = 256; 2709 cqr->retries = 256;
2425 cqr->buildclk = get_clock(); 2710 cqr->buildclk = get_clock();
2426 cqr->status = DASD_CQR_FILLED; 2711 cqr->status = DASD_CQR_FILLED;
@@ -2431,11 +2716,9 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
2431 struct dasd_block *block, 2716 struct dasd_block *block,
2432 struct request *req) 2717 struct request *req)
2433{ 2718{
2434 int tpm, cmdrtd, cmdwtd; 2719 int cmdrtd, cmdwtd;
2435 int use_prefix; 2720 int use_prefix;
2436#if defined(CONFIG_64BIT) 2721 int fcx_multitrack;
2437 int fcx_in_css, fcx_in_gneq, fcx_in_features;
2438#endif
2439 struct dasd_eckd_private *private; 2722 struct dasd_eckd_private *private;
2440 struct dasd_device *basedev; 2723 struct dasd_device *basedev;
2441 sector_t first_rec, last_rec; 2724 sector_t first_rec, last_rec;
@@ -2443,6 +2726,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
2443 unsigned int first_offs, last_offs; 2726 unsigned int first_offs, last_offs;
2444 unsigned int blk_per_trk, blksize; 2727 unsigned int blk_per_trk, blksize;
2445 int cdlspecial; 2728 int cdlspecial;
2729 unsigned int data_size;
2446 struct dasd_ccw_req *cqr; 2730 struct dasd_ccw_req *cqr;
2447 2731
2448 basedev = block->base; 2732 basedev = block->base;
@@ -2461,15 +2745,11 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
2461 last_offs = sector_div(last_trk, blk_per_trk); 2745 last_offs = sector_div(last_trk, blk_per_trk);
2462 cdlspecial = (private->uses_cdl && first_rec < 2*blk_per_trk); 2746 cdlspecial = (private->uses_cdl && first_rec < 2*blk_per_trk);
2463 2747
2464 /* is transport mode supported? */ 2748 fcx_multitrack = private->features.feature[40] & 0x20;
2465#if defined(CONFIG_64BIT) 2749 data_size = blk_rq_bytes(req);
2466 fcx_in_css = css_general_characteristics.fcx; 2750 /* tpm write request add CBC data on each track boundary */
2467 fcx_in_gneq = private->gneq->reserved2[7] & 0x04; 2751 if (rq_data_dir(req) == WRITE)
2468 fcx_in_features = private->features.feature[40] & 0x80; 2752 data_size += (last_trk - first_trk) * 4;
2469 tpm = fcx_in_css && fcx_in_gneq && fcx_in_features;
2470#else
2471 tpm = 0;
2472#endif
2473 2753
2474 /* is read track data and write track data in command mode supported? */ 2754 /* is read track data and write track data in command mode supported? */
2475 cmdrtd = private->features.feature[9] & 0x20; 2755 cmdrtd = private->features.feature[9] & 0x20;
@@ -2479,13 +2759,15 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
2479 cqr = NULL; 2759 cqr = NULL;
2480 if (cdlspecial || dasd_page_cache) { 2760 if (cdlspecial || dasd_page_cache) {
2481 /* do nothing, just fall through to the cmd mode single case */ 2761 /* do nothing, just fall through to the cmd mode single case */
2482 } else if (!dasd_nofcx && tpm && (first_trk == last_trk)) { 2762 } else if ((data_size <= private->fcx_max_data)
2763 && (fcx_multitrack || (first_trk == last_trk))) {
2483 cqr = dasd_eckd_build_cp_tpm_track(startdev, block, req, 2764 cqr = dasd_eckd_build_cp_tpm_track(startdev, block, req,
2484 first_rec, last_rec, 2765 first_rec, last_rec,
2485 first_trk, last_trk, 2766 first_trk, last_trk,
2486 first_offs, last_offs, 2767 first_offs, last_offs,
2487 blk_per_trk, blksize); 2768 blk_per_trk, blksize);
2488 if (IS_ERR(cqr) && PTR_ERR(cqr) != -EAGAIN) 2769 if (IS_ERR(cqr) && (PTR_ERR(cqr) != -EAGAIN) &&
2770 (PTR_ERR(cqr) != -ENOMEM))
2489 cqr = NULL; 2771 cqr = NULL;
2490 } else if (use_prefix && 2772 } else if (use_prefix &&
2491 (((rq_data_dir(req) == READ) && cmdrtd) || 2773 (((rq_data_dir(req) == READ) && cmdrtd) ||
@@ -2495,7 +2777,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
2495 first_trk, last_trk, 2777 first_trk, last_trk,
2496 first_offs, last_offs, 2778 first_offs, last_offs,
2497 blk_per_trk, blksize); 2779 blk_per_trk, blksize);
2498 if (IS_ERR(cqr) && PTR_ERR(cqr) != -EAGAIN) 2780 if (IS_ERR(cqr) && (PTR_ERR(cqr) != -EAGAIN) &&
2781 (PTR_ERR(cqr) != -ENOMEM))
2499 cqr = NULL; 2782 cqr = NULL;
2500 } 2783 }
2501 if (!cqr) 2784 if (!cqr)
@@ -2507,6 +2790,133 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
2507 return cqr; 2790 return cqr;
2508} 2791}
2509 2792
2793static struct dasd_ccw_req *dasd_raw_build_cp(struct dasd_device *startdev,
2794 struct dasd_block *block,
2795 struct request *req)
2796{
2797 unsigned long *idaws;
2798 struct dasd_device *basedev;
2799 struct dasd_ccw_req *cqr;
2800 struct ccw1 *ccw;
2801 struct req_iterator iter;
2802 struct bio_vec *bv;
2803 char *dst;
2804 unsigned char cmd;
2805 unsigned int trkcount;
2806 unsigned int seg_len, len_to_track_end;
2807 unsigned int first_offs;
2808 unsigned int cidaw, cplength, datasize;
2809 sector_t first_trk, last_trk;
2810 unsigned int pfx_datasize;
2811
2812 /*
2813 * raw track access needs to be mutiple of 64k and on 64k boundary
2814 */
2815 if ((blk_rq_pos(req) % DASD_RAW_SECTORS_PER_TRACK) != 0) {
2816 cqr = ERR_PTR(-EINVAL);
2817 goto out;
2818 }
2819 if (((blk_rq_pos(req) + blk_rq_sectors(req)) %
2820 DASD_RAW_SECTORS_PER_TRACK) != 0) {
2821 cqr = ERR_PTR(-EINVAL);
2822 goto out;
2823 }
2824
2825 first_trk = blk_rq_pos(req) / DASD_RAW_SECTORS_PER_TRACK;
2826 last_trk = (blk_rq_pos(req) + blk_rq_sectors(req) - 1) /
2827 DASD_RAW_SECTORS_PER_TRACK;
2828 trkcount = last_trk - first_trk + 1;
2829 first_offs = 0;
2830 basedev = block->base;
2831
2832 if (rq_data_dir(req) == READ)
2833 cmd = DASD_ECKD_CCW_READ_TRACK;
2834 else if (rq_data_dir(req) == WRITE)
2835 cmd = DASD_ECKD_CCW_WRITE_FULL_TRACK;
2836 else {
2837 cqr = ERR_PTR(-EINVAL);
2838 goto out;
2839 }
2840
2841 /*
2842 * Raw track based I/O needs IDAWs for each page,
2843 * and not just for 64 bit addresses.
2844 */
2845 cidaw = trkcount * DASD_RAW_BLOCK_PER_TRACK;
2846
2847 /* 1x prefix + one read/write ccw per track */
2848 cplength = 1 + trkcount;
2849
2850 /*
2851 * struct PFX_eckd_data has up to 2 byte as extended parameter
2852 * this is needed for write full track and has to be mentioned
2853 * separately
2854 * add 8 instead of 2 to keep 8 byte boundary
2855 */
2856 pfx_datasize = sizeof(struct PFX_eckd_data) + 8;
2857
2858 datasize = pfx_datasize + cidaw * sizeof(unsigned long long);
2859
2860 /* Allocate the ccw request. */
2861 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, cplength,
2862 datasize, startdev);
2863 if (IS_ERR(cqr))
2864 goto out;
2865 ccw = cqr->cpaddr;
2866
2867 if (prefix_LRE(ccw++, cqr->data, first_trk, last_trk, cmd,
2868 basedev, startdev, 1 /* format */, first_offs + 1,
2869 trkcount, 0, 0) == -EAGAIN) {
2870 /* Clock not in sync and XRC is enabled.
2871 * Try again later.
2872 */
2873 dasd_sfree_request(cqr, startdev);
2874 cqr = ERR_PTR(-EAGAIN);
2875 goto out;
2876 }
2877
2878 idaws = (unsigned long *)(cqr->data + pfx_datasize);
2879
2880 len_to_track_end = 0;
2881
2882 rq_for_each_segment(bv, req, iter) {
2883 dst = page_address(bv->bv_page) + bv->bv_offset;
2884 seg_len = bv->bv_len;
2885 if (!len_to_track_end) {
2886 ccw[-1].flags |= CCW_FLAG_CC;
2887 ccw->cmd_code = cmd;
2888 /* maximum 3390 track size */
2889 ccw->count = 57326;
2890 /* 64k map to one track */
2891 len_to_track_end = 65536;
2892 ccw->cda = (__u32)(addr_t)idaws;
2893 ccw->flags |= CCW_FLAG_IDA;
2894 ccw->flags |= CCW_FLAG_SLI;
2895 ccw++;
2896 }
2897 len_to_track_end -= seg_len;
2898 idaws = idal_create_words(idaws, dst, seg_len);
2899 }
2900
2901 if (blk_noretry_request(req) ||
2902 block->base->features & DASD_FEATURE_FAILFAST)
2903 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
2904 cqr->startdev = startdev;
2905 cqr->memdev = startdev;
2906 cqr->block = block;
2907 cqr->expires = startdev->default_expires * HZ;
2908 cqr->lpm = startdev->path_data.ppm;
2909 cqr->retries = 256;
2910 cqr->buildclk = get_clock();
2911 cqr->status = DASD_CQR_FILLED;
2912
2913 if (IS_ERR(cqr) && PTR_ERR(cqr) != -EAGAIN)
2914 cqr = NULL;
2915out:
2916 return cqr;
2917}
2918
2919
2510static int 2920static int
2511dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req) 2921dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req)
2512{ 2922{
@@ -2611,7 +3021,10 @@ static struct dasd_ccw_req *dasd_eckd_build_alias_cp(struct dasd_device *base,
2611 3021
2612 spin_lock_irqsave(get_ccwdev_lock(startdev->cdev), flags); 3022 spin_lock_irqsave(get_ccwdev_lock(startdev->cdev), flags);
2613 private->count++; 3023 private->count++;
2614 cqr = dasd_eckd_build_cp(startdev, block, req); 3024 if ((base->features & DASD_FEATURE_USERAW))
3025 cqr = dasd_raw_build_cp(startdev, block, req);
3026 else
3027 cqr = dasd_eckd_build_cp(startdev, block, req);
2615 if (IS_ERR(cqr)) 3028 if (IS_ERR(cqr))
2616 private->count--; 3029 private->count--;
2617 spin_unlock_irqrestore(get_ccwdev_lock(startdev->cdev), flags); 3030 spin_unlock_irqrestore(get_ccwdev_lock(startdev->cdev), flags);
@@ -2699,6 +3112,8 @@ dasd_eckd_release(struct dasd_device *device)
2699 cqr->status = DASD_CQR_FILLED; 3112 cqr->status = DASD_CQR_FILLED;
2700 3113
2701 rc = dasd_sleep_on_immediatly(cqr); 3114 rc = dasd_sleep_on_immediatly(cqr);
3115 if (!rc)
3116 clear_bit(DASD_FLAG_IS_RESERVED, &device->flags);
2702 3117
2703 if (useglobal) 3118 if (useglobal)
2704 mutex_unlock(&dasd_reserve_mutex); 3119 mutex_unlock(&dasd_reserve_mutex);
@@ -2752,6 +3167,8 @@ dasd_eckd_reserve(struct dasd_device *device)
2752 cqr->status = DASD_CQR_FILLED; 3167 cqr->status = DASD_CQR_FILLED;
2753 3168
2754 rc = dasd_sleep_on_immediatly(cqr); 3169 rc = dasd_sleep_on_immediatly(cqr);
3170 if (!rc)
3171 set_bit(DASD_FLAG_IS_RESERVED, &device->flags);
2755 3172
2756 if (useglobal) 3173 if (useglobal)
2757 mutex_unlock(&dasd_reserve_mutex); 3174 mutex_unlock(&dasd_reserve_mutex);
@@ -2804,6 +3221,76 @@ dasd_eckd_steal_lock(struct dasd_device *device)
2804 cqr->status = DASD_CQR_FILLED; 3221 cqr->status = DASD_CQR_FILLED;
2805 3222
2806 rc = dasd_sleep_on_immediatly(cqr); 3223 rc = dasd_sleep_on_immediatly(cqr);
3224 if (!rc)
3225 set_bit(DASD_FLAG_IS_RESERVED, &device->flags);
3226
3227 if (useglobal)
3228 mutex_unlock(&dasd_reserve_mutex);
3229 else
3230 dasd_sfree_request(cqr, cqr->memdev);
3231 return rc;
3232}
3233
3234/*
3235 * SNID - Sense Path Group ID
3236 * This ioctl may be used in situations where I/O is stalled due to
3237 * a reserve, so if the normal dasd_smalloc_request fails, we use the
3238 * preallocated dasd_reserve_req.
3239 */
3240static int dasd_eckd_snid(struct dasd_device *device,
3241 void __user *argp)
3242{
3243 struct dasd_ccw_req *cqr;
3244 int rc;
3245 struct ccw1 *ccw;
3246 int useglobal;
3247 struct dasd_snid_ioctl_data usrparm;
3248
3249 if (!capable(CAP_SYS_ADMIN))
3250 return -EACCES;
3251
3252 if (copy_from_user(&usrparm, argp, sizeof(usrparm)))
3253 return -EFAULT;
3254
3255 useglobal = 0;
3256 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1,
3257 sizeof(struct dasd_snid_data), device);
3258 if (IS_ERR(cqr)) {
3259 mutex_lock(&dasd_reserve_mutex);
3260 useglobal = 1;
3261 cqr = &dasd_reserve_req->cqr;
3262 memset(cqr, 0, sizeof(*cqr));
3263 memset(&dasd_reserve_req->ccw, 0,
3264 sizeof(dasd_reserve_req->ccw));
3265 cqr->cpaddr = &dasd_reserve_req->ccw;
3266 cqr->data = &dasd_reserve_req->data;
3267 cqr->magic = DASD_ECKD_MAGIC;
3268 }
3269 ccw = cqr->cpaddr;
3270 ccw->cmd_code = DASD_ECKD_CCW_SNID;
3271 ccw->flags |= CCW_FLAG_SLI;
3272 ccw->count = 12;
3273 ccw->cda = (__u32)(addr_t) cqr->data;
3274 cqr->startdev = device;
3275 cqr->memdev = device;
3276 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
3277 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
3278 set_bit(DASD_CQR_ALLOW_SLOCK, &cqr->flags);
3279 cqr->retries = 5;
3280 cqr->expires = 10 * HZ;
3281 cqr->buildclk = get_clock();
3282 cqr->status = DASD_CQR_FILLED;
3283 cqr->lpm = usrparm.path_mask;
3284
3285 rc = dasd_sleep_on_immediatly(cqr);
3286 /* verify that I/O processing didn't modify the path mask */
3287 if (!rc && usrparm.path_mask && (cqr->lpm != usrparm.path_mask))
3288 rc = -EIO;
3289 if (!rc) {
3290 usrparm.data = *((struct dasd_snid_data *)cqr->data);
3291 if (copy_to_user(argp, &usrparm, sizeof(usrparm)))
3292 rc = -EFAULT;
3293 }
2807 3294
2808 if (useglobal) 3295 if (useglobal)
2809 mutex_unlock(&dasd_reserve_mutex); 3296 mutex_unlock(&dasd_reserve_mutex);
@@ -3047,6 +3534,8 @@ dasd_eckd_ioctl(struct dasd_block *block, unsigned int cmd, void __user *argp)
3047 return dasd_eckd_reserve(device); 3534 return dasd_eckd_reserve(device);
3048 case BIODASDSLCK: 3535 case BIODASDSLCK:
3049 return dasd_eckd_steal_lock(device); 3536 return dasd_eckd_steal_lock(device);
3537 case BIODASDSNID:
3538 return dasd_eckd_snid(device, argp);
3050 case BIODASDSYMMIO: 3539 case BIODASDSYMMIO:
3051 return dasd_symm_io(device, argp); 3540 return dasd_symm_io(device, argp);
3052 default: 3541 default:
@@ -3093,19 +3582,19 @@ dasd_eckd_dump_sense_dbf(struct dasd_device *device, struct irb *irb,
3093 char *reason) 3582 char *reason)
3094{ 3583{
3095 u64 *sense; 3584 u64 *sense;
3585 u64 *stat;
3096 3586
3097 sense = (u64 *) dasd_get_sense(irb); 3587 sense = (u64 *) dasd_get_sense(irb);
3588 stat = (u64 *) &irb->scsw;
3098 if (sense) { 3589 if (sense) {
3099 DBF_DEV_EVENT(DBF_EMERG, device, 3590 DBF_DEV_EVENT(DBF_EMERG, device, "%s: %016llx %08x : "
3100 "%s: %s %02x%02x%02x %016llx %016llx %016llx " 3591 "%016llx %016llx %016llx %016llx",
3101 "%016llx", reason, 3592 reason, *stat, *((u32 *) (stat + 1)),
3102 scsw_is_tm(&irb->scsw) ? "t" : "c", 3593 sense[0], sense[1], sense[2], sense[3]);
3103 scsw_cc(&irb->scsw), scsw_cstat(&irb->scsw),
3104 scsw_dstat(&irb->scsw), sense[0], sense[1],
3105 sense[2], sense[3]);
3106 } else { 3594 } else {
3107 DBF_DEV_EVENT(DBF_EMERG, device, "%s", 3595 DBF_DEV_EVENT(DBF_EMERG, device, "%s: %016llx %08x : %s",
3108 "SORRY - NO VALID SENSE AVAILABLE\n"); 3596 reason, *stat, *((u32 *) (stat + 1)),
3597 "NO VALID SENSE");
3109 } 3598 }
3110} 3599}
3111 3600
@@ -3131,9 +3620,12 @@ static void dasd_eckd_dump_sense_ccw(struct dasd_device *device,
3131 " I/O status report for device %s:\n", 3620 " I/O status report for device %s:\n",
3132 dev_name(&device->cdev->dev)); 3621 dev_name(&device->cdev->dev));
3133 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 3622 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3134 " in req: %p CS: 0x%02X DS: 0x%02X CC: 0x%02X RC: %d\n", 3623 " in req: %p CC:%02X FC:%02X AC:%02X SC:%02X DS:%02X "
3135 req, scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw), 3624 "CS:%02X RC:%d\n",
3136 scsw_cc(&irb->scsw), req ? req->intrc : 0); 3625 req, scsw_cc(&irb->scsw), scsw_fctl(&irb->scsw),
3626 scsw_actl(&irb->scsw), scsw_stctl(&irb->scsw),
3627 scsw_dstat(&irb->scsw), scsw_cstat(&irb->scsw),
3628 req ? req->intrc : 0);
3137 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 3629 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3138 " device %s: Failing CCW: %p\n", 3630 " device %s: Failing CCW: %p\n",
3139 dev_name(&device->cdev->dev), 3631 dev_name(&device->cdev->dev),
@@ -3218,10 +3710,8 @@ static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
3218{ 3710{
3219 char *page; 3711 char *page;
3220 int len, sl, sct, residual; 3712 int len, sl, sct, residual;
3221
3222 struct tsb *tsb; 3713 struct tsb *tsb;
3223 u8 *sense; 3714 u8 *sense, *rcq;
3224
3225 3715
3226 page = (char *) get_zeroed_page(GFP_ATOMIC); 3716 page = (char *) get_zeroed_page(GFP_ATOMIC);
3227 if (page == NULL) { 3717 if (page == NULL) {
@@ -3234,11 +3724,13 @@ static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
3234 " I/O status report for device %s:\n", 3724 " I/O status report for device %s:\n",
3235 dev_name(&device->cdev->dev)); 3725 dev_name(&device->cdev->dev));
3236 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 3726 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3237 " in req: %p CS: 0x%02X DS: 0x%02X CC: 0x%02X RC: %d " 3727 " in req: %p CC:%02X FC:%02X AC:%02X SC:%02X DS:%02X "
3238 "fcxs: 0x%02X schxs: 0x%02X\n", req, 3728 "CS:%02X fcxs:%02X schxs:%02X RC:%d\n",
3239 scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw), 3729 req, scsw_cc(&irb->scsw), scsw_fctl(&irb->scsw),
3240 scsw_cc(&irb->scsw), req->intrc, 3730 scsw_actl(&irb->scsw), scsw_stctl(&irb->scsw),
3241 irb->scsw.tm.fcxs, irb->scsw.tm.schxs); 3731 scsw_dstat(&irb->scsw), scsw_cstat(&irb->scsw),
3732 irb->scsw.tm.fcxs, irb->scsw.tm.schxs,
3733 req ? req->intrc : 0);
3242 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 3734 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3243 " device %s: Failing TCW: %p\n", 3735 " device %s: Failing TCW: %p\n",
3244 dev_name(&device->cdev->dev), 3736 dev_name(&device->cdev->dev),
@@ -3246,7 +3738,7 @@ static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
3246 3738
3247 tsb = NULL; 3739 tsb = NULL;
3248 sense = NULL; 3740 sense = NULL;
3249 if (irb->scsw.tm.tcw && (irb->scsw.tm.fcxs == 0x01)) 3741 if (irb->scsw.tm.tcw && (irb->scsw.tm.fcxs & 0x01))
3250 tsb = tcw_get_tsb( 3742 tsb = tcw_get_tsb(
3251 (struct tcw *)(unsigned long)irb->scsw.tm.tcw); 3743 (struct tcw *)(unsigned long)irb->scsw.tm.tcw);
3252 3744
@@ -3285,12 +3777,15 @@ static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
3285 case 2: /* ts_ddpc */ 3777 case 2: /* ts_ddpc */
3286 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 3778 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3287 " tsb->tsa.ddpc.rc %d\n", tsb->tsa.ddpc.rc); 3779 " tsb->tsa.ddpc.rc %d\n", tsb->tsa.ddpc.rc);
3288 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 3780 for (sl = 0; sl < 2; sl++) {
3289 " tsb->tsa.ddpc.rcq: "); 3781 len += sprintf(page + len,
3290 for (sl = 0; sl < 16; sl++) { 3782 KERN_ERR PRINTK_HEADER
3783 " tsb->tsa.ddpc.rcq %2d-%2d: ",
3784 (8 * sl), ((8 * sl) + 7));
3785 rcq = tsb->tsa.ddpc.rcq;
3291 for (sct = 0; sct < 8; sct++) { 3786 for (sct = 0; sct < 8; sct++) {
3292 len += sprintf(page + len, " %02x", 3787 len += sprintf(page + len, " %02x",
3293 tsb->tsa.ddpc.rcq[sl]); 3788 rcq[8 * sl + sct]);
3294 } 3789 }
3295 len += sprintf(page + len, "\n"); 3790 len += sprintf(page + len, "\n");
3296 } 3791 }
@@ -3344,7 +3839,7 @@ static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
3344static void dasd_eckd_dump_sense(struct dasd_device *device, 3839static void dasd_eckd_dump_sense(struct dasd_device *device,
3345 struct dasd_ccw_req *req, struct irb *irb) 3840 struct dasd_ccw_req *req, struct irb *irb)
3346{ 3841{
3347 if (req && scsw_is_tm(&req->irb.scsw)) 3842 if (scsw_is_tm(&irb->scsw))
3348 dasd_eckd_dump_sense_tcw(device, req, irb); 3843 dasd_eckd_dump_sense_tcw(device, req, irb);
3349 else 3844 else
3350 dasd_eckd_dump_sense_ccw(device, req, irb); 3845 dasd_eckd_dump_sense_ccw(device, req, irb);
@@ -3479,14 +3974,17 @@ out_err:
3479} 3974}
3480 3975
3481static struct ccw_driver dasd_eckd_driver = { 3976static struct ccw_driver dasd_eckd_driver = {
3482 .name = "dasd-eckd", 3977 .driver = {
3483 .owner = THIS_MODULE, 3978 .name = "dasd-eckd",
3979 .owner = THIS_MODULE,
3980 },
3484 .ids = dasd_eckd_ids, 3981 .ids = dasd_eckd_ids,
3485 .probe = dasd_eckd_probe, 3982 .probe = dasd_eckd_probe,
3486 .remove = dasd_generic_remove, 3983 .remove = dasd_generic_remove,
3487 .set_offline = dasd_generic_set_offline, 3984 .set_offline = dasd_generic_set_offline,
3488 .set_online = dasd_eckd_set_online, 3985 .set_online = dasd_eckd_set_online,
3489 .notify = dasd_generic_notify, 3986 .notify = dasd_generic_notify,
3987 .path_event = dasd_generic_path_event,
3490 .freeze = dasd_generic_pm_freeze, 3988 .freeze = dasd_generic_pm_freeze,
3491 .thaw = dasd_generic_restore_device, 3989 .thaw = dasd_generic_restore_device,
3492 .restore = dasd_generic_restore_device, 3990 .restore = dasd_generic_restore_device,
@@ -3510,10 +4008,11 @@ static struct dasd_discipline dasd_eckd_discipline = {
3510 .owner = THIS_MODULE, 4008 .owner = THIS_MODULE,
3511 .name = "ECKD", 4009 .name = "ECKD",
3512 .ebcname = "ECKD", 4010 .ebcname = "ECKD",
3513 .max_blocks = 240, 4011 .max_blocks = 190,
3514 .check_device = dasd_eckd_check_characteristics, 4012 .check_device = dasd_eckd_check_characteristics,
3515 .uncheck_device = dasd_eckd_uncheck_device, 4013 .uncheck_device = dasd_eckd_uncheck_device,
3516 .do_analysis = dasd_eckd_do_analysis, 4014 .do_analysis = dasd_eckd_do_analysis,
4015 .verify_path = dasd_eckd_verify_path,
3517 .ready_to_online = dasd_eckd_ready_to_online, 4016 .ready_to_online = dasd_eckd_ready_to_online,
3518 .online_to_ready = dasd_eckd_online_to_ready, 4017 .online_to_ready = dasd_eckd_online_to_ready,
3519 .fill_geometry = dasd_eckd_fill_geometry, 4018 .fill_geometry = dasd_eckd_fill_geometry,
@@ -3523,7 +4022,7 @@ static struct dasd_discipline dasd_eckd_discipline = {
3523 .format_device = dasd_eckd_format_device, 4022 .format_device = dasd_eckd_format_device,
3524 .erp_action = dasd_eckd_erp_action, 4023 .erp_action = dasd_eckd_erp_action,
3525 .erp_postaction = dasd_eckd_erp_postaction, 4024 .erp_postaction = dasd_eckd_erp_postaction,
3526 .handle_unsolicited_interrupt = dasd_eckd_handle_unsolicited_interrupt, 4025 .check_for_device_change = dasd_eckd_check_for_device_change,
3527 .build_cp = dasd_eckd_build_alias_cp, 4026 .build_cp = dasd_eckd_build_alias_cp,
3528 .free_cp = dasd_eckd_free_alias_cp, 4027 .free_cp = dasd_eckd_free_alias_cp,
3529 .dump_sense = dasd_eckd_dump_sense, 4028 .dump_sense = dasd_eckd_dump_sense,
@@ -3546,11 +4045,19 @@ dasd_eckd_init(void)
3546 GFP_KERNEL | GFP_DMA); 4045 GFP_KERNEL | GFP_DMA);
3547 if (!dasd_reserve_req) 4046 if (!dasd_reserve_req)
3548 return -ENOMEM; 4047 return -ENOMEM;
4048 path_verification_worker = kmalloc(sizeof(*path_verification_worker),
4049 GFP_KERNEL | GFP_DMA);
4050 if (!path_verification_worker) {
4051 kfree(dasd_reserve_req);
4052 return -ENOMEM;
4053 }
3549 ret = ccw_driver_register(&dasd_eckd_driver); 4054 ret = ccw_driver_register(&dasd_eckd_driver);
3550 if (!ret) 4055 if (!ret)
3551 wait_for_device_probe(); 4056 wait_for_device_probe();
3552 else 4057 else {
4058 kfree(path_verification_worker);
3553 kfree(dasd_reserve_req); 4059 kfree(dasd_reserve_req);
4060 }
3554 return ret; 4061 return ret;
3555} 4062}
3556 4063
@@ -3558,6 +4065,7 @@ static void __exit
3558dasd_eckd_cleanup(void) 4065dasd_eckd_cleanup(void)
3559{ 4066{
3560 ccw_driver_unregister(&dasd_eckd_driver); 4067 ccw_driver_unregister(&dasd_eckd_driver);
4068 kfree(path_verification_worker);
3561 kfree(dasd_reserve_req); 4069 kfree(dasd_reserve_req);
3562} 4070}
3563 4071
diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h
index 0eb49655a6cd..4a688a873a77 100644
--- a/drivers/s390/block/dasd_eckd.h
+++ b/drivers/s390/block/dasd_eckd.h
@@ -27,6 +27,7 @@
27#define DASD_ECKD_CCW_WRITE_CKD 0x1d 27#define DASD_ECKD_CCW_WRITE_CKD 0x1d
28#define DASD_ECKD_CCW_READ_CKD 0x1e 28#define DASD_ECKD_CCW_READ_CKD 0x1e
29#define DASD_ECKD_CCW_PSF 0x27 29#define DASD_ECKD_CCW_PSF 0x27
30#define DASD_ECKD_CCW_SNID 0x34
30#define DASD_ECKD_CCW_RSSD 0x3e 31#define DASD_ECKD_CCW_RSSD 0x3e
31#define DASD_ECKD_CCW_LOCATE_RECORD 0x47 32#define DASD_ECKD_CCW_LOCATE_RECORD 0x47
32#define DASD_ECKD_CCW_SNSS 0x54 33#define DASD_ECKD_CCW_SNSS 0x54
@@ -36,14 +37,17 @@
36#define DASD_ECKD_CCW_WRITE_KD_MT 0x8d 37#define DASD_ECKD_CCW_WRITE_KD_MT 0x8d
37#define DASD_ECKD_CCW_READ_KD_MT 0x8e 38#define DASD_ECKD_CCW_READ_KD_MT 0x8e
38#define DASD_ECKD_CCW_RELEASE 0x94 39#define DASD_ECKD_CCW_RELEASE 0x94
40#define DASD_ECKD_CCW_WRITE_FULL_TRACK 0x95
39#define DASD_ECKD_CCW_READ_CKD_MT 0x9e 41#define DASD_ECKD_CCW_READ_CKD_MT 0x9e
40#define DASD_ECKD_CCW_WRITE_CKD_MT 0x9d 42#define DASD_ECKD_CCW_WRITE_CKD_MT 0x9d
41#define DASD_ECKD_CCW_WRITE_TRACK_DATA 0xA5 43#define DASD_ECKD_CCW_WRITE_TRACK_DATA 0xA5
42#define DASD_ECKD_CCW_READ_TRACK_DATA 0xA6 44#define DASD_ECKD_CCW_READ_TRACK_DATA 0xA6
43#define DASD_ECKD_CCW_RESERVE 0xB4 45#define DASD_ECKD_CCW_RESERVE 0xB4
46#define DASD_ECKD_CCW_READ_TRACK 0xDE
44#define DASD_ECKD_CCW_PFX 0xE7 47#define DASD_ECKD_CCW_PFX 0xE7
45#define DASD_ECKD_CCW_PFX_READ 0xEA 48#define DASD_ECKD_CCW_PFX_READ 0xEA
46#define DASD_ECKD_CCW_RSCK 0xF9 49#define DASD_ECKD_CCW_RSCK 0xF9
50#define DASD_ECKD_CCW_RCD 0xFA
47 51
48/* 52/*
49 * Perform Subsystem Function / Sub-Orders 53 * Perform Subsystem Function / Sub-Orders
@@ -56,6 +60,11 @@
56 */ 60 */
57#define LV_COMPAT_CYL 0xFFFE 61#define LV_COMPAT_CYL 0xFFFE
58 62
63
64#define FCX_MAX_DATA_FACTOR 65536
65#define DASD_ECKD_RCD_DATA_SIZE 256
66
67
59/***************************************************************************** 68/*****************************************************************************
60 * SECTION: Type Definitions 69 * SECTION: Type Definitions
61 ****************************************************************************/ 70 ****************************************************************************/
@@ -330,12 +339,6 @@ struct dasd_gneq {
330 __u8 reserved2[22]; 339 __u8 reserved2[22];
331} __attribute__ ((packed)); 340} __attribute__ ((packed));
332 341
333struct dasd_eckd_path {
334 __u8 opm;
335 __u8 ppm;
336 __u8 npm;
337};
338
339struct dasd_rssd_features { 342struct dasd_rssd_features {
340 char feature[256]; 343 char feature[256];
341} __attribute__((packed)); 344} __attribute__((packed));
@@ -441,7 +444,6 @@ struct dasd_eckd_private {
441 struct vd_sneq *vdsneq; 444 struct vd_sneq *vdsneq;
442 struct dasd_gneq *gneq; 445 struct dasd_gneq *gneq;
443 446
444 struct dasd_eckd_path path_data;
445 struct eckd_count count_area[5]; 447 struct eckd_count count_area[5];
446 int init_cqr_status; 448 int init_cqr_status;
447 int uses_cdl; 449 int uses_cdl;
@@ -454,6 +456,8 @@ struct dasd_eckd_private {
454 struct alias_pav_group *pavgroup; 456 struct alias_pav_group *pavgroup;
455 struct alias_lcu *lcu; 457 struct alias_lcu *lcu;
456 int count; 458 int count;
459
460 u32 fcx_max_data;
457}; 461};
458 462
459 463
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c
index 7158f9528ecc..77f778b7b070 100644
--- a/drivers/s390/block/dasd_eer.c
+++ b/drivers/s390/block/dasd_eer.c
@@ -17,7 +17,6 @@
17#include <linux/device.h> 17#include <linux/device.h>
18#include <linux/poll.h> 18#include <linux/poll.h>
19#include <linux/mutex.h> 19#include <linux/mutex.h>
20#include <linux/smp_lock.h>
21#include <linux/err.h> 20#include <linux/err.h>
22#include <linux/slab.h> 21#include <linux/slab.h>
23 22
@@ -474,6 +473,7 @@ int dasd_eer_enable(struct dasd_device *device)
474 cqr->retries = 255; 473 cqr->retries = 255;
475 cqr->expires = 10 * HZ; 474 cqr->expires = 10 * HZ;
476 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); 475 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
476 set_bit(DASD_CQR_ALLOW_SLOCK, &cqr->flags);
477 477
478 ccw = cqr->cpaddr; 478 ccw = cqr->cpaddr;
479 ccw->cmd_code = DASD_ECKD_CCW_SNSS; 479 ccw->cmd_code = DASD_ECKD_CCW_SNSS;
@@ -670,6 +670,7 @@ static const struct file_operations dasd_eer_fops = {
670 .read = &dasd_eer_read, 670 .read = &dasd_eer_read,
671 .poll = &dasd_eer_poll, 671 .poll = &dasd_eer_poll,
672 .owner = THIS_MODULE, 672 .owner = THIS_MODULE,
673 .llseek = noop_llseek,
673}; 674};
674 675
675static struct miscdevice *dasd_eer_dev = NULL; 676static struct miscdevice *dasd_eer_dev = NULL;
diff --git a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c
index 7656384a811d..0eafe2e421e7 100644
--- a/drivers/s390/block/dasd_erp.c
+++ b/drivers/s390/block/dasd_erp.c
@@ -96,7 +96,8 @@ dasd_default_erp_action(struct dasd_ccw_req *cqr)
96 DBF_DEV_EVENT(DBF_DEBUG, device, 96 DBF_DEV_EVENT(DBF_DEBUG, device,
97 "default ERP called (%i retries left)", 97 "default ERP called (%i retries left)",
98 cqr->retries); 98 cqr->retries);
99 cqr->lpm = LPM_ANYPATH; 99 if (!test_bit(DASD_CQR_VERIFY_PATH, &cqr->flags))
100 cqr->lpm = device->path_data.opm;
100 cqr->status = DASD_CQR_FILLED; 101 cqr->status = DASD_CQR_FILLED;
101 } else { 102 } else {
102 pr_err("%s: default ERP has run out of retries and failed\n", 103 pr_err("%s: default ERP has run out of retries and failed\n",
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
index bec5486e0e6d..4b71b1164868 100644
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -65,14 +65,17 @@ dasd_fba_set_online(struct ccw_device *cdev)
65} 65}
66 66
67static struct ccw_driver dasd_fba_driver = { 67static struct ccw_driver dasd_fba_driver = {
68 .name = "dasd-fba", 68 .driver = {
69 .owner = THIS_MODULE, 69 .name = "dasd-fba",
70 .owner = THIS_MODULE,
71 },
70 .ids = dasd_fba_ids, 72 .ids = dasd_fba_ids,
71 .probe = dasd_fba_probe, 73 .probe = dasd_fba_probe,
72 .remove = dasd_generic_remove, 74 .remove = dasd_generic_remove,
73 .set_offline = dasd_generic_set_offline, 75 .set_offline = dasd_generic_set_offline,
74 .set_online = dasd_fba_set_online, 76 .set_online = dasd_fba_set_online,
75 .notify = dasd_generic_notify, 77 .notify = dasd_generic_notify,
78 .path_event = dasd_generic_path_event,
76 .freeze = dasd_generic_pm_freeze, 79 .freeze = dasd_generic_pm_freeze,
77 .thaw = dasd_generic_restore_device, 80 .thaw = dasd_generic_restore_device,
78 .restore = dasd_generic_restore_device, 81 .restore = dasd_generic_restore_device,
@@ -164,6 +167,7 @@ dasd_fba_check_characteristics(struct dasd_device *device)
164 } 167 }
165 168
166 device->default_expires = DASD_EXPIRES; 169 device->default_expires = DASD_EXPIRES;
170 device->path_data.opm = LPM_ANYPATH;
167 171
168 readonly = dasd_device_is_ro(device); 172 readonly = dasd_device_is_ro(device);
169 if (readonly) 173 if (readonly)
@@ -231,24 +235,16 @@ dasd_fba_erp_postaction(struct dasd_ccw_req * cqr)
231 return NULL; 235 return NULL;
232} 236}
233 237
234static void dasd_fba_handle_unsolicited_interrupt(struct dasd_device *device, 238static void dasd_fba_check_for_device_change(struct dasd_device *device,
235 struct irb *irb) 239 struct dasd_ccw_req *cqr,
240 struct irb *irb)
236{ 241{
237 char mask; 242 char mask;
238 243
239 /* first of all check for state change pending interrupt */ 244 /* first of all check for state change pending interrupt */
240 mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP; 245 mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP;
241 if ((irb->scsw.cmd.dstat & mask) == mask) { 246 if ((irb->scsw.cmd.dstat & mask) == mask)
242 dasd_generic_handle_state_change(device); 247 dasd_generic_handle_state_change(device);
243 return;
244 }
245
246 /* check for unsolicited interrupts */
247 DBF_DEV_EVENT(DBF_WARNING, device, "%s",
248 "unsolicited interrupt received");
249 device->discipline->dump_sense_dbf(device, irb, "unsolicited");
250 dasd_schedule_device_bh(device);
251 return;
252}; 248};
253 249
254static struct dasd_ccw_req *dasd_fba_build_cp(struct dasd_device * memdev, 250static struct dasd_ccw_req *dasd_fba_build_cp(struct dasd_device * memdev,
@@ -596,13 +592,14 @@ static struct dasd_discipline dasd_fba_discipline = {
596 .max_blocks = 96, 592 .max_blocks = 96,
597 .check_device = dasd_fba_check_characteristics, 593 .check_device = dasd_fba_check_characteristics,
598 .do_analysis = dasd_fba_do_analysis, 594 .do_analysis = dasd_fba_do_analysis,
595 .verify_path = dasd_generic_verify_path,
599 .fill_geometry = dasd_fba_fill_geometry, 596 .fill_geometry = dasd_fba_fill_geometry,
600 .start_IO = dasd_start_IO, 597 .start_IO = dasd_start_IO,
601 .term_IO = dasd_term_IO, 598 .term_IO = dasd_term_IO,
602 .handle_terminated_request = dasd_fba_handle_terminated_request, 599 .handle_terminated_request = dasd_fba_handle_terminated_request,
603 .erp_action = dasd_fba_erp_action, 600 .erp_action = dasd_fba_erp_action,
604 .erp_postaction = dasd_fba_erp_postaction, 601 .erp_postaction = dasd_fba_erp_postaction,
605 .handle_unsolicited_interrupt = dasd_fba_handle_unsolicited_interrupt, 602 .check_for_device_change = dasd_fba_check_for_device_change,
606 .build_cp = dasd_fba_build_cp, 603 .build_cp = dasd_fba_build_cp,
607 .free_cp = dasd_fba_free_cp, 604 .free_cp = dasd_fba_free_cp,
608 .dump_sense = dasd_fba_dump_sense, 605 .dump_sense = dasd_fba_dump_sense,
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
index 30a1ca3d08b7..19a1ff03d65e 100644
--- a/drivers/s390/block/dasd_genhd.c
+++ b/drivers/s390/block/dasd_genhd.c
@@ -73,7 +73,7 @@ int dasd_gendisk_alloc(struct dasd_block *block)
73 if (base->features & DASD_FEATURE_READONLY || 73 if (base->features & DASD_FEATURE_READONLY ||
74 test_bit(DASD_FLAG_DEVICE_RO, &base->flags)) 74 test_bit(DASD_FLAG_DEVICE_RO, &base->flags))
75 set_disk_ro(gdp, 1); 75 set_disk_ro(gdp, 1);
76 gdp->private_data = block; 76 dasd_add_link_to_gendisk(gdp, base);
77 gdp->queue = block->request_queue; 77 gdp->queue = block->request_queue;
78 block->gdp = gdp; 78 block->gdp = gdp;
79 set_capacity(block->gdp, 0); 79 set_capacity(block->gdp, 0);
@@ -103,7 +103,7 @@ int dasd_scan_partitions(struct dasd_block *block)
103 struct block_device *bdev; 103 struct block_device *bdev;
104 104
105 bdev = bdget_disk(block->gdp, 0); 105 bdev = bdget_disk(block->gdp, 0);
106 if (!bdev || blkdev_get(bdev, FMODE_READ) < 0) 106 if (!bdev || blkdev_get(bdev, FMODE_READ, NULL) < 0)
107 return -ENODEV; 107 return -ENODEV;
108 /* 108 /*
109 * See fs/partition/check.c:register_disk,rescan_partitions 109 * See fs/partition/check.c:register_disk,rescan_partitions
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 500678d7116c..d1e4f2c1264c 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -231,6 +231,11 @@ struct dasd_ccw_req {
231/* per dasd_ccw_req flags */ 231/* per dasd_ccw_req flags */
232#define DASD_CQR_FLAGS_USE_ERP 0 /* use ERP for this request */ 232#define DASD_CQR_FLAGS_USE_ERP 0 /* use ERP for this request */
233#define DASD_CQR_FLAGS_FAILFAST 1 /* FAILFAST */ 233#define DASD_CQR_FLAGS_FAILFAST 1 /* FAILFAST */
234#define DASD_CQR_VERIFY_PATH 2 /* path verification request */
235#define DASD_CQR_ALLOW_SLOCK 3 /* Try this request even when lock was
236 * stolen. Should not be combined with
237 * DASD_CQR_FLAGS_USE_ERP
238 */
234 239
235/* Signature for error recovery functions. */ 240/* Signature for error recovery functions. */
236typedef struct dasd_ccw_req *(*dasd_erp_fn_t) (struct dasd_ccw_req *); 241typedef struct dasd_ccw_req *(*dasd_erp_fn_t) (struct dasd_ccw_req *);
@@ -287,6 +292,14 @@ struct dasd_discipline {
287 int (*do_analysis) (struct dasd_block *); 292 int (*do_analysis) (struct dasd_block *);
288 293
289 /* 294 /*
295 * This function is called, when new paths become available.
296 * Disciplins may use this callback to do necessary setup work,
297 * e.g. verify that new path is compatible with the current
298 * configuration.
299 */
300 int (*verify_path)(struct dasd_device *, __u8);
301
302 /*
290 * Last things to do when a device is set online, and first things 303 * Last things to do when a device is set online, and first things
291 * when it is set offline. 304 * when it is set offline.
292 */ 305 */
@@ -325,9 +338,9 @@ struct dasd_discipline {
325 void (*dump_sense) (struct dasd_device *, struct dasd_ccw_req *, 338 void (*dump_sense) (struct dasd_device *, struct dasd_ccw_req *,
326 struct irb *); 339 struct irb *);
327 void (*dump_sense_dbf) (struct dasd_device *, struct irb *, char *); 340 void (*dump_sense_dbf) (struct dasd_device *, struct irb *, char *);
328 341 void (*check_for_device_change) (struct dasd_device *,
329 void (*handle_unsolicited_interrupt) (struct dasd_device *, 342 struct dasd_ccw_req *,
330 struct irb *); 343 struct irb *);
331 344
332 /* i/o control functions. */ 345 /* i/o control functions. */
333 int (*fill_geometry) (struct dasd_block *, struct hd_geometry *); 346 int (*fill_geometry) (struct dasd_block *, struct hd_geometry *);
@@ -362,6 +375,13 @@ extern struct dasd_discipline *dasd_diag_discipline_pointer;
362#define DASD_EER_STATECHANGE 3 375#define DASD_EER_STATECHANGE 3
363#define DASD_EER_PPRCSUSPEND 4 376#define DASD_EER_PPRCSUSPEND 4
364 377
378struct dasd_path {
379 __u8 opm;
380 __u8 tbvpm;
381 __u8 ppm;
382 __u8 npm;
383};
384
365struct dasd_device { 385struct dasd_device {
366 /* Block device stuff. */ 386 /* Block device stuff. */
367 struct dasd_block *block; 387 struct dasd_block *block;
@@ -377,6 +397,7 @@ struct dasd_device {
377 struct dasd_discipline *discipline; 397 struct dasd_discipline *discipline;
378 struct dasd_discipline *base_discipline; 398 struct dasd_discipline *base_discipline;
379 char *private; 399 char *private;
400 struct dasd_path path_data;
380 401
381 /* Device state and target state. */ 402 /* Device state and target state. */
382 int state, target; 403 int state, target;
@@ -456,6 +477,9 @@ struct dasd_block {
456 * confuse this with the user specified 477 * confuse this with the user specified
457 * read-only feature. 478 * read-only feature.
458 */ 479 */
480#define DASD_FLAG_IS_RESERVED 7 /* The device is reserved */
481#define DASD_FLAG_LOCK_STOLEN 8 /* The device lock was stolen */
482
459 483
460void dasd_put_device_wake(struct dasd_device *); 484void dasd_put_device_wake(struct dasd_device *);
461 485
@@ -620,10 +644,15 @@ void dasd_generic_remove (struct ccw_device *cdev);
620int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *); 644int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *);
621int dasd_generic_set_offline (struct ccw_device *cdev); 645int dasd_generic_set_offline (struct ccw_device *cdev);
622int dasd_generic_notify(struct ccw_device *, int); 646int dasd_generic_notify(struct ccw_device *, int);
647int dasd_generic_last_path_gone(struct dasd_device *);
648int dasd_generic_path_operational(struct dasd_device *);
649
623void dasd_generic_handle_state_change(struct dasd_device *); 650void dasd_generic_handle_state_change(struct dasd_device *);
624int dasd_generic_pm_freeze(struct ccw_device *); 651int dasd_generic_pm_freeze(struct ccw_device *);
625int dasd_generic_restore_device(struct ccw_device *); 652int dasd_generic_restore_device(struct ccw_device *);
626enum uc_todo dasd_generic_uc_handler(struct ccw_device *, struct irb *); 653enum uc_todo dasd_generic_uc_handler(struct ccw_device *, struct irb *);
654void dasd_generic_path_event(struct ccw_device *, int *);
655int dasd_generic_verify_path(struct dasd_device *, __u8);
627 656
628int dasd_generic_read_dev_chars(struct dasd_device *, int, void *, int); 657int dasd_generic_read_dev_chars(struct dasd_device *, int, void *, int);
629char *dasd_get_sense(struct irb *); 658char *dasd_get_sense(struct irb *);
@@ -657,6 +686,9 @@ struct dasd_device *dasd_device_from_cdev(struct ccw_device *);
657struct dasd_device *dasd_device_from_cdev_locked(struct ccw_device *); 686struct dasd_device *dasd_device_from_cdev_locked(struct ccw_device *);
658struct dasd_device *dasd_device_from_devindex(int); 687struct dasd_device *dasd_device_from_devindex(int);
659 688
689void dasd_add_link_to_gendisk(struct gendisk *, struct dasd_device *);
690struct dasd_device *dasd_device_from_gendisk(struct gendisk *);
691
660int dasd_parse(void); 692int dasd_parse(void);
661int dasd_busid_known(const char *); 693int dasd_busid_known(const char *);
662 694
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index 1557214944f7..72261e4c516d 100644
--- a/drivers/s390/block/dasd_ioctl.c
+++ b/drivers/s390/block/dasd_ioctl.c
@@ -16,7 +16,6 @@
16#include <linux/major.h> 16#include <linux/major.h>
17#include <linux/fs.h> 17#include <linux/fs.h>
18#include <linux/blkpg.h> 18#include <linux/blkpg.h>
19#include <linux/smp_lock.h>
20#include <linux/slab.h> 19#include <linux/slab.h>
21#include <asm/compat.h> 20#include <asm/compat.h>
22#include <asm/ccwdev.h> 21#include <asm/ccwdev.h>
@@ -43,16 +42,22 @@ dasd_ioctl_api_version(void __user *argp)
43static int 42static int
44dasd_ioctl_enable(struct block_device *bdev) 43dasd_ioctl_enable(struct block_device *bdev)
45{ 44{
46 struct dasd_block *block = bdev->bd_disk->private_data; 45 struct dasd_device *base;
47 46
48 if (!capable(CAP_SYS_ADMIN)) 47 if (!capable(CAP_SYS_ADMIN))
49 return -EACCES; 48 return -EACCES;
50 49
51 dasd_enable_device(block->base); 50 base = dasd_device_from_gendisk(bdev->bd_disk);
51 if (!base)
52 return -ENODEV;
53
54 dasd_enable_device(base);
52 /* Formatting the dasd device can change the capacity. */ 55 /* Formatting the dasd device can change the capacity. */
53 mutex_lock(&bdev->bd_mutex); 56 mutex_lock(&bdev->bd_mutex);
54 i_size_write(bdev->bd_inode, (loff_t)get_capacity(block->gdp) << 9); 57 i_size_write(bdev->bd_inode,
58 (loff_t)get_capacity(base->block->gdp) << 9);
55 mutex_unlock(&bdev->bd_mutex); 59 mutex_unlock(&bdev->bd_mutex);
60 dasd_put_device(base);
56 return 0; 61 return 0;
57} 62}
58 63
@@ -63,11 +68,14 @@ dasd_ioctl_enable(struct block_device *bdev)
63static int 68static int
64dasd_ioctl_disable(struct block_device *bdev) 69dasd_ioctl_disable(struct block_device *bdev)
65{ 70{
66 struct dasd_block *block = bdev->bd_disk->private_data; 71 struct dasd_device *base;
67 72
68 if (!capable(CAP_SYS_ADMIN)) 73 if (!capable(CAP_SYS_ADMIN))
69 return -EACCES; 74 return -EACCES;
70 75
76 base = dasd_device_from_gendisk(bdev->bd_disk);
77 if (!base)
78 return -ENODEV;
71 /* 79 /*
72 * Man this is sick. We don't do a real disable but only downgrade 80 * Man this is sick. We don't do a real disable but only downgrade
73 * the device to DASD_STATE_BASIC. The reason is that dasdfmt uses 81 * the device to DASD_STATE_BASIC. The reason is that dasdfmt uses
@@ -76,7 +84,7 @@ dasd_ioctl_disable(struct block_device *bdev)
76 * using the BIODASDFMT ioctl. Therefore the correct state for the 84 * using the BIODASDFMT ioctl. Therefore the correct state for the
77 * device is DASD_STATE_BASIC that allows to do basic i/o. 85 * device is DASD_STATE_BASIC that allows to do basic i/o.
78 */ 86 */
79 dasd_set_target_state(block->base, DASD_STATE_BASIC); 87 dasd_set_target_state(base, DASD_STATE_BASIC);
80 /* 88 /*
81 * Set i_size to zero, since read, write, etc. check against this 89 * Set i_size to zero, since read, write, etc. check against this
82 * value. 90 * value.
@@ -84,6 +92,7 @@ dasd_ioctl_disable(struct block_device *bdev)
84 mutex_lock(&bdev->bd_mutex); 92 mutex_lock(&bdev->bd_mutex);
85 i_size_write(bdev->bd_inode, 0); 93 i_size_write(bdev->bd_inode, 0);
86 mutex_unlock(&bdev->bd_mutex); 94 mutex_unlock(&bdev->bd_mutex);
95 dasd_put_device(base);
87 return 0; 96 return 0;
88} 97}
89 98
@@ -192,26 +201,36 @@ static int dasd_format(struct dasd_block *block, struct format_data_t *fdata)
192static int 201static int
193dasd_ioctl_format(struct block_device *bdev, void __user *argp) 202dasd_ioctl_format(struct block_device *bdev, void __user *argp)
194{ 203{
195 struct dasd_block *block = bdev->bd_disk->private_data; 204 struct dasd_device *base;
196 struct format_data_t fdata; 205 struct format_data_t fdata;
206 int rc;
197 207
198 if (!capable(CAP_SYS_ADMIN)) 208 if (!capable(CAP_SYS_ADMIN))
199 return -EACCES; 209 return -EACCES;
200 if (!argp) 210 if (!argp)
201 return -EINVAL; 211 return -EINVAL;
202 212 base = dasd_device_from_gendisk(bdev->bd_disk);
203 if (block->base->features & DASD_FEATURE_READONLY || 213 if (!base)
204 test_bit(DASD_FLAG_DEVICE_RO, &block->base->flags)) 214 return -ENODEV;
215 if (base->features & DASD_FEATURE_READONLY ||
216 test_bit(DASD_FLAG_DEVICE_RO, &base->flags)) {
217 dasd_put_device(base);
205 return -EROFS; 218 return -EROFS;
206 if (copy_from_user(&fdata, argp, sizeof(struct format_data_t))) 219 }
220 if (copy_from_user(&fdata, argp, sizeof(struct format_data_t))) {
221 dasd_put_device(base);
207 return -EFAULT; 222 return -EFAULT;
223 }
208 if (bdev != bdev->bd_contains) { 224 if (bdev != bdev->bd_contains) {
209 pr_warning("%s: The specified DASD is a partition and cannot " 225 pr_warning("%s: The specified DASD is a partition and cannot "
210 "be formatted\n", 226 "be formatted\n",
211 dev_name(&block->base->cdev->dev)); 227 dev_name(&base->cdev->dev));
228 dasd_put_device(base);
212 return -EINVAL; 229 return -EINVAL;
213 } 230 }
214 return dasd_format(block, &fdata); 231 rc = dasd_format(base->block, &fdata);
232 dasd_put_device(base);
233 return rc;
215} 234}
216 235
217#ifdef CONFIG_DASD_PROFILE 236#ifdef CONFIG_DASD_PROFILE
@@ -341,8 +360,8 @@ static int dasd_ioctl_information(struct dasd_block *block,
341static int 360static int
342dasd_ioctl_set_ro(struct block_device *bdev, void __user *argp) 361dasd_ioctl_set_ro(struct block_device *bdev, void __user *argp)
343{ 362{
344 struct dasd_block *block = bdev->bd_disk->private_data; 363 struct dasd_device *base;
345 int intval; 364 int intval, rc;
346 365
347 if (!capable(CAP_SYS_ADMIN)) 366 if (!capable(CAP_SYS_ADMIN))
348 return -EACCES; 367 return -EACCES;
@@ -351,10 +370,17 @@ dasd_ioctl_set_ro(struct block_device *bdev, void __user *argp)
351 return -EINVAL; 370 return -EINVAL;
352 if (get_user(intval, (int __user *)argp)) 371 if (get_user(intval, (int __user *)argp))
353 return -EFAULT; 372 return -EFAULT;
354 if (!intval && test_bit(DASD_FLAG_DEVICE_RO, &block->base->flags)) 373 base = dasd_device_from_gendisk(bdev->bd_disk);
374 if (!base)
375 return -ENODEV;
376 if (!intval && test_bit(DASD_FLAG_DEVICE_RO, &base->flags)) {
377 dasd_put_device(base);
355 return -EROFS; 378 return -EROFS;
379 }
356 set_disk_ro(bdev->bd_disk, intval); 380 set_disk_ro(bdev->bd_disk, intval);
357 return dasd_set_feature(block->base->cdev, DASD_FEATURE_READONLY, intval); 381 rc = dasd_set_feature(base->cdev, DASD_FEATURE_READONLY, intval);
382 dasd_put_device(base);
383 return rc;
358} 384}
359 385
360static int dasd_ioctl_readall_cmb(struct dasd_block *block, unsigned int cmd, 386static int dasd_ioctl_readall_cmb(struct dasd_block *block, unsigned int cmd,
@@ -370,74 +396,81 @@ static int dasd_ioctl_readall_cmb(struct dasd_block *block, unsigned int cmd,
370 return ret; 396 return ret;
371} 397}
372 398
373static int 399int dasd_ioctl(struct block_device *bdev, fmode_t mode,
374dasd_do_ioctl(struct block_device *bdev, fmode_t mode, 400 unsigned int cmd, unsigned long arg)
375 unsigned int cmd, unsigned long arg)
376{ 401{
377 struct dasd_block *block = bdev->bd_disk->private_data; 402 struct dasd_block *block;
403 struct dasd_device *base;
378 void __user *argp; 404 void __user *argp;
405 int rc;
379 406
380 if (is_compat_task()) 407 if (is_compat_task())
381 argp = compat_ptr(arg); 408 argp = compat_ptr(arg);
382 else 409 else
383 argp = (void __user *)arg; 410 argp = (void __user *)arg;
384 411
385 if (!block)
386 return -ENODEV;
387
388 if ((_IOC_DIR(cmd) != _IOC_NONE) && !arg) { 412 if ((_IOC_DIR(cmd) != _IOC_NONE) && !arg) {
389 PRINT_DEBUG("empty data ptr"); 413 PRINT_DEBUG("empty data ptr");
390 return -EINVAL; 414 return -EINVAL;
391 } 415 }
392 416
417 base = dasd_device_from_gendisk(bdev->bd_disk);
418 if (!base)
419 return -ENODEV;
420 block = base->block;
421 rc = 0;
393 switch (cmd) { 422 switch (cmd) {
394 case BIODASDDISABLE: 423 case BIODASDDISABLE:
395 return dasd_ioctl_disable(bdev); 424 rc = dasd_ioctl_disable(bdev);
425 break;
396 case BIODASDENABLE: 426 case BIODASDENABLE:
397 return dasd_ioctl_enable(bdev); 427 rc = dasd_ioctl_enable(bdev);
428 break;
398 case BIODASDQUIESCE: 429 case BIODASDQUIESCE:
399 return dasd_ioctl_quiesce(block); 430 rc = dasd_ioctl_quiesce(block);
431 break;
400 case BIODASDRESUME: 432 case BIODASDRESUME:
401 return dasd_ioctl_resume(block); 433 rc = dasd_ioctl_resume(block);
434 break;
402 case BIODASDFMT: 435 case BIODASDFMT:
403 return dasd_ioctl_format(bdev, argp); 436 rc = dasd_ioctl_format(bdev, argp);
437 break;
404 case BIODASDINFO: 438 case BIODASDINFO:
405 return dasd_ioctl_information(block, cmd, argp); 439 rc = dasd_ioctl_information(block, cmd, argp);
440 break;
406 case BIODASDINFO2: 441 case BIODASDINFO2:
407 return dasd_ioctl_information(block, cmd, argp); 442 rc = dasd_ioctl_information(block, cmd, argp);
443 break;
408 case BIODASDPRRD: 444 case BIODASDPRRD:
409 return dasd_ioctl_read_profile(block, argp); 445 rc = dasd_ioctl_read_profile(block, argp);
446 break;
410 case BIODASDPRRST: 447 case BIODASDPRRST:
411 return dasd_ioctl_reset_profile(block); 448 rc = dasd_ioctl_reset_profile(block);
449 break;
412 case BLKROSET: 450 case BLKROSET:
413 return dasd_ioctl_set_ro(bdev, argp); 451 rc = dasd_ioctl_set_ro(bdev, argp);
452 break;
414 case DASDAPIVER: 453 case DASDAPIVER:
415 return dasd_ioctl_api_version(argp); 454 rc = dasd_ioctl_api_version(argp);
455 break;
416 case BIODASDCMFENABLE: 456 case BIODASDCMFENABLE:
417 return enable_cmf(block->base->cdev); 457 rc = enable_cmf(base->cdev);
458 break;
418 case BIODASDCMFDISABLE: 459 case BIODASDCMFDISABLE:
419 return disable_cmf(block->base->cdev); 460 rc = disable_cmf(base->cdev);
461 break;
420 case BIODASDREADALLCMB: 462 case BIODASDREADALLCMB:
421 return dasd_ioctl_readall_cmb(block, cmd, argp); 463 rc = dasd_ioctl_readall_cmb(block, cmd, argp);
464 break;
422 default: 465 default:
423 /* if the discipline has an ioctl method try it. */ 466 /* if the discipline has an ioctl method try it. */
424 if (block->base->discipline->ioctl) { 467 if (base->discipline->ioctl) {
425 int rval = block->base->discipline->ioctl(block, cmd, argp); 468 rc = base->discipline->ioctl(block, cmd, argp);
426 if (rval != -ENOIOCTLCMD) 469 if (rc == -ENOIOCTLCMD)
427 return rval; 470 rc = -EINVAL;
428 } 471 } else
429 472 rc = -EINVAL;
430 return -EINVAL;
431 } 473 }
432} 474 dasd_put_device(base);
433
434int dasd_ioctl(struct block_device *bdev, fmode_t mode,
435 unsigned int cmd, unsigned long arg)
436{
437 int rc;
438
439 lock_kernel();
440 rc = dasd_do_ioctl(bdev, mode, cmd, arg);
441 unlock_kernel();
442 return rc; 475 return rc;
443} 476}
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
index 2eb025592809..c4a6a31bd9cd 100644
--- a/drivers/s390/block/dasd_proc.c
+++ b/drivers/s390/block/dasd_proc.c
@@ -251,7 +251,6 @@ static ssize_t dasd_stats_proc_write(struct file *file,
251 buffer = dasd_get_user_string(user_buf, user_len); 251 buffer = dasd_get_user_string(user_buf, user_len);
252 if (IS_ERR(buffer)) 252 if (IS_ERR(buffer))
253 return PTR_ERR(buffer); 253 return PTR_ERR(buffer);
254 DBF_EVENT(DBF_DEBUG, "/proc/dasd/statictics: '%s'\n", buffer);
255 254
256 /* check for valid verbs */ 255 /* check for valid verbs */
257 str = skip_spaces(buffer); 256 str = skip_spaces(buffer);
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index 2bd72aa34c59..9b43ae94beba 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -14,7 +14,6 @@
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/blkdev.h> 16#include <linux/blkdev.h>
17#include <linux/smp_lock.h>
18#include <linux/completion.h> 17#include <linux/completion.h>
19#include <linux/interrupt.h> 18#include <linux/interrupt.h>
20#include <linux/platform_device.h> 19#include <linux/platform_device.h>
@@ -776,7 +775,6 @@ dcssblk_open(struct block_device *bdev, fmode_t mode)
776 struct dcssblk_dev_info *dev_info; 775 struct dcssblk_dev_info *dev_info;
777 int rc; 776 int rc;
778 777
779 lock_kernel();
780 dev_info = bdev->bd_disk->private_data; 778 dev_info = bdev->bd_disk->private_data;
781 if (NULL == dev_info) { 779 if (NULL == dev_info) {
782 rc = -ENODEV; 780 rc = -ENODEV;
@@ -786,7 +784,6 @@ dcssblk_open(struct block_device *bdev, fmode_t mode)
786 bdev->bd_block_size = 4096; 784 bdev->bd_block_size = 4096;
787 rc = 0; 785 rc = 0;
788out: 786out:
789 unlock_kernel();
790 return rc; 787 return rc;
791} 788}
792 789
@@ -797,7 +794,6 @@ dcssblk_release(struct gendisk *disk, fmode_t mode)
797 struct segment_info *entry; 794 struct segment_info *entry;
798 int rc; 795 int rc;
799 796
800 lock_kernel();
801 if (!dev_info) { 797 if (!dev_info) {
802 rc = -ENODEV; 798 rc = -ENODEV;
803 goto out; 799 goto out;
@@ -815,7 +811,6 @@ dcssblk_release(struct gendisk *disk, fmode_t mode)
815 up_write(&dcssblk_devices_sem); 811 up_write(&dcssblk_devices_sem);
816 rc = 0; 812 rc = 0;
817out: 813out:
818 unlock_kernel();
819 return rc; 814 return rc;
820} 815}
821 816
diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c
index c881a14fa5dd..1f6a4d894e73 100644
--- a/drivers/s390/block/xpram.c
+++ b/drivers/s390/block/xpram.c
@@ -62,8 +62,8 @@ static int xpram_devs;
62/* 62/*
63 * Parameter parsing functions. 63 * Parameter parsing functions.
64 */ 64 */
65static int __initdata devs = XPRAM_DEVS; 65static int devs = XPRAM_DEVS;
66static char __initdata *sizes[XPRAM_MAX_DEVS]; 66static char *sizes[XPRAM_MAX_DEVS];
67 67
68module_param(devs, int, 0); 68module_param(devs, int, 0);
69module_param_array(sizes, charp, NULL, 0); 69module_param_array(sizes, charp, NULL, 0);