aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block
diff options
context:
space:
mode:
authorStefan Weinhuber <wein@de.ibm.com>2009-03-26 10:23:48 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2009-03-26 10:24:05 -0400
commitf3eb5384cf0325c02e306b1d81e70f81a03d7432 (patch)
tree4d75517ad2c61ac2f8b6431eafd62b5d32c188ed /drivers/s390/block
parentb44b0ab3bac16356f03e94b1b49ba9305710c445 (diff)
[S390] dasd: add High Performance FICON support
To support High Performance FICON, the DASD device driver has to translate I/O requests into the new transport mode control words (TCW) instead of the traditional (command mode) CCW requests. Signed-off-by: Stefan Weinhuber <wein@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/block')
-rw-r--r--drivers/s390/block/dasd.c70
-rw-r--r--drivers/s390/block/dasd_3990_erp.c141
-rw-r--r--drivers/s390/block/dasd_alias.c25
-rw-r--r--drivers/s390/block/dasd_devmap.c7
-rw-r--r--drivers/s390/block/dasd_eckd.c972
-rw-r--r--drivers/s390/block/dasd_eckd.h40
-rw-r--r--drivers/s390/block/dasd_eer.c21
-rw-r--r--drivers/s390/block/dasd_int.h5
8 files changed, 1118 insertions, 163 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 93972ed7f2df..00f7d24b337a 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -22,6 +22,7 @@
22#include <asm/ebcdic.h> 22#include <asm/ebcdic.h>
23#include <asm/idals.h> 23#include <asm/idals.h>
24#include <asm/todclk.h> 24#include <asm/todclk.h>
25#include <asm/itcw.h>
25 26
26/* This is ugly... */ 27/* This is ugly... */
27#define PRINTK_HEADER "dasd:" 28#define PRINTK_HEADER "dasd:"
@@ -852,8 +853,13 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
852 cqr->startclk = get_clock(); 853 cqr->startclk = get_clock();
853 cqr->starttime = jiffies; 854 cqr->starttime = jiffies;
854 cqr->retries--; 855 cqr->retries--;
855 rc = ccw_device_start(device->cdev, cqr->cpaddr, (long) cqr, 856 if (cqr->cpmode == 1) {
856 cqr->lpm, 0); 857 rc = ccw_device_tm_start(device->cdev, cqr->cpaddr,
858 (long) cqr, cqr->lpm);
859 } else {
860 rc = ccw_device_start(device->cdev, cqr->cpaddr,
861 (long) cqr, cqr->lpm, 0);
862 }
857 switch (rc) { 863 switch (rc) {
858 case 0: 864 case 0:
859 cqr->status = DASD_CQR_IN_IO; 865 cqr->status = DASD_CQR_IN_IO;
@@ -881,9 +887,12 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
881 " retry on all pathes"); 887 " retry on all pathes");
882 break; 888 break;
883 case -ENODEV: 889 case -ENODEV:
890 DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
891 "start_IO: -ENODEV device gone, retry");
892 break;
884 case -EIO: 893 case -EIO:
885 DBF_DEV_EVENT(DBF_ERR, device, "%s", 894 DBF_DEV_EVENT(DBF_ERR, device, "%s",
886 "start_IO: device gone, retry"); 895 "start_IO: -EIO device gone, retry");
887 break; 896 break;
888 default: 897 default:
889 DEV_MESSAGE(KERN_ERR, device, 898 DEV_MESSAGE(KERN_ERR, device,
@@ -1015,9 +1024,9 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
1015 1024
1016 /* check for unsolicited interrupts */ 1025 /* check for unsolicited interrupts */
1017 cqr = (struct dasd_ccw_req *) intparm; 1026 cqr = (struct dasd_ccw_req *) intparm;
1018 if (!cqr || ((irb->scsw.cmd.cc == 1) && 1027 if (!cqr || ((scsw_cc(&irb->scsw) == 1) &&
1019 (irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC) && 1028 (scsw_fctl(&irb->scsw) & SCSW_FCTL_START_FUNC) &&
1020 (irb->scsw.cmd.stctl & SCSW_STCTL_STATUS_PEND))) { 1029 (scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND))) {
1021 if (cqr && cqr->status == DASD_CQR_IN_IO) 1030 if (cqr && cqr->status == DASD_CQR_IN_IO)
1022 cqr->status = DASD_CQR_QUEUED; 1031 cqr->status = DASD_CQR_QUEUED;
1023 device = dasd_device_from_cdev_locked(cdev); 1032 device = dasd_device_from_cdev_locked(cdev);
@@ -1040,7 +1049,7 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
1040 1049
1041 /* Check for clear pending */ 1050 /* Check for clear pending */
1042 if (cqr->status == DASD_CQR_CLEAR_PENDING && 1051 if (cqr->status == DASD_CQR_CLEAR_PENDING &&
1043 irb->scsw.cmd.fctl & SCSW_FCTL_CLEAR_FUNC) { 1052 scsw_fctl(&irb->scsw) & SCSW_FCTL_CLEAR_FUNC) {
1044 cqr->status = DASD_CQR_CLEARED; 1053 cqr->status = DASD_CQR_CLEARED;
1045 dasd_device_clear_timer(device); 1054 dasd_device_clear_timer(device);
1046 wake_up(&dasd_flush_wq); 1055 wake_up(&dasd_flush_wq);
@@ -1048,7 +1057,7 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
1048 return; 1057 return;
1049 } 1058 }
1050 1059
1051 /* check status - the request might have been killed by dyn detach */ 1060 /* check status - the request might have been killed by dyn detach */
1052 if (cqr->status != DASD_CQR_IN_IO) { 1061 if (cqr->status != DASD_CQR_IN_IO) {
1053 MESSAGE(KERN_DEBUG, 1062 MESSAGE(KERN_DEBUG,
1054 "invalid status: bus_id %s, status %02x", 1063 "invalid status: bus_id %s, status %02x",
@@ -1059,8 +1068,8 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
1059 ((irb->scsw.cmd.cstat << 8) | irb->scsw.cmd.dstat), cqr); 1068 ((irb->scsw.cmd.cstat << 8) | irb->scsw.cmd.dstat), cqr);
1060 next = NULL; 1069 next = NULL;
1061 expires = 0; 1070 expires = 0;
1062 if (irb->scsw.cmd.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) && 1071 if (scsw_dstat(&irb->scsw) == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) &&
1063 irb->scsw.cmd.cstat == 0 && !irb->esw.esw0.erw.cons) { 1072 scsw_cstat(&irb->scsw) == 0) {
1064 /* request was completed successfully */ 1073 /* request was completed successfully */
1065 cqr->status = DASD_CQR_SUCCESS; 1074 cqr->status = DASD_CQR_SUCCESS;
1066 cqr->stopclk = now; 1075 cqr->stopclk = now;
@@ -1991,8 +2000,11 @@ static void dasd_setup_queue(struct dasd_block *block)
1991 blk_queue_max_sectors(block->request_queue, max); 2000 blk_queue_max_sectors(block->request_queue, max);
1992 blk_queue_max_phys_segments(block->request_queue, -1L); 2001 blk_queue_max_phys_segments(block->request_queue, -1L);
1993 blk_queue_max_hw_segments(block->request_queue, -1L); 2002 blk_queue_max_hw_segments(block->request_queue, -1L);
1994 blk_queue_max_segment_size(block->request_queue, -1L); 2003 /* with page sized segments we can translate each segement into
1995 blk_queue_segment_boundary(block->request_queue, -1L); 2004 * one idaw/tidaw
2005 */
2006 blk_queue_max_segment_size(block->request_queue, PAGE_SIZE);
2007 blk_queue_segment_boundary(block->request_queue, PAGE_SIZE - 1);
1996 blk_queue_ordered(block->request_queue, QUEUE_ORDERED_DRAIN, NULL); 2008 blk_queue_ordered(block->request_queue, QUEUE_ORDERED_DRAIN, NULL);
1997} 2009}
1998 2010
@@ -2432,6 +2444,40 @@ int dasd_generic_read_dev_chars(struct dasd_device *device, char *magic,
2432} 2444}
2433EXPORT_SYMBOL_GPL(dasd_generic_read_dev_chars); 2445EXPORT_SYMBOL_GPL(dasd_generic_read_dev_chars);
2434 2446
2447/*
2448 * In command mode and transport mode we need to look for sense
2449 * data in different places. The sense data itself is allways
2450 * an array of 32 bytes, so we can unify the sense data access
2451 * for both modes.
2452 */
2453char *dasd_get_sense(struct irb *irb)
2454{
2455 struct tsb *tsb = NULL;
2456 char *sense = NULL;
2457
2458 if (scsw_is_tm(&irb->scsw) && (irb->scsw.tm.fcxs == 0x01)) {
2459 if (irb->scsw.tm.tcw)
2460 tsb = tcw_get_tsb((struct tcw *)(unsigned long)
2461 irb->scsw.tm.tcw);
2462 if (tsb && tsb->length == 64 && tsb->flags)
2463 switch (tsb->flags & 0x07) {
2464 case 1: /* tsa_iostat */
2465 sense = tsb->tsa.iostat.sense;
2466 break;
2467 case 2: /* tsa_ddpc */
2468 sense = tsb->tsa.ddpc.sense;
2469 break;
2470 default:
2471 /* currently we don't use interrogate data */
2472 break;
2473 }
2474 } else if (irb->esw.esw0.erw.cons) {
2475 sense = irb->ecw;
2476 }
2477 return sense;
2478}
2479EXPORT_SYMBOL_GPL(dasd_get_sense);
2480
2435static int __init dasd_init(void) 2481static int __init dasd_init(void)
2436{ 2482{
2437 int rc; 2483 int rc;
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
index d82aad5224f0..4cee45916144 100644
--- a/drivers/s390/block/dasd_3990_erp.c
+++ b/drivers/s390/block/dasd_3990_erp.c
@@ -1561,6 +1561,13 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
1561 cqr = cqr->refers; 1561 cqr = cqr->refers;
1562 } 1562 }
1563 1563
1564 if (scsw_is_tm(&cqr->irb.scsw)) {
1565 DBF_DEV_EVENT(DBF_WARNING, device, "%s",
1566 "32 bit sense, action 1B is not defined"
1567 " in transport mode - just retry");
1568 return default_erp;
1569 }
1570
1564 /* for imprecise ending just do default erp */ 1571 /* for imprecise ending just do default erp */
1565 if (sense[1] & 0x01) { 1572 if (sense[1] & 0x01) {
1566 1573
@@ -1599,7 +1606,7 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense)
1599 oldccw = cqr->cpaddr; 1606 oldccw = cqr->cpaddr;
1600 if (oldccw->cmd_code == DASD_ECKD_CCW_PFX) { 1607 if (oldccw->cmd_code == DASD_ECKD_CCW_PFX) {
1601 PFX_data = cqr->data; 1608 PFX_data = cqr->data;
1602 memcpy(DE_data, &PFX_data->define_extend, 1609 memcpy(DE_data, &PFX_data->define_extent,
1603 sizeof(struct DE_eckd_data)); 1610 sizeof(struct DE_eckd_data));
1604 } else 1611 } else
1605 memcpy(DE_data, cqr->data, sizeof(struct DE_eckd_data)); 1612 memcpy(DE_data, cqr->data, sizeof(struct DE_eckd_data));
@@ -1712,6 +1719,13 @@ dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense)
1712 cqr = cqr->refers; 1719 cqr = cqr->refers;
1713 } 1720 }
1714 1721
1722 if (scsw_is_tm(&cqr->irb.scsw)) {
1723 DBF_DEV_EVENT(DBF_WARNING, device, "%s",
1724 "32 bit sense, action 1B, update,"
1725 " in transport mode - just retry");
1726 return previous_erp;
1727 }
1728
1715 /* for imprecise ending just do default erp */ 1729 /* for imprecise ending just do default erp */
1716 if (sense[1] & 0x01) { 1730 if (sense[1] & 0x01) {
1717 1731
@@ -2171,7 +2185,7 @@ dasd_3990_erp_control_check(struct dasd_ccw_req *erp)
2171{ 2185{
2172 struct dasd_device *device = erp->startdev; 2186 struct dasd_device *device = erp->startdev;
2173 2187
2174 if (erp->refers->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK 2188 if (scsw_cstat(&erp->refers->irb.scsw) & (SCHN_STAT_INTF_CTRL_CHK
2175 | SCHN_STAT_CHN_CTRL_CHK)) { 2189 | SCHN_STAT_CHN_CTRL_CHK)) {
2176 DEV_MESSAGE(KERN_DEBUG, device, "%s", 2190 DEV_MESSAGE(KERN_DEBUG, device, "%s",
2177 "channel or interface control check"); 2191 "channel or interface control check");
@@ -2193,21 +2207,23 @@ dasd_3990_erp_control_check(struct dasd_ccw_req *erp)
2193 * erp_new contens was possibly modified 2207 * erp_new contens was possibly modified
2194 */ 2208 */
2195static struct dasd_ccw_req * 2209static struct dasd_ccw_req *
2196dasd_3990_erp_inspect(struct dasd_ccw_req * erp) 2210dasd_3990_erp_inspect(struct dasd_ccw_req *erp)
2197{ 2211{
2198 2212
2199 struct dasd_ccw_req *erp_new = NULL; 2213 struct dasd_ccw_req *erp_new = NULL;
2200 /* sense data are located in the refers record of the */ 2214 char *sense;
2201 /* already set up new ERP ! */
2202 char *sense = erp->refers->irb.ecw;
2203 2215
2204 /* if this problem occured on an alias retry on base */ 2216 /* if this problem occured on an alias retry on base */
2205 erp_new = dasd_3990_erp_inspect_alias(erp); 2217 erp_new = dasd_3990_erp_inspect_alias(erp);
2206 if (erp_new) 2218 if (erp_new)
2207 return erp_new; 2219 return erp_new;
2208 2220
2209 /* check if no concurrent sens is available */ 2221 /* sense data are located in the refers record of the
2210 if (!erp->refers->irb.esw.esw0.erw.cons) 2222 * already set up new ERP !
2223 * check if concurrent sens is available
2224 */
2225 sense = dasd_get_sense(&erp->refers->irb);
2226 if (!sense)
2211 erp_new = dasd_3990_erp_control_check(erp); 2227 erp_new = dasd_3990_erp_control_check(erp);
2212 /* distinguish between 24 and 32 byte sense data */ 2228 /* distinguish between 24 and 32 byte sense data */
2213 else if (sense[27] & DASD_SENSE_BIT_0) { 2229 else if (sense[27] & DASD_SENSE_BIT_0) {
@@ -2231,7 +2247,11 @@ dasd_3990_erp_inspect(struct dasd_ccw_req * erp)
2231 * DESCRIPTION 2247 * DESCRIPTION
2232 * This funtion adds an additional request block (ERP) to the head of 2248 * This funtion adds an additional request block (ERP) to the head of
2233 * the given cqr (or erp). 2249 * the given cqr (or erp).
2234 * This erp is initialized as an default erp (retry TIC) 2250 * For a command mode cqr the erp is initialized as an default erp
2251 * (retry TIC).
2252 * For transport mode we make a copy of the original TCW (points to
2253 * the original TCCB, TIDALs, etc.) but give it a fresh
2254 * TSB so the original sense data will not be changed.
2235 * 2255 *
2236 * PARAMETER 2256 * PARAMETER
2237 * cqr head of the current ERP-chain (or single cqr if 2257 * cqr head of the current ERP-chain (or single cqr if
@@ -2239,17 +2259,27 @@ dasd_3990_erp_inspect(struct dasd_ccw_req * erp)
2239 * RETURN VALUES 2259 * RETURN VALUES
2240 * erp pointer to new ERP-chain head 2260 * erp pointer to new ERP-chain head
2241 */ 2261 */
2242static struct dasd_ccw_req * 2262static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req *cqr)
2243dasd_3990_erp_add_erp(struct dasd_ccw_req * cqr)
2244{ 2263{
2245 2264
2246 struct dasd_device *device = cqr->startdev; 2265 struct dasd_device *device = cqr->startdev;
2247 struct ccw1 *ccw; 2266 struct ccw1 *ccw;
2248
2249 /* allocate additional request block */
2250 struct dasd_ccw_req *erp; 2267 struct dasd_ccw_req *erp;
2268 int cplength, datasize;
2269 struct tcw *tcw;
2270 struct tsb *tsb;
2271
2272 if (cqr->cpmode == 1) {
2273 cplength = 0;
2274 datasize = sizeof(struct tcw) + sizeof(struct tsb);
2275 } else {
2276 cplength = 2;
2277 datasize = 0;
2278 }
2251 2279
2252 erp = dasd_alloc_erp_request((char *) &cqr->magic, 2, 0, device); 2280 /* allocate additional request block */
2281 erp = dasd_alloc_erp_request((char *) &cqr->magic,
2282 cplength, datasize, device);
2253 if (IS_ERR(erp)) { 2283 if (IS_ERR(erp)) {
2254 if (cqr->retries <= 0) { 2284 if (cqr->retries <= 0) {
2255 DEV_MESSAGE(KERN_ERR, device, "%s", 2285 DEV_MESSAGE(KERN_ERR, device, "%s",
@@ -2266,13 +2296,24 @@ dasd_3990_erp_add_erp(struct dasd_ccw_req * cqr)
2266 return cqr; 2296 return cqr;
2267 } 2297 }
2268 2298
2269 /* initialize request with default TIC to current ERP/CQR */ 2299 if (cqr->cpmode == 1) {
2270 ccw = erp->cpaddr; 2300 /* make a shallow copy of the original tcw but set new tsb */
2271 ccw->cmd_code = CCW_CMD_NOOP; 2301 erp->cpmode = 1;
2272 ccw->flags = CCW_FLAG_CC; 2302 erp->cpaddr = erp->data;
2273 ccw++; 2303 tcw = erp->data;
2274 ccw->cmd_code = CCW_CMD_TIC; 2304 tsb = (struct tsb *) &tcw[1];
2275 ccw->cda = (long)(cqr->cpaddr); 2305 *tcw = *((struct tcw *)cqr->cpaddr);
2306 tcw->tsb = (long)tsb;
2307 } else {
2308 /* initialize request with default TIC to current ERP/CQR */
2309 ccw = erp->cpaddr;
2310 ccw->cmd_code = CCW_CMD_NOOP;
2311 ccw->flags = CCW_FLAG_CC;
2312 ccw++;
2313 ccw->cmd_code = CCW_CMD_TIC;
2314 ccw->cda = (long)(cqr->cpaddr);
2315 }
2316
2276 erp->function = dasd_3990_erp_add_erp; 2317 erp->function = dasd_3990_erp_add_erp;
2277 erp->refers = cqr; 2318 erp->refers = cqr;
2278 erp->startdev = device; 2319 erp->startdev = device;
@@ -2282,7 +2323,6 @@ dasd_3990_erp_add_erp(struct dasd_ccw_req * cqr)
2282 erp->expires = 0; 2323 erp->expires = 0;
2283 erp->retries = 256; 2324 erp->retries = 256;
2284 erp->buildclk = get_clock(); 2325 erp->buildclk = get_clock();
2285
2286 erp->status = DASD_CQR_FILLED; 2326 erp->status = DASD_CQR_FILLED;
2287 2327
2288 return erp; 2328 return erp;
@@ -2340,28 +2380,33 @@ dasd_3990_erp_additional_erp(struct dasd_ccw_req * cqr)
2340 * match 'boolean' for match found 2380 * match 'boolean' for match found
2341 * returns 1 if match found, otherwise 0. 2381 * returns 1 if match found, otherwise 0.
2342 */ 2382 */
2343static int 2383static int dasd_3990_erp_error_match(struct dasd_ccw_req *cqr1,
2344dasd_3990_erp_error_match(struct dasd_ccw_req *cqr1, struct dasd_ccw_req *cqr2) 2384 struct dasd_ccw_req *cqr2)
2345{ 2385{
2386 char *sense1, *sense2;
2346 2387
2347 if (cqr1->startdev != cqr2->startdev) 2388 if (cqr1->startdev != cqr2->startdev)
2348 return 0; 2389 return 0;
2349 2390
2350 if (cqr1->irb.esw.esw0.erw.cons != cqr2->irb.esw.esw0.erw.cons) 2391 sense1 = dasd_get_sense(&cqr1->irb);
2351 return 0; 2392 sense2 = dasd_get_sense(&cqr2->irb);
2352 2393
2353 if ((cqr1->irb.esw.esw0.erw.cons == 0) && 2394 /* one request has sense data, the other not -> no match, return 0 */
2354 (cqr2->irb.esw.esw0.erw.cons == 0)) { 2395 if (!sense1 != !sense2)
2355 if ((cqr1->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK | 2396 return 0;
2356 SCHN_STAT_CHN_CTRL_CHK)) == 2397 /* no sense data in both cases -> check cstat for IFCC */
2357 (cqr2->irb.scsw.cmd.cstat & (SCHN_STAT_INTF_CTRL_CHK | 2398 if (!sense1 && !sense2) {
2358 SCHN_STAT_CHN_CTRL_CHK))) 2399 if ((scsw_cstat(&cqr1->irb.scsw) & (SCHN_STAT_INTF_CTRL_CHK |
2400 SCHN_STAT_CHN_CTRL_CHK)) ==
2401 (scsw_cstat(&cqr2->irb.scsw) & (SCHN_STAT_INTF_CTRL_CHK |
2402 SCHN_STAT_CHN_CTRL_CHK)))
2359 return 1; /* match with ifcc*/ 2403 return 1; /* match with ifcc*/
2360 } 2404 }
2361 /* check sense data; byte 0-2,25,27 */ 2405 /* check sense data; byte 0-2,25,27 */
2362 if (!((memcmp (cqr1->irb.ecw, cqr2->irb.ecw, 3) == 0) && 2406 if (!(sense1 && sense2 &&
2363 (cqr1->irb.ecw[27] == cqr2->irb.ecw[27]) && 2407 (memcmp(sense1, sense2, 3) == 0) &&
2364 (cqr1->irb.ecw[25] == cqr2->irb.ecw[25]))) { 2408 (sense1[27] == sense2[27]) &&
2409 (sense1[25] == sense2[25]))) {
2365 2410
2366 return 0; /* sense doesn't match */ 2411 return 0; /* sense doesn't match */
2367 } 2412 }
@@ -2434,7 +2479,7 @@ dasd_3990_erp_further_erp(struct dasd_ccw_req *erp)
2434{ 2479{
2435 2480
2436 struct dasd_device *device = erp->startdev; 2481 struct dasd_device *device = erp->startdev;
2437 char *sense = erp->irb.ecw; 2482 char *sense = dasd_get_sense(&erp->irb);
2438 2483
2439 /* check for 24 byte sense ERP */ 2484 /* check for 24 byte sense ERP */
2440 if ((erp->function == dasd_3990_erp_bus_out) || 2485 if ((erp->function == dasd_3990_erp_bus_out) ||
@@ -2449,7 +2494,7 @@ dasd_3990_erp_further_erp(struct dasd_ccw_req *erp)
2449 /* prepare erp for retry on different channel path */ 2494 /* prepare erp for retry on different channel path */
2450 erp = dasd_3990_erp_action_1(erp); 2495 erp = dasd_3990_erp_action_1(erp);
2451 2496
2452 if (!(sense[2] & DASD_SENSE_BIT_0)) { 2497 if (sense && !(sense[2] & DASD_SENSE_BIT_0)) {
2453 2498
2454 /* issue a Diagnostic Control command with an 2499 /* issue a Diagnostic Control command with an
2455 * Inhibit Write subcommand */ 2500 * Inhibit Write subcommand */
@@ -2479,10 +2524,11 @@ dasd_3990_erp_further_erp(struct dasd_ccw_req *erp)
2479 } 2524 }
2480 2525
2481 /* check for 32 byte sense ERP */ 2526 /* check for 32 byte sense ERP */
2482 } else if ((erp->function == dasd_3990_erp_compound_retry) || 2527 } else if (sense &&
2483 (erp->function == dasd_3990_erp_compound_path) || 2528 ((erp->function == dasd_3990_erp_compound_retry) ||
2484 (erp->function == dasd_3990_erp_compound_code) || 2529 (erp->function == dasd_3990_erp_compound_path) ||
2485 (erp->function == dasd_3990_erp_compound_config)) { 2530 (erp->function == dasd_3990_erp_compound_code) ||
2531 (erp->function == dasd_3990_erp_compound_config))) {
2486 2532
2487 erp = dasd_3990_erp_compound(erp, sense); 2533 erp = dasd_3990_erp_compound(erp, sense);
2488 2534
@@ -2548,18 +2594,19 @@ dasd_3990_erp_handle_match_erp(struct dasd_ccw_req *erp_head,
2548 2594
2549 if (erp->retries > 0) { 2595 if (erp->retries > 0) {
2550 2596
2551 char *sense = erp->refers->irb.ecw; 2597 char *sense = dasd_get_sense(&erp->refers->irb);
2552 2598
2553 /* check for special retries */ 2599 /* check for special retries */
2554 if (erp->function == dasd_3990_erp_action_4) { 2600 if (sense && erp->function == dasd_3990_erp_action_4) {
2555 2601
2556 erp = dasd_3990_erp_action_4(erp, sense); 2602 erp = dasd_3990_erp_action_4(erp, sense);
2557 2603
2558 } else if (erp->function == dasd_3990_erp_action_1B_32) { 2604 } else if (sense &&
2605 erp->function == dasd_3990_erp_action_1B_32) {
2559 2606
2560 erp = dasd_3990_update_1B(erp, sense); 2607 erp = dasd_3990_update_1B(erp, sense);
2561 2608
2562 } else if (erp->function == dasd_3990_erp_int_req) { 2609 } else if (sense && erp->function == dasd_3990_erp_int_req) {
2563 2610
2564 erp = dasd_3990_erp_int_req(erp); 2611 erp = dasd_3990_erp_int_req(erp);
2565 2612
@@ -2622,8 +2669,8 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr)
2622 } 2669 }
2623 2670
2624 /* double-check if current erp/cqr was successful */ 2671 /* double-check if current erp/cqr was successful */
2625 if ((cqr->irb.scsw.cmd.cstat == 0x00) && 2672 if ((scsw_cstat(&cqr->irb.scsw) == 0x00) &&
2626 (cqr->irb.scsw.cmd.dstat == 2673 (scsw_dstat(&cqr->irb.scsw) ==
2627 (DEV_STAT_CHN_END | DEV_STAT_DEV_END))) { 2674 (DEV_STAT_CHN_END | DEV_STAT_DEV_END))) {
2628 2675
2629 DEV_MESSAGE(KERN_DEBUG, device, 2676 DEV_MESSAGE(KERN_DEBUG, device,
diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c
index 20676cdef4a5..219bee7bd77c 100644
--- a/drivers/s390/block/dasd_alias.c
+++ b/drivers/s390/block/dasd_alias.c
@@ -646,14 +646,16 @@ static int reset_summary_unit_check(struct alias_lcu *lcu,
646{ 646{
647 struct dasd_ccw_req *cqr; 647 struct dasd_ccw_req *cqr;
648 int rc = 0; 648 int rc = 0;
649 struct ccw1 *ccw;
649 650
650 cqr = lcu->rsu_cqr; 651 cqr = lcu->rsu_cqr;
651 strncpy((char *) &cqr->magic, "ECKD", 4); 652 strncpy((char *) &cqr->magic, "ECKD", 4);
652 ASCEBC((char *) &cqr->magic, 4); 653 ASCEBC((char *) &cqr->magic, 4);
653 cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RSCK; 654 ccw = cqr->cpaddr;
654 cqr->cpaddr->flags = 0 ; 655 ccw->cmd_code = DASD_ECKD_CCW_RSCK;
655 cqr->cpaddr->count = 16; 656 ccw->flags = 0 ;
656 cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; 657 ccw->count = 16;
658 ccw->cda = (__u32)(addr_t) cqr->data;
657 ((char *)cqr->data)[0] = reason; 659 ((char *)cqr->data)[0] = reason;
658 660
659 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); 661 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
@@ -855,12 +857,21 @@ void dasd_alias_handle_summary_unit_check(struct dasd_device *device,
855 struct alias_lcu *lcu; 857 struct alias_lcu *lcu;
856 char reason; 858 char reason;
857 struct dasd_eckd_private *private; 859 struct dasd_eckd_private *private;
860 char *sense;
858 861
859 private = (struct dasd_eckd_private *) device->private; 862 private = (struct dasd_eckd_private *) device->private;
860 863
861 reason = irb->ecw[8]; 864 sense = dasd_get_sense(irb);
862 DEV_MESSAGE(KERN_WARNING, device, "%s %x", 865 if (sense) {
863 "eckd handle summary unit check: reason", reason); 866 reason = sense[8];
867 DBF_DEV_EVENT(DBF_NOTICE, device, "%s %x",
868 "eckd handle summary unit check: reason", reason);
869 } else {
870 DBF_DEV_EVENT(DBF_WARNING, device, "%s",
871 "eckd handle summary unit check:"
872 " no reason code available");
873 return;
874 }
864 875
865 lcu = private->lcu; 876 lcu = private->lcu;
866 if (!lcu) { 877 if (!lcu) {
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index 34339902efb9..da231a787cee 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -67,6 +67,8 @@ int dasd_probeonly = 0; /* is true, when probeonly mode is active */
67int dasd_autodetect = 0; /* is true, when autodetection is active */ 67int dasd_autodetect = 0; /* is true, when autodetection is active */
68int dasd_nopav = 0; /* is true, when PAV is disabled */ 68int dasd_nopav = 0; /* is true, when PAV is disabled */
69EXPORT_SYMBOL_GPL(dasd_nopav); 69EXPORT_SYMBOL_GPL(dasd_nopav);
70int dasd_nofcx; /* disable High Performance Ficon */
71EXPORT_SYMBOL_GPL(dasd_nofcx);
70 72
71/* 73/*
72 * char *dasd[] is intended to hold the ranges supplied by the dasd= statement 74 * char *dasd[] is intended to hold the ranges supplied by the dasd= statement
@@ -272,6 +274,11 @@ dasd_parse_keyword( char *parsestring ) {
272 } 274 }
273 return residual_str; 275 return residual_str;
274 } 276 }
277 if (strncmp("nofcx", parsestring, length) == 0) {
278 dasd_nofcx = 1;
279 MESSAGE(KERN_INFO, "%s", "disable High Performance Ficon");
280 return residual_str;
281 }
275 if (strncmp("fixedbuffers", parsestring, length) == 0) { 282 if (strncmp("fixedbuffers", parsestring, length) == 0) {
276 if (dasd_page_cache) 283 if (dasd_page_cache)
277 return residual_str; 284 return residual_str;
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 69f93e626fd3..1e4c89b8b304 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -27,9 +27,12 @@
27#include <asm/uaccess.h> 27#include <asm/uaccess.h>
28#include <asm/cio.h> 28#include <asm/cio.h>
29#include <asm/ccwdev.h> 29#include <asm/ccwdev.h>
30#include <asm/itcw.h>
30 31
31#include "dasd_int.h" 32#include "dasd_int.h"
32#include "dasd_eckd.h" 33#include "dasd_eckd.h"
34#include "../cio/chsc.h"
35
33 36
34#ifdef PRINTK_HEADER 37#ifdef PRINTK_HEADER
35#undef PRINTK_HEADER 38#undef PRINTK_HEADER
@@ -245,7 +248,8 @@ define_extent(struct ccw1 *ccw, struct DE_eckd_data *data, unsigned int trk,
245 rc = check_XRC (ccw, data, device); 248 rc = check_XRC (ccw, data, device);
246 break; 249 break;
247 default: 250 default:
248 DEV_MESSAGE(KERN_ERR, device, "unknown opcode 0x%x", cmd); 251 DBF_DEV_EVENT(DBF_ERR, device,
252 "PFX LRE unknown opcode 0x%x", cmd);
249 break; 253 break;
250 } 254 }
251 255
@@ -289,30 +293,145 @@ static int check_XRC_on_prefix(struct PFX_eckd_data *pfxdata,
289 return 0; 293 return 0;
290 294
291 /* switch on System Time Stamp - needed for XRC Support */ 295 /* switch on System Time Stamp - needed for XRC Support */
292 pfxdata->define_extend.ga_extended |= 0x08; /* 'Time Stamp Valid' */ 296 pfxdata->define_extent.ga_extended |= 0x08; /* 'Time Stamp Valid' */
293 pfxdata->define_extend.ga_extended |= 0x02; /* 'Extended Parameter' */ 297 pfxdata->define_extent.ga_extended |= 0x02; /* 'Extended Parameter' */
294 pfxdata->validity.time_stamp = 1; /* 'Time Stamp Valid' */ 298 pfxdata->validity.time_stamp = 1; /* 'Time Stamp Valid' */
295 299
296 rc = get_sync_clock(&pfxdata->define_extend.ep_sys_time); 300 rc = get_sync_clock(&pfxdata->define_extent.ep_sys_time);
297 /* Ignore return code if sync clock is switched off. */ 301 /* Ignore return code if sync clock is switched off. */
298 if (rc == -ENOSYS || rc == -EACCES) 302 if (rc == -ENOSYS || rc == -EACCES)
299 rc = 0; 303 rc = 0;
300 return rc; 304 return rc;
301} 305}
302 306
303static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata, 307static void fill_LRE_data(struct LRE_eckd_data *data, unsigned int trk,
304 unsigned int trk, unsigned int totrk, int cmd, 308 unsigned int rec_on_trk, int count, int cmd,
305 struct dasd_device *basedev, struct dasd_device *startdev) 309 struct dasd_device *device, unsigned int reclen,
310 unsigned int tlf)
311{
312 struct dasd_eckd_private *private;
313 int sector;
314 int dn, d;
315
316 private = (struct dasd_eckd_private *) device->private;
317
318 memset(data, 0, sizeof(*data));
319 sector = 0;
320 if (rec_on_trk) {
321 switch (private->rdc_data.dev_type) {
322 case 0x3390:
323 dn = ceil_quot(reclen + 6, 232);
324 d = 9 + ceil_quot(reclen + 6 * (dn + 1), 34);
325 sector = (49 + (rec_on_trk - 1) * (10 + d)) / 8;
326 break;
327 case 0x3380:
328 d = 7 + ceil_quot(reclen + 12, 32);
329 sector = (39 + (rec_on_trk - 1) * (8 + d)) / 7;
330 break;
331 }
332 }
333 data->sector = sector;
334 /* note: meaning of count depends on the operation
335 * for record based I/O it's the number of records, but for
336 * track based I/O it's the number of tracks
337 */
338 data->count = count;
339 switch (cmd) {
340 case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:
341 data->operation.orientation = 0x3;
342 data->operation.operation = 0x03;
343 break;
344 case DASD_ECKD_CCW_READ_HOME_ADDRESS:
345 data->operation.orientation = 0x3;
346 data->operation.operation = 0x16;
347 break;
348 case DASD_ECKD_CCW_WRITE_RECORD_ZERO:
349 data->operation.orientation = 0x1;
350 data->operation.operation = 0x03;
351 data->count++;
352 break;
353 case DASD_ECKD_CCW_READ_RECORD_ZERO:
354 data->operation.orientation = 0x3;
355 data->operation.operation = 0x16;
356 data->count++;
357 break;
358 case DASD_ECKD_CCW_WRITE:
359 case DASD_ECKD_CCW_WRITE_MT:
360 case DASD_ECKD_CCW_WRITE_KD:
361 case DASD_ECKD_CCW_WRITE_KD_MT:
362 data->auxiliary.length_valid = 0x1;
363 data->length = reclen;
364 data->operation.operation = 0x01;
365 break;
366 case DASD_ECKD_CCW_WRITE_CKD:
367 case DASD_ECKD_CCW_WRITE_CKD_MT:
368 data->auxiliary.length_valid = 0x1;
369 data->length = reclen;
370 data->operation.operation = 0x03;
371 break;
372 case DASD_ECKD_CCW_WRITE_TRACK_DATA:
373 data->auxiliary.length_valid = 0x1;
374 data->length = reclen; /* not tlf, as one might think */
375 data->operation.operation = 0x3F;
376 data->extended_operation = 0x23;
377 break;
378 case DASD_ECKD_CCW_READ:
379 case DASD_ECKD_CCW_READ_MT:
380 case DASD_ECKD_CCW_READ_KD:
381 case DASD_ECKD_CCW_READ_KD_MT:
382 data->auxiliary.length_valid = 0x1;
383 data->length = reclen;
384 data->operation.operation = 0x06;
385 break;
386 case DASD_ECKD_CCW_READ_CKD:
387 case DASD_ECKD_CCW_READ_CKD_MT:
388 data->auxiliary.length_valid = 0x1;
389 data->length = reclen;
390 data->operation.operation = 0x16;
391 break;
392 case DASD_ECKD_CCW_READ_COUNT:
393 data->operation.operation = 0x06;
394 break;
395 case DASD_ECKD_CCW_READ_TRACK_DATA:
396 data->auxiliary.length_valid = 0x1;
397 data->length = tlf;
398 data->operation.operation = 0x0C;
399 break;
400 case DASD_ECKD_CCW_ERASE:
401 data->length = reclen;
402 data->auxiliary.length_valid = 0x1;
403 data->operation.operation = 0x0b;
404 break;
405 default:
406 DBF_DEV_EVENT(DBF_ERR, device,
407 "fill LRE unknown opcode 0x%x", cmd);
408 BUG();
409 }
410 set_ch_t(&data->seek_addr,
411 trk / private->rdc_data.trk_per_cyl,
412 trk % private->rdc_data.trk_per_cyl);
413 data->search_arg.cyl = data->seek_addr.cyl;
414 data->search_arg.head = data->seek_addr.head;
415 data->search_arg.record = rec_on_trk;
416}
417
418static int prefix_LRE(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
419 unsigned int trk, unsigned int totrk, int cmd,
420 struct dasd_device *basedev, struct dasd_device *startdev,
421 unsigned char format, unsigned int rec_on_trk, int count,
422 unsigned int blksize, unsigned int tlf)
306{ 423{
307 struct dasd_eckd_private *basepriv, *startpriv; 424 struct dasd_eckd_private *basepriv, *startpriv;
308 struct DE_eckd_data *data; 425 struct DE_eckd_data *dedata;
426 struct LRE_eckd_data *lredata;
309 u32 begcyl, endcyl; 427 u32 begcyl, endcyl;
310 u16 heads, beghead, endhead; 428 u16 heads, beghead, endhead;
311 int rc = 0; 429 int rc = 0;
312 430
313 basepriv = (struct dasd_eckd_private *) basedev->private; 431 basepriv = (struct dasd_eckd_private *) basedev->private;
314 startpriv = (struct dasd_eckd_private *) startdev->private; 432 startpriv = (struct dasd_eckd_private *) startdev->private;
315 data = &pfxdata->define_extend; 433 dedata = &pfxdata->define_extent;
434 lredata = &pfxdata->locate_record;
316 435
317 ccw->cmd_code = DASD_ECKD_CCW_PFX; 436 ccw->cmd_code = DASD_ECKD_CCW_PFX;
318 ccw->flags = 0; 437 ccw->flags = 0;
@@ -321,10 +440,16 @@ static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
321 440
322 memset(pfxdata, 0, sizeof(*pfxdata)); 441 memset(pfxdata, 0, sizeof(*pfxdata));
323 /* prefix data */ 442 /* prefix data */
324 pfxdata->format = 0; 443 if (format > 1) {
444 DBF_DEV_EVENT(DBF_ERR, basedev,
445 "PFX LRE unknown format 0x%x", format);
446 BUG();
447 return -EINVAL;
448 }
449 pfxdata->format = format;
325 pfxdata->base_address = basepriv->ned->unit_addr; 450 pfxdata->base_address = basepriv->ned->unit_addr;
326 pfxdata->base_lss = basepriv->ned->ID; 451 pfxdata->base_lss = basepriv->ned->ID;
327 pfxdata->validity.define_extend = 1; 452 pfxdata->validity.define_extent = 1;
328 453
329 /* private uid is kept up to date, conf_data may be outdated */ 454 /* private uid is kept up to date, conf_data may be outdated */
330 if (startpriv->uid.type != UA_BASE_DEVICE) { 455 if (startpriv->uid.type != UA_BASE_DEVICE) {
@@ -344,42 +469,55 @@ static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
344 case DASD_ECKD_CCW_READ_KD: 469 case DASD_ECKD_CCW_READ_KD:
345 case DASD_ECKD_CCW_READ_KD_MT: 470 case DASD_ECKD_CCW_READ_KD_MT:
346 case DASD_ECKD_CCW_READ_COUNT: 471 case DASD_ECKD_CCW_READ_COUNT:
347 data->mask.perm = 0x1; 472 dedata->mask.perm = 0x1;
348 data->attributes.operation = basepriv->attrib.operation; 473 dedata->attributes.operation = basepriv->attrib.operation;
474 break;
475 case DASD_ECKD_CCW_READ_TRACK_DATA:
476 dedata->mask.perm = 0x1;
477 dedata->attributes.operation = basepriv->attrib.operation;
478 dedata->blk_size = 0;
349 break; 479 break;
350 case DASD_ECKD_CCW_WRITE: 480 case DASD_ECKD_CCW_WRITE:
351 case DASD_ECKD_CCW_WRITE_MT: 481 case DASD_ECKD_CCW_WRITE_MT:
352 case DASD_ECKD_CCW_WRITE_KD: 482 case DASD_ECKD_CCW_WRITE_KD:
353 case DASD_ECKD_CCW_WRITE_KD_MT: 483 case DASD_ECKD_CCW_WRITE_KD_MT:
354 data->mask.perm = 0x02; 484 dedata->mask.perm = 0x02;
355 data->attributes.operation = basepriv->attrib.operation; 485 dedata->attributes.operation = basepriv->attrib.operation;
356 rc = check_XRC_on_prefix(pfxdata, basedev); 486 rc = check_XRC_on_prefix(pfxdata, basedev);
357 break; 487 break;
358 case DASD_ECKD_CCW_WRITE_CKD: 488 case DASD_ECKD_CCW_WRITE_CKD:
359 case DASD_ECKD_CCW_WRITE_CKD_MT: 489 case DASD_ECKD_CCW_WRITE_CKD_MT:
360 data->attributes.operation = DASD_BYPASS_CACHE; 490 dedata->attributes.operation = DASD_BYPASS_CACHE;
361 rc = check_XRC_on_prefix(pfxdata, basedev); 491 rc = check_XRC_on_prefix(pfxdata, basedev);
362 break; 492 break;
363 case DASD_ECKD_CCW_ERASE: 493 case DASD_ECKD_CCW_ERASE:
364 case DASD_ECKD_CCW_WRITE_HOME_ADDRESS: 494 case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:
365 case DASD_ECKD_CCW_WRITE_RECORD_ZERO: 495 case DASD_ECKD_CCW_WRITE_RECORD_ZERO:
366 data->mask.perm = 0x3; 496 dedata->mask.perm = 0x3;
367 data->mask.auth = 0x1; 497 dedata->mask.auth = 0x1;
368 data->attributes.operation = DASD_BYPASS_CACHE; 498 dedata->attributes.operation = DASD_BYPASS_CACHE;
369 rc = check_XRC_on_prefix(pfxdata, basedev); 499 rc = check_XRC_on_prefix(pfxdata, basedev);
370 break; 500 break;
371 default: 501 case DASD_ECKD_CCW_WRITE_TRACK_DATA:
372 DEV_MESSAGE(KERN_ERR, basedev, "unknown opcode 0x%x", cmd); 502 dedata->mask.perm = 0x02;
503 dedata->attributes.operation = basepriv->attrib.operation;
504 dedata->blk_size = blksize;
505 rc = check_XRC_on_prefix(pfxdata, basedev);
373 break; 506 break;
507 default:
508 DBF_DEV_EVENT(DBF_ERR, basedev,
509 "PFX LRE unknown opcode 0x%x", cmd);
510 BUG();
511 return -EINVAL;
374 } 512 }
375 513
376 data->attributes.mode = 0x3; /* ECKD */ 514 dedata->attributes.mode = 0x3; /* ECKD */
377 515
378 if ((basepriv->rdc_data.cu_type == 0x2105 || 516 if ((basepriv->rdc_data.cu_type == 0x2105 ||
379 basepriv->rdc_data.cu_type == 0x2107 || 517 basepriv->rdc_data.cu_type == 0x2107 ||
380 basepriv->rdc_data.cu_type == 0x1750) 518 basepriv->rdc_data.cu_type == 0x1750)
381 && !(basepriv->uses_cdl && trk < 2)) 519 && !(basepriv->uses_cdl && trk < 2))
382 data->ga_extended |= 0x40; /* Regular Data Format Mode */ 520 dedata->ga_extended |= 0x40; /* Regular Data Format Mode */
383 521
384 heads = basepriv->rdc_data.trk_per_cyl; 522 heads = basepriv->rdc_data.trk_per_cyl;
385 begcyl = trk / heads; 523 begcyl = trk / heads;
@@ -388,8 +526,8 @@ static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
388 endhead = totrk % heads; 526 endhead = totrk % heads;
389 527
390 /* check for sequential prestage - enhance cylinder range */ 528 /* check for sequential prestage - enhance cylinder range */
391 if (data->attributes.operation == DASD_SEQ_PRESTAGE || 529 if (dedata->attributes.operation == DASD_SEQ_PRESTAGE ||
392 data->attributes.operation == DASD_SEQ_ACCESS) { 530 dedata->attributes.operation == DASD_SEQ_ACCESS) {
393 531
394 if (endcyl + basepriv->attrib.nr_cyl < basepriv->real_cyl) 532 if (endcyl + basepriv->attrib.nr_cyl < basepriv->real_cyl)
395 endcyl += basepriv->attrib.nr_cyl; 533 endcyl += basepriv->attrib.nr_cyl;
@@ -397,11 +535,25 @@ static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
397 endcyl = (basepriv->real_cyl - 1); 535 endcyl = (basepriv->real_cyl - 1);
398 } 536 }
399 537
400 set_ch_t(&data->beg_ext, begcyl, beghead); 538 set_ch_t(&dedata->beg_ext, begcyl, beghead);
401 set_ch_t(&data->end_ext, endcyl, endhead); 539 set_ch_t(&dedata->end_ext, endcyl, endhead);
540
541 if (format == 1) {
542 fill_LRE_data(lredata, trk, rec_on_trk, count, cmd,
543 basedev, blksize, tlf);
544 }
545
402 return rc; 546 return rc;
403} 547}
404 548
549static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
550 unsigned int trk, unsigned int totrk, int cmd,
551 struct dasd_device *basedev, struct dasd_device *startdev)
552{
553 return prefix_LRE(ccw, pfxdata, trk, totrk, cmd, basedev, startdev,
554 0, 0, 0, 0, 0);
555}
556
405static void 557static void
406locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, unsigned int trk, 558locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, unsigned int trk,
407 unsigned int rec_on_trk, int no_rec, int cmd, 559 unsigned int rec_on_trk, int no_rec, int cmd,
@@ -845,7 +997,8 @@ static int dasd_eckd_read_features(struct dasd_device *device)
845/* 997/*
846 * Build CP for Perform Subsystem Function - SSC. 998 * Build CP for Perform Subsystem Function - SSC.
847 */ 999 */
848static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device) 1000static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device,
1001 int enable_pav)
849{ 1002{
850 struct dasd_ccw_req *cqr; 1003 struct dasd_ccw_req *cqr;
851 struct dasd_psf_ssc_data *psf_ssc_data; 1004 struct dasd_psf_ssc_data *psf_ssc_data;
@@ -862,9 +1015,11 @@ static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device)
862 } 1015 }
863 psf_ssc_data = (struct dasd_psf_ssc_data *)cqr->data; 1016 psf_ssc_data = (struct dasd_psf_ssc_data *)cqr->data;
864 psf_ssc_data->order = PSF_ORDER_SSC; 1017 psf_ssc_data->order = PSF_ORDER_SSC;
865 psf_ssc_data->suborder = 0x88; 1018 psf_ssc_data->suborder = 0x40;
866 psf_ssc_data->reserved[0] = 0x88; 1019 if (enable_pav) {
867 1020 psf_ssc_data->suborder |= 0x88;
1021 psf_ssc_data->reserved[0] = 0x88;
1022 }
868 ccw = cqr->cpaddr; 1023 ccw = cqr->cpaddr;
869 ccw->cmd_code = DASD_ECKD_CCW_PSF; 1024 ccw->cmd_code = DASD_ECKD_CCW_PSF;
870 ccw->cda = (__u32)(addr_t)psf_ssc_data; 1025 ccw->cda = (__u32)(addr_t)psf_ssc_data;
@@ -885,12 +1040,12 @@ static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device)
885 * call might change behaviour of DASD devices. 1040 * call might change behaviour of DASD devices.
886 */ 1041 */
887static int 1042static int
888dasd_eckd_psf_ssc(struct dasd_device *device) 1043dasd_eckd_psf_ssc(struct dasd_device *device, int enable_pav)
889{ 1044{
890 struct dasd_ccw_req *cqr; 1045 struct dasd_ccw_req *cqr;
891 int rc; 1046 int rc;
892 1047
893 cqr = dasd_eckd_build_psf_ssc(device); 1048 cqr = dasd_eckd_build_psf_ssc(device, enable_pav);
894 if (IS_ERR(cqr)) 1049 if (IS_ERR(cqr))
895 return PTR_ERR(cqr); 1050 return PTR_ERR(cqr);
896 1051
@@ -909,12 +1064,13 @@ static int dasd_eckd_validate_server(struct dasd_device *device)
909{ 1064{
910 int rc; 1065 int rc;
911 struct dasd_eckd_private *private; 1066 struct dasd_eckd_private *private;
1067 int enable_pav;
912 1068
913 /* Currently PAV is the only reason to 'validate' server on LPAR */
914 if (dasd_nopav || MACHINE_IS_VM) 1069 if (dasd_nopav || MACHINE_IS_VM)
915 return 0; 1070 enable_pav = 0;
916 1071 else
917 rc = dasd_eckd_psf_ssc(device); 1072 enable_pav = 1;
1073 rc = dasd_eckd_psf_ssc(device, enable_pav);
918 /* may be requested feature is not available on server, 1074 /* may be requested feature is not available on server,
919 * therefore just report error and go ahead */ 1075 * therefore just report error and go ahead */
920 private = (struct dasd_eckd_private *) device->private; 1076 private = (struct dasd_eckd_private *) device->private;
@@ -1504,40 +1660,41 @@ static void dasd_eckd_handle_unsolicited_interrupt(struct dasd_device *device,
1504 struct irb *irb) 1660 struct irb *irb)
1505{ 1661{
1506 char mask; 1662 char mask;
1663 char *sense = NULL;
1507 1664
1508 /* first of all check for state change pending interrupt */ 1665 /* first of all check for state change pending interrupt */
1509 mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP; 1666 mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP;
1510 if ((irb->scsw.cmd.dstat & mask) == mask) { 1667 if ((scsw_dstat(&irb->scsw) & mask) == mask) {
1511 dasd_generic_handle_state_change(device); 1668 dasd_generic_handle_state_change(device);
1512 return; 1669 return;
1513 } 1670 }
1514 1671
1515 /* summary unit check */ 1672 /* summary unit check */
1516 if ((irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) && 1673 if ((scsw_dstat(&irb->scsw) & DEV_STAT_UNIT_CHECK) &&
1517 (irb->ecw[7] == 0x0D)) { 1674 (irb->ecw[7] == 0x0D)) {
1518 dasd_alias_handle_summary_unit_check(device, irb); 1675 dasd_alias_handle_summary_unit_check(device, irb);
1519 return; 1676 return;
1520 } 1677 }
1521 1678
1522 1679 sense = dasd_get_sense(irb);
1523 /* service information message SIM */ 1680 /* service information message SIM */
1524 if (irb->esw.esw0.erw.cons && !(irb->ecw[27] & DASD_SENSE_BIT_0) && 1681 if (sense && !(sense[27] & DASD_SENSE_BIT_0) &&
1525 ((irb->ecw[6] & DASD_SIM_SENSE) == DASD_SIM_SENSE)) { 1682 ((sense[6] & DASD_SIM_SENSE) == DASD_SIM_SENSE)) {
1526 dasd_3990_erp_handle_sim(device, irb->ecw); 1683 dasd_3990_erp_handle_sim(device, sense);
1527 dasd_schedule_device_bh(device); 1684 dasd_schedule_device_bh(device);
1528 return; 1685 return;
1529 } 1686 }
1530 1687
1531 if ((irb->scsw.cmd.cc == 1) && 1688 if ((scsw_cc(&irb->scsw) == 1) &&
1532 (irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC) && 1689 (scsw_fctl(&irb->scsw) & SCSW_FCTL_START_FUNC) &&
1533 (irb->scsw.cmd.actl & SCSW_ACTL_START_PEND) && 1690 (scsw_actl(&irb->scsw) & SCSW_ACTL_START_PEND) &&
1534 (irb->scsw.cmd.stctl & SCSW_STCTL_STATUS_PEND)) { 1691 (scsw_stctl(&irb->scsw) & SCSW_STCTL_STATUS_PEND)) {
1535 /* fake irb do nothing, they are handled elsewhere */ 1692 /* fake irb do nothing, they are handled elsewhere */
1536 dasd_schedule_device_bh(device); 1693 dasd_schedule_device_bh(device);
1537 return; 1694 return;
1538 } 1695 }
1539 1696
1540 if (!(irb->esw.esw0.erw.cons)) { 1697 if (!sense) {
1541 /* just report other unsolicited interrupts */ 1698 /* just report other unsolicited interrupts */
1542 DEV_MESSAGE(KERN_ERR, device, "%s", 1699 DEV_MESSAGE(KERN_ERR, device, "%s",
1543 "unsolicited interrupt received"); 1700 "unsolicited interrupt received");
@@ -1552,9 +1709,19 @@ static void dasd_eckd_handle_unsolicited_interrupt(struct dasd_device *device,
1552 return; 1709 return;
1553}; 1710};
1554 1711
1555static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev, 1712
1713static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single(
1714 struct dasd_device *startdev,
1556 struct dasd_block *block, 1715 struct dasd_block *block,
1557 struct request *req) 1716 struct request *req,
1717 sector_t first_rec,
1718 sector_t last_rec,
1719 sector_t first_trk,
1720 sector_t last_trk,
1721 unsigned int first_offs,
1722 unsigned int last_offs,
1723 unsigned int blk_per_trk,
1724 unsigned int blksize)
1558{ 1725{
1559 struct dasd_eckd_private *private; 1726 struct dasd_eckd_private *private;
1560 unsigned long *idaws; 1727 unsigned long *idaws;
@@ -1564,11 +1731,9 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
1564 struct req_iterator iter; 1731 struct req_iterator iter;
1565 struct bio_vec *bv; 1732 struct bio_vec *bv;
1566 char *dst; 1733 char *dst;
1567 unsigned int blksize, blk_per_trk, off; 1734 unsigned int off;
1568 int count, cidaw, cplength, datasize; 1735 int count, cidaw, cplength, datasize;
1569 sector_t recid, first_rec, last_rec; 1736 sector_t recid;
1570 sector_t first_trk, last_trk;
1571 unsigned int first_offs, last_offs;
1572 unsigned char cmd, rcmd; 1737 unsigned char cmd, rcmd;
1573 int use_prefix; 1738 int use_prefix;
1574 struct dasd_device *basedev; 1739 struct dasd_device *basedev;
@@ -1581,15 +1746,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
1581 cmd = DASD_ECKD_CCW_WRITE_MT; 1746 cmd = DASD_ECKD_CCW_WRITE_MT;
1582 else 1747 else
1583 return ERR_PTR(-EINVAL); 1748 return ERR_PTR(-EINVAL);
1584 /* Calculate number of blocks/records per track. */ 1749
1585 blksize = block->bp_block;
1586 blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize);
1587 /* Calculate record id of first and last block. */
1588 first_rec = first_trk = req->sector >> block->s2b_shift;
1589 first_offs = sector_div(first_trk, blk_per_trk);
1590 last_rec = last_trk =
1591 (req->sector + req->nr_sectors - 1) >> block->s2b_shift;
1592 last_offs = sector_div(last_trk, blk_per_trk);
1593 /* Check struct bio and count the number of blocks for the request. */ 1750 /* Check struct bio and count the number of blocks for the request. */
1594 count = 0; 1751 count = 0;
1595 cidaw = 0; 1752 cidaw = 0;
@@ -1739,6 +1896,497 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
1739 return cqr; 1896 return cqr;
1740} 1897}
1741 1898
1899static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_track(
1900 struct dasd_device *startdev,
1901 struct dasd_block *block,
1902 struct request *req,
1903 sector_t first_rec,
1904 sector_t last_rec,
1905 sector_t first_trk,
1906 sector_t last_trk,
1907 unsigned int first_offs,
1908 unsigned int last_offs,
1909 unsigned int blk_per_trk,
1910 unsigned int blksize)
1911{
1912 struct dasd_eckd_private *private;
1913 unsigned long *idaws;
1914 struct dasd_ccw_req *cqr;
1915 struct ccw1 *ccw;
1916 struct req_iterator iter;
1917 struct bio_vec *bv;
1918 char *dst, *idaw_dst;
1919 unsigned int cidaw, cplength, datasize;
1920 unsigned int tlf;
1921 sector_t recid;
1922 unsigned char cmd;
1923 struct dasd_device *basedev;
1924 unsigned int trkcount, count, count_to_trk_end;
1925 unsigned int idaw_len, seg_len, part_len, len_to_track_end;
1926 unsigned char new_track, end_idaw;
1927 sector_t trkid;
1928 unsigned int recoffs;
1929
1930 basedev = block->base;
1931 private = (struct dasd_eckd_private *) basedev->private;
1932 if (rq_data_dir(req) == READ)
1933 cmd = DASD_ECKD_CCW_READ_TRACK_DATA;
1934 else if (rq_data_dir(req) == WRITE)
1935 cmd = DASD_ECKD_CCW_WRITE_TRACK_DATA;
1936 else
1937 return ERR_PTR(-EINVAL);
1938
1939 /* Track based I/O needs IDAWs for each page, and not just for
1940 * 64 bit addresses. We need additional idals for pages
1941 * that get filled from two tracks, so we use the number
1942 * of records as upper limit.
1943 */
1944 cidaw = last_rec - first_rec + 1;
1945 trkcount = last_trk - first_trk + 1;
1946
1947 /* 1x prefix + one read/write ccw per track */
1948 cplength = 1 + trkcount;
1949
1950 /* on 31-bit we need space for two 32 bit addresses per page
1951 * on 64-bit one 64 bit address
1952 */
1953 datasize = sizeof(struct PFX_eckd_data) +
1954 cidaw * sizeof(unsigned long long);
1955
1956 /* Allocate the ccw request. */
1957 cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
1958 cplength, datasize, startdev);
1959 if (IS_ERR(cqr))
1960 return cqr;
1961 ccw = cqr->cpaddr;
1962 /* transfer length factor: how many bytes to read from the last track */
1963 if (first_trk == last_trk)
1964 tlf = last_offs - first_offs + 1;
1965 else
1966 tlf = last_offs + 1;
1967 tlf *= blksize;
1968
1969 if (prefix_LRE(ccw++, cqr->data, first_trk,
1970 last_trk, cmd, basedev, startdev,
1971 1 /* format */, first_offs + 1,
1972 trkcount, blksize,
1973 tlf) == -EAGAIN) {
1974 /* Clock not in sync and XRC is enabled.
1975 * Try again later.
1976 */
1977 dasd_sfree_request(cqr, startdev);
1978 return ERR_PTR(-EAGAIN);
1979 }
1980
1981 /*
1982 * The translation of request into ccw programs must meet the
1983 * following conditions:
1984 * - all idaws but the first and the last must address full pages
1985 * (or 2K blocks on 31-bit)
1986 * - the scope of a ccw and it's idal ends with the track boundaries
1987 */
1988 idaws = (unsigned long *) (cqr->data + sizeof(struct PFX_eckd_data));
1989 recid = first_rec;
1990 new_track = 1;
1991 end_idaw = 0;
1992 len_to_track_end = 0;
1993 idaw_dst = 0;
1994 idaw_len = 0;
1995 rq_for_each_segment(bv, req, iter) {
1996 dst = page_address(bv->bv_page) + bv->bv_offset;
1997 seg_len = bv->bv_len;
1998 while (seg_len) {
1999 if (new_track) {
2000 trkid = recid;
2001 recoffs = sector_div(trkid, blk_per_trk);
2002 count_to_trk_end = blk_per_trk - recoffs;
2003 count = min((last_rec - recid + 1),
2004 (sector_t)count_to_trk_end);
2005 len_to_track_end = count * blksize;
2006 ccw[-1].flags |= CCW_FLAG_CC;
2007 ccw->cmd_code = cmd;
2008 ccw->count = len_to_track_end;
2009 ccw->cda = (__u32)(addr_t)idaws;
2010 ccw->flags = CCW_FLAG_IDA;
2011 ccw++;
2012 recid += count;
2013 new_track = 0;
2014 }
2015 /* If we start a new idaw, everything is fine and the
2016 * start of the new idaw is the start of this segment.
2017 * If we continue an idaw, we must make sure that the
2018 * current segment begins where the so far accumulated
2019 * idaw ends
2020 */
2021 if (!idaw_dst)
2022 idaw_dst = dst;
2023 if ((idaw_dst + idaw_len) != dst) {
2024 dasd_sfree_request(cqr, startdev);
2025 return ERR_PTR(-ERANGE);
2026 }
2027 part_len = min(seg_len, len_to_track_end);
2028 seg_len -= part_len;
2029 dst += part_len;
2030 idaw_len += part_len;
2031 len_to_track_end -= part_len;
2032 /* collected memory area ends on an IDA_BLOCK border,
2033 * -> create an idaw
2034 * idal_create_words will handle cases where idaw_len
2035 * is larger then IDA_BLOCK_SIZE
2036 */
2037 if (!(__pa(idaw_dst + idaw_len) & (IDA_BLOCK_SIZE-1)))
2038 end_idaw = 1;
2039 /* We also need to end the idaw at track end */
2040 if (!len_to_track_end) {
2041 new_track = 1;
2042 end_idaw = 1;
2043 }
2044 if (end_idaw) {
2045 idaws = idal_create_words(idaws, idaw_dst,
2046 idaw_len);
2047 idaw_dst = 0;
2048 idaw_len = 0;
2049 end_idaw = 0;
2050 }
2051 }
2052 }
2053
2054 if (blk_noretry_request(req) ||
2055 block->base->features & DASD_FEATURE_FAILFAST)
2056 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
2057 cqr->startdev = startdev;
2058 cqr->memdev = startdev;
2059 cqr->block = block;
2060 cqr->expires = 5 * 60 * HZ; /* 5 minutes */
2061 cqr->lpm = private->path_data.ppm;
2062 cqr->retries = 256;
2063 cqr->buildclk = get_clock();
2064 cqr->status = DASD_CQR_FILLED;
2065 return cqr;
2066}
2067
2068static int prepare_itcw(struct itcw *itcw,
2069 unsigned int trk, unsigned int totrk, int cmd,
2070 struct dasd_device *basedev,
2071 struct dasd_device *startdev,
2072 unsigned int rec_on_trk, int count,
2073 unsigned int blksize,
2074 unsigned int total_data_size,
2075 unsigned int tlf,
2076 unsigned int blk_per_trk)
2077{
2078 struct PFX_eckd_data pfxdata;
2079 struct dasd_eckd_private *basepriv, *startpriv;
2080 struct DE_eckd_data *dedata;
2081 struct LRE_eckd_data *lredata;
2082 struct dcw *dcw;
2083
2084 u32 begcyl, endcyl;
2085 u16 heads, beghead, endhead;
2086 u8 pfx_cmd;
2087
2088 int rc = 0;
2089 int sector = 0;
2090 int dn, d;
2091
2092
2093 /* setup prefix data */
2094 basepriv = (struct dasd_eckd_private *) basedev->private;
2095 startpriv = (struct dasd_eckd_private *) startdev->private;
2096 dedata = &pfxdata.define_extent;
2097 lredata = &pfxdata.locate_record;
2098
2099 memset(&pfxdata, 0, sizeof(pfxdata));
2100 pfxdata.format = 1; /* PFX with LRE */
2101 pfxdata.base_address = basepriv->ned->unit_addr;
2102 pfxdata.base_lss = basepriv->ned->ID;
2103 pfxdata.validity.define_extent = 1;
2104
2105 /* private uid is kept up to date, conf_data may be outdated */
2106 if (startpriv->uid.type != UA_BASE_DEVICE) {
2107 pfxdata.validity.verify_base = 1;
2108 if (startpriv->uid.type == UA_HYPER_PAV_ALIAS)
2109 pfxdata.validity.hyper_pav = 1;
2110 }
2111
2112 switch (cmd) {
2113 case DASD_ECKD_CCW_READ_TRACK_DATA:
2114 dedata->mask.perm = 0x1;
2115 dedata->attributes.operation = basepriv->attrib.operation;
2116 dedata->blk_size = blksize;
2117 dedata->ga_extended |= 0x42;
2118 lredata->operation.orientation = 0x0;
2119 lredata->operation.operation = 0x0C;
2120 lredata->auxiliary.check_bytes = 0x01;
2121 pfx_cmd = DASD_ECKD_CCW_PFX_READ;
2122 break;
2123 case DASD_ECKD_CCW_WRITE_TRACK_DATA:
2124 dedata->mask.perm = 0x02;
2125 dedata->attributes.operation = basepriv->attrib.operation;
2126 dedata->blk_size = blksize;
2127 rc = check_XRC_on_prefix(&pfxdata, basedev);
2128 dedata->ga_extended |= 0x42;
2129 lredata->operation.orientation = 0x0;
2130 lredata->operation.operation = 0x3F;
2131 lredata->extended_operation = 0x23;
2132 lredata->auxiliary.check_bytes = 0x2;
2133 pfx_cmd = DASD_ECKD_CCW_PFX;
2134 break;
2135 default:
2136 DBF_DEV_EVENT(DBF_ERR, basedev,
2137 "prepare itcw, unknown opcode 0x%x", cmd);
2138 BUG();
2139 break;
2140 }
2141 if (rc)
2142 return rc;
2143
2144 dedata->attributes.mode = 0x3; /* ECKD */
2145
2146 heads = basepriv->rdc_data.trk_per_cyl;
2147 begcyl = trk / heads;
2148 beghead = trk % heads;
2149 endcyl = totrk / heads;
2150 endhead = totrk % heads;
2151
2152 /* check for sequential prestage - enhance cylinder range */
2153 if (dedata->attributes.operation == DASD_SEQ_PRESTAGE ||
2154 dedata->attributes.operation == DASD_SEQ_ACCESS) {
2155
2156 if (endcyl + basepriv->attrib.nr_cyl < basepriv->real_cyl)
2157 endcyl += basepriv->attrib.nr_cyl;
2158 else
2159 endcyl = (basepriv->real_cyl - 1);
2160 }
2161
2162 set_ch_t(&dedata->beg_ext, begcyl, beghead);
2163 set_ch_t(&dedata->end_ext, endcyl, endhead);
2164
2165 dedata->ep_format = 0x20; /* records per track is valid */
2166 dedata->ep_rec_per_track = blk_per_trk;
2167
2168 if (rec_on_trk) {
2169 switch (basepriv->rdc_data.dev_type) {
2170 case 0x3390:
2171 dn = ceil_quot(blksize + 6, 232);
2172 d = 9 + ceil_quot(blksize + 6 * (dn + 1), 34);
2173 sector = (49 + (rec_on_trk - 1) * (10 + d)) / 8;
2174 break;
2175 case 0x3380:
2176 d = 7 + ceil_quot(blksize + 12, 32);
2177 sector = (39 + (rec_on_trk - 1) * (8 + d)) / 7;
2178 break;
2179 }
2180 }
2181
2182 lredata->auxiliary.length_valid = 1;
2183 lredata->auxiliary.length_scope = 1;
2184 lredata->auxiliary.imbedded_ccw_valid = 1;
2185 lredata->length = tlf;
2186 lredata->imbedded_ccw = cmd;
2187 lredata->count = count;
2188 lredata->sector = sector;
2189 set_ch_t(&lredata->seek_addr, begcyl, beghead);
2190 lredata->search_arg.cyl = lredata->seek_addr.cyl;
2191 lredata->search_arg.head = lredata->seek_addr.head;
2192 lredata->search_arg.record = rec_on_trk;
2193
2194 dcw = itcw_add_dcw(itcw, pfx_cmd, 0,
2195 &pfxdata, sizeof(pfxdata), total_data_size);
2196
2197 return rc;
2198}
2199
2200static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
2201 struct dasd_device *startdev,
2202 struct dasd_block *block,
2203 struct request *req,
2204 sector_t first_rec,
2205 sector_t last_rec,
2206 sector_t first_trk,
2207 sector_t last_trk,
2208 unsigned int first_offs,
2209 unsigned int last_offs,
2210 unsigned int blk_per_trk,
2211 unsigned int blksize)
2212{
2213 struct dasd_eckd_private *private;
2214 struct dasd_ccw_req *cqr;
2215 struct req_iterator iter;
2216 struct bio_vec *bv;
2217 char *dst;
2218 unsigned int trkcount, ctidaw;
2219 unsigned char cmd;
2220 struct dasd_device *basedev;
2221 unsigned int tlf;
2222 struct itcw *itcw;
2223 struct tidaw *last_tidaw = NULL;
2224 int itcw_op;
2225 size_t itcw_size;
2226
2227 basedev = block->base;
2228 private = (struct dasd_eckd_private *) basedev->private;
2229 if (rq_data_dir(req) == READ) {
2230 cmd = DASD_ECKD_CCW_READ_TRACK_DATA;
2231 itcw_op = ITCW_OP_READ;
2232 } else if (rq_data_dir(req) == WRITE) {
2233 cmd = DASD_ECKD_CCW_WRITE_TRACK_DATA;
2234 itcw_op = ITCW_OP_WRITE;
2235 } else
2236 return ERR_PTR(-EINVAL);
2237
2238 /* trackbased I/O needs address all memory via TIDAWs,
2239 * not just for 64 bit addresses. This allows us to map
2240 * each segment directly to one tidaw.
2241 */
2242 trkcount = last_trk - first_trk + 1;
2243 ctidaw = 0;
2244 rq_for_each_segment(bv, req, iter) {
2245 ++ctidaw;
2246 }
2247
2248 /* Allocate the ccw request. */
2249 itcw_size = itcw_calc_size(0, ctidaw, 0);
2250 cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
2251 0, itcw_size, startdev);
2252 if (IS_ERR(cqr))
2253 return cqr;
2254
2255 cqr->cpmode = 1;
2256 cqr->startdev = startdev;
2257 cqr->memdev = startdev;
2258 cqr->block = block;
2259 cqr->expires = 100*HZ;
2260 cqr->buildclk = get_clock();
2261 cqr->status = DASD_CQR_FILLED;
2262 cqr->retries = 10;
2263
2264 /* transfer length factor: how many bytes to read from the last track */
2265 if (first_trk == last_trk)
2266 tlf = last_offs - first_offs + 1;
2267 else
2268 tlf = last_offs + 1;
2269 tlf *= blksize;
2270
2271 itcw = itcw_init(cqr->data, itcw_size, itcw_op, 0, ctidaw, 0);
2272 cqr->cpaddr = itcw_get_tcw(itcw);
2273
2274 if (prepare_itcw(itcw, first_trk, last_trk,
2275 cmd, basedev, startdev,
2276 first_offs + 1,
2277 trkcount, blksize,
2278 (last_rec - first_rec + 1) * blksize,
2279 tlf, blk_per_trk) == -EAGAIN) {
2280 /* Clock not in sync and XRC is enabled.
2281 * Try again later.
2282 */
2283 dasd_sfree_request(cqr, startdev);
2284 return ERR_PTR(-EAGAIN);
2285 }
2286
2287 /*
2288 * A tidaw can address 4k of memory, but must not cross page boundaries
2289 * We can let the block layer handle this by setting
2290 * blk_queue_segment_boundary to page boundaries and
2291 * blk_max_segment_size to page size when setting up the request queue.
2292 */
2293 rq_for_each_segment(bv, req, iter) {
2294 dst = page_address(bv->bv_page) + bv->bv_offset;
2295 last_tidaw = itcw_add_tidaw(itcw, 0x00, dst, bv->bv_len);
2296 if (IS_ERR(last_tidaw))
2297 return (struct dasd_ccw_req *)last_tidaw;
2298 }
2299
2300 last_tidaw->flags |= 0x80;
2301 itcw_finalize(itcw);
2302
2303 if (blk_noretry_request(req) ||
2304 block->base->features & DASD_FEATURE_FAILFAST)
2305 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
2306 cqr->startdev = startdev;
2307 cqr->memdev = startdev;
2308 cqr->block = block;
2309 cqr->expires = 5 * 60 * HZ; /* 5 minutes */
2310 cqr->lpm = private->path_data.ppm;
2311 cqr->retries = 256;
2312 cqr->buildclk = get_clock();
2313 cqr->status = DASD_CQR_FILLED;
2314 return cqr;
2315}
2316
2317static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
2318 struct dasd_block *block,
2319 struct request *req)
2320{
2321 int tpm, cmdrtd, cmdwtd;
2322 int use_prefix;
2323
2324 struct dasd_eckd_private *private;
2325 int fcx_in_css, fcx_in_gneq, fcx_in_features;
2326 struct dasd_device *basedev;
2327 sector_t first_rec, last_rec;
2328 sector_t first_trk, last_trk;
2329 unsigned int first_offs, last_offs;
2330 unsigned int blk_per_trk, blksize;
2331 int cdlspecial;
2332 struct dasd_ccw_req *cqr;
2333
2334 basedev = block->base;
2335 private = (struct dasd_eckd_private *) basedev->private;
2336
2337 /* Calculate number of blocks/records per track. */
2338 blksize = block->bp_block;
2339 blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize);
2340 /* Calculate record id of first and last block. */
2341 first_rec = first_trk = req->sector >> block->s2b_shift;
2342 first_offs = sector_div(first_trk, blk_per_trk);
2343 last_rec = last_trk =
2344 (req->sector + req->nr_sectors - 1) >> block->s2b_shift;
2345 last_offs = sector_div(last_trk, blk_per_trk);
2346 cdlspecial = (private->uses_cdl && first_rec < 2*blk_per_trk);
2347
2348 /* is transport mode supported ? */
2349 fcx_in_css = css_general_characteristics.fcx;
2350 fcx_in_gneq = private->gneq->reserved2[7] & 0x04;
2351 fcx_in_features = private->features.feature[40] & 0x80;
2352 tpm = fcx_in_css && fcx_in_gneq && fcx_in_features;
2353
2354 /* is read track data and write track data in command mode supported? */
2355 cmdrtd = private->features.feature[9] & 0x20;
2356 cmdwtd = private->features.feature[12] & 0x40;
2357 use_prefix = private->features.feature[8] & 0x01;
2358
2359 cqr = NULL;
2360 if (cdlspecial || dasd_page_cache) {
2361 /* do nothing, just fall through to the cmd mode single case */
2362 } else if (!dasd_nofcx && tpm && (first_trk == last_trk)) {
2363 cqr = dasd_eckd_build_cp_tpm_track(startdev, block, req,
2364 first_rec, last_rec,
2365 first_trk, last_trk,
2366 first_offs, last_offs,
2367 blk_per_trk, blksize);
2368 if (IS_ERR(cqr) && PTR_ERR(cqr) != -EAGAIN)
2369 cqr = NULL;
2370 } else if (use_prefix &&
2371 (((rq_data_dir(req) == READ) && cmdrtd) ||
2372 ((rq_data_dir(req) == WRITE) && cmdwtd))) {
2373 cqr = dasd_eckd_build_cp_cmd_track(startdev, block, req,
2374 first_rec, last_rec,
2375 first_trk, last_trk,
2376 first_offs, last_offs,
2377 blk_per_trk, blksize);
2378 if (IS_ERR(cqr) && PTR_ERR(cqr) != -EAGAIN)
2379 cqr = NULL;
2380 }
2381 if (!cqr)
2382 cqr = dasd_eckd_build_cp_cmd_single(startdev, block, req,
2383 first_rec, last_rec,
2384 first_trk, last_trk,
2385 first_offs, last_offs,
2386 blk_per_trk, blksize);
2387 return cqr;
2388}
2389
1742static int 2390static int
1743dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req) 2391dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req)
1744{ 2392{
@@ -1792,7 +2440,7 @@ out:
1792} 2440}
1793 2441
1794/* 2442/*
1795 * Modify ccw chain in cqr so it can be started on a base device. 2443 * Modify ccw/tcw in cqr so it can be started on a base device.
1796 * 2444 *
1797 * Note that this is not enough to restart the cqr! 2445 * Note that this is not enough to restart the cqr!
1798 * Either reset cqr->startdev as well (summary unit check handling) 2446 * Either reset cqr->startdev as well (summary unit check handling)
@@ -1802,13 +2450,24 @@ void dasd_eckd_reset_ccw_to_base_io(struct dasd_ccw_req *cqr)
1802{ 2450{
1803 struct ccw1 *ccw; 2451 struct ccw1 *ccw;
1804 struct PFX_eckd_data *pfxdata; 2452 struct PFX_eckd_data *pfxdata;
1805 2453 struct tcw *tcw;
1806 ccw = cqr->cpaddr; 2454 struct tccb *tccb;
1807 pfxdata = cqr->data; 2455 struct dcw *dcw;
1808 2456
1809 if (ccw->cmd_code == DASD_ECKD_CCW_PFX) { 2457 if (cqr->cpmode == 1) {
2458 tcw = cqr->cpaddr;
2459 tccb = tcw_get_tccb(tcw);
2460 dcw = (struct dcw *)&tccb->tca[0];
2461 pfxdata = (struct PFX_eckd_data *)&dcw->cd[0];
1810 pfxdata->validity.verify_base = 0; 2462 pfxdata->validity.verify_base = 0;
1811 pfxdata->validity.hyper_pav = 0; 2463 pfxdata->validity.hyper_pav = 0;
2464 } else {
2465 ccw = cqr->cpaddr;
2466 pfxdata = cqr->data;
2467 if (ccw->cmd_code == DASD_ECKD_CCW_PFX) {
2468 pfxdata->validity.verify_base = 0;
2469 pfxdata->validity.hyper_pav = 0;
2470 }
1812 } 2471 }
1813} 2472}
1814 2473
@@ -1886,6 +2545,7 @@ dasd_eckd_release(struct dasd_device *device)
1886{ 2545{
1887 struct dasd_ccw_req *cqr; 2546 struct dasd_ccw_req *cqr;
1888 int rc; 2547 int rc;
2548 struct ccw1 *ccw;
1889 2549
1890 if (!capable(CAP_SYS_ADMIN)) 2550 if (!capable(CAP_SYS_ADMIN))
1891 return -EACCES; 2551 return -EACCES;
@@ -1897,10 +2557,11 @@ dasd_eckd_release(struct dasd_device *device)
1897 "Could not allocate initialization request"); 2557 "Could not allocate initialization request");
1898 return PTR_ERR(cqr); 2558 return PTR_ERR(cqr);
1899 } 2559 }
1900 cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RELEASE; 2560 ccw = cqr->cpaddr;
1901 cqr->cpaddr->flags |= CCW_FLAG_SLI; 2561 ccw->cmd_code = DASD_ECKD_CCW_RELEASE;
1902 cqr->cpaddr->count = 32; 2562 ccw->flags |= CCW_FLAG_SLI;
1903 cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; 2563 ccw->count = 32;
2564 ccw->cda = (__u32)(addr_t) cqr->data;
1904 cqr->startdev = device; 2565 cqr->startdev = device;
1905 cqr->memdev = device; 2566 cqr->memdev = device;
1906 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); 2567 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
@@ -1927,6 +2588,7 @@ dasd_eckd_reserve(struct dasd_device *device)
1927{ 2588{
1928 struct dasd_ccw_req *cqr; 2589 struct dasd_ccw_req *cqr;
1929 int rc; 2590 int rc;
2591 struct ccw1 *ccw;
1930 2592
1931 if (!capable(CAP_SYS_ADMIN)) 2593 if (!capable(CAP_SYS_ADMIN))
1932 return -EACCES; 2594 return -EACCES;
@@ -1938,10 +2600,11 @@ dasd_eckd_reserve(struct dasd_device *device)
1938 "Could not allocate initialization request"); 2600 "Could not allocate initialization request");
1939 return PTR_ERR(cqr); 2601 return PTR_ERR(cqr);
1940 } 2602 }
1941 cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RESERVE; 2603 ccw = cqr->cpaddr;
1942 cqr->cpaddr->flags |= CCW_FLAG_SLI; 2604 ccw->cmd_code = DASD_ECKD_CCW_RESERVE;
1943 cqr->cpaddr->count = 32; 2605 ccw->flags |= CCW_FLAG_SLI;
1944 cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; 2606 ccw->count = 32;
2607 ccw->cda = (__u32)(addr_t) cqr->data;
1945 cqr->startdev = device; 2608 cqr->startdev = device;
1946 cqr->memdev = device; 2609 cqr->memdev = device;
1947 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); 2610 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
@@ -1967,6 +2630,7 @@ dasd_eckd_steal_lock(struct dasd_device *device)
1967{ 2630{
1968 struct dasd_ccw_req *cqr; 2631 struct dasd_ccw_req *cqr;
1969 int rc; 2632 int rc;
2633 struct ccw1 *ccw;
1970 2634
1971 if (!capable(CAP_SYS_ADMIN)) 2635 if (!capable(CAP_SYS_ADMIN))
1972 return -EACCES; 2636 return -EACCES;
@@ -1978,10 +2642,11 @@ dasd_eckd_steal_lock(struct dasd_device *device)
1978 "Could not allocate initialization request"); 2642 "Could not allocate initialization request");
1979 return PTR_ERR(cqr); 2643 return PTR_ERR(cqr);
1980 } 2644 }
1981 cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SLCK; 2645 ccw = cqr->cpaddr;
1982 cqr->cpaddr->flags |= CCW_FLAG_SLI; 2646 ccw->cmd_code = DASD_ECKD_CCW_SLCK;
1983 cqr->cpaddr->count = 32; 2647 ccw->flags |= CCW_FLAG_SLI;
1984 cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; 2648 ccw->count = 32;
2649 ccw->cda = (__u32)(addr_t) cqr->data;
1985 cqr->startdev = device; 2650 cqr->startdev = device;
1986 cqr->memdev = device; 2651 cqr->memdev = device;
1987 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); 2652 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
@@ -2271,7 +2936,7 @@ dasd_eckd_dump_ccw_range(struct ccw1 *from, struct ccw1 *to, char *page)
2271 * Print sense data and related channel program. 2936 * Print sense data and related channel program.
2272 * Parts are printed because printk buffer is only 1024 bytes. 2937 * Parts are printed because printk buffer is only 1024 bytes.
2273 */ 2938 */
2274static void dasd_eckd_dump_sense(struct dasd_device *device, 2939static void dasd_eckd_dump_sense_ccw(struct dasd_device *device,
2275 struct dasd_ccw_req *req, struct irb *irb) 2940 struct dasd_ccw_req *req, struct irb *irb)
2276{ 2941{
2277 char *page; 2942 char *page;
@@ -2290,7 +2955,7 @@ static void dasd_eckd_dump_sense(struct dasd_device *device,
2290 dev_name(&device->cdev->dev)); 2955 dev_name(&device->cdev->dev));
2291 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 2956 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
2292 " in req: %p CS: 0x%02X DS: 0x%02X\n", req, 2957 " in req: %p CS: 0x%02X DS: 0x%02X\n", req,
2293 irb->scsw.cmd.cstat, irb->scsw.cmd.dstat); 2958 scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw));
2294 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 2959 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
2295 " device %s: Failing CCW: %p\n", 2960 " device %s: Failing CCW: %p\n",
2296 dev_name(&device->cdev->dev), 2961 dev_name(&device->cdev->dev),
@@ -2366,6 +3031,147 @@ static void dasd_eckd_dump_sense(struct dasd_device *device,
2366 free_page((unsigned long) page); 3031 free_page((unsigned long) page);
2367} 3032}
2368 3033
3034
3035/*
3036 * Print sense data from a tcw.
3037 */
3038static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
3039 struct dasd_ccw_req *req, struct irb *irb)
3040{
3041 char *page;
3042 int len, sl, sct, residual;
3043
3044 struct tsb *tsb;
3045 u8 *sense;
3046
3047
3048 page = (char *) get_zeroed_page(GFP_ATOMIC);
3049 if (page == NULL) {
3050 DEV_MESSAGE(KERN_ERR, device, " %s",
3051 "No memory to dump sense data");
3052 return;
3053 }
3054 /* dump the sense data */
3055 len = sprintf(page, KERN_ERR PRINTK_HEADER
3056 " I/O status report for device %s:\n",
3057 dev_name(&device->cdev->dev));
3058 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3059 " in req: %p CS: 0x%02X DS: 0x%02X "
3060 "fcxs: 0x%02X schxs: 0x%02X\n", req,
3061 scsw_cstat(&irb->scsw), scsw_dstat(&irb->scsw),
3062 irb->scsw.tm.fcxs, irb->scsw.tm.schxs);
3063 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3064 " device %s: Failing TCW: %p\n",
3065 dev_name(&device->cdev->dev),
3066 (void *) (addr_t) irb->scsw.tm.tcw);
3067
3068 tsb = NULL;
3069 sense = NULL;
3070 if (irb->scsw.tm.tcw)
3071 tsb = tcw_get_tsb(
3072 (struct tcw *)(unsigned long)irb->scsw.tm.tcw);
3073
3074 if (tsb && (irb->scsw.tm.fcxs == 0x01)) {
3075 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3076 " tsb->length %d\n", tsb->length);
3077 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3078 " tsb->flags %x\n", tsb->flags);
3079 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3080 " tsb->dcw_offset %d\n", tsb->dcw_offset);
3081 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3082 " tsb->count %d\n", tsb->count);
3083 residual = tsb->count - 28;
3084 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3085 " residual %d\n", residual);
3086
3087 switch (tsb->flags & 0x07) {
3088 case 1: /* tsa_iostat */
3089 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3090 " tsb->tsa.iostat.dev_time %d\n",
3091 tsb->tsa.iostat.dev_time);
3092 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3093 " tsb->tsa.iostat.def_time %d\n",
3094 tsb->tsa.iostat.def_time);
3095 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3096 " tsb->tsa.iostat.queue_time %d\n",
3097 tsb->tsa.iostat.queue_time);
3098 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3099 " tsb->tsa.iostat.dev_busy_time %d\n",
3100 tsb->tsa.iostat.dev_busy_time);
3101 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3102 " tsb->tsa.iostat.dev_act_time %d\n",
3103 tsb->tsa.iostat.dev_act_time);
3104 sense = tsb->tsa.iostat.sense;
3105 break;
3106 case 2: /* ts_ddpc */
3107 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3108 " tsb->tsa.ddpc.rc %d\n", tsb->tsa.ddpc.rc);
3109 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3110 " tsb->tsa.ddpc.rcq: ");
3111 for (sl = 0; sl < 16; sl++) {
3112 for (sct = 0; sct < 8; sct++) {
3113 len += sprintf(page + len, " %02x",
3114 tsb->tsa.ddpc.rcq[sl]);
3115 }
3116 len += sprintf(page + len, "\n");
3117 }
3118 sense = tsb->tsa.ddpc.sense;
3119 break;
3120 case 3: /* tsa_intrg */
3121 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
3122 " tsb->tsa.intrg.: not supportet yet \n");
3123 break;
3124 }
3125
3126 if (sense) {
3127 for (sl = 0; sl < 4; sl++) {
3128 len += sprintf(page + len,
3129 KERN_ERR PRINTK_HEADER
3130 " Sense(hex) %2d-%2d:",
3131 (8 * sl), ((8 * sl) + 7));
3132 for (sct = 0; sct < 8; sct++) {
3133 len += sprintf(page + len, " %02x",
3134 sense[8 * sl + sct]);
3135 }
3136 len += sprintf(page + len, "\n");
3137 }
3138
3139 if (sense[27] & DASD_SENSE_BIT_0) {
3140 /* 24 Byte Sense Data */
3141 sprintf(page + len, KERN_ERR PRINTK_HEADER
3142 " 24 Byte: %x MSG %x, "
3143 "%s MSGb to SYSOP\n",
3144 sense[7] >> 4, sense[7] & 0x0f,
3145 sense[1] & 0x10 ? "" : "no");
3146 } else {
3147 /* 32 Byte Sense Data */
3148 sprintf(page + len, KERN_ERR PRINTK_HEADER
3149 " 32 Byte: Format: %x "
3150 "Exception class %x\n",
3151 sense[6] & 0x0f, sense[22] >> 4);
3152 }
3153 } else {
3154 sprintf(page + len, KERN_ERR PRINTK_HEADER
3155 " SORRY - NO VALID SENSE AVAILABLE\n");
3156 }
3157 } else {
3158 sprintf(page + len, KERN_ERR PRINTK_HEADER
3159 " SORRY - NO TSB DATA AVAILABLE\n");
3160 }
3161 printk("%s", page);
3162 free_page((unsigned long) page);
3163}
3164
3165static void dasd_eckd_dump_sense(struct dasd_device *device,
3166 struct dasd_ccw_req *req, struct irb *irb)
3167{
3168 if (req && scsw_is_tm(&req->irb.scsw))
3169 dasd_eckd_dump_sense_tcw(device, req, irb);
3170 else
3171 dasd_eckd_dump_sense_ccw(device, req, irb);
3172}
3173
3174
2369/* 3175/*
2370 * max_blocks is dependent on the amount of storage that is available 3176 * max_blocks is dependent on the amount of storage that is available
2371 * in the static io buffer for each device. Currently each device has 3177 * in the static io buffer for each device. Currently each device has
diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h
index eecfa776db15..ad45bcac3ce4 100644
--- a/drivers/s390/block/dasd_eckd.h
+++ b/drivers/s390/block/dasd_eckd.h
@@ -38,8 +38,11 @@
38#define DASD_ECKD_CCW_RELEASE 0x94 38#define DASD_ECKD_CCW_RELEASE 0x94
39#define DASD_ECKD_CCW_READ_CKD_MT 0x9e 39#define DASD_ECKD_CCW_READ_CKD_MT 0x9e
40#define DASD_ECKD_CCW_WRITE_CKD_MT 0x9d 40#define DASD_ECKD_CCW_WRITE_CKD_MT 0x9d
41#define DASD_ECKD_CCW_WRITE_TRACK_DATA 0xA5
42#define DASD_ECKD_CCW_READ_TRACK_DATA 0xA6
41#define DASD_ECKD_CCW_RESERVE 0xB4 43#define DASD_ECKD_CCW_RESERVE 0xB4
42#define DASD_ECKD_CCW_PFX 0xE7 44#define DASD_ECKD_CCW_PFX 0xE7
45#define DASD_ECKD_CCW_PFX_READ 0xEA
43#define DASD_ECKD_CCW_RSCK 0xF9 46#define DASD_ECKD_CCW_RSCK 0xF9
44 47
45/* 48/*
@@ -123,7 +126,9 @@ struct DE_eckd_data {
123 unsigned long long ep_sys_time; /* Ext Parameter - System Time Stamp */ 126 unsigned long long ep_sys_time; /* Ext Parameter - System Time Stamp */
124 __u8 ep_format; /* Extended Parameter format byte */ 127 __u8 ep_format; /* Extended Parameter format byte */
125 __u8 ep_prio; /* Extended Parameter priority I/O byte */ 128 __u8 ep_prio; /* Extended Parameter priority I/O byte */
126 __u8 ep_reserved[6]; /* Extended Parameter Reserved */ 129 __u8 ep_reserved1; /* Extended Parameter Reserved */
130 __u8 ep_rec_per_track; /* Number of records on a track */
131 __u8 ep_reserved[4]; /* Extended Parameter Reserved */
127} __attribute__ ((packed)); 132} __attribute__ ((packed));
128 133
129struct LO_eckd_data { 134struct LO_eckd_data {
@@ -144,11 +149,37 @@ struct LO_eckd_data {
144 __u16 length; 149 __u16 length;
145} __attribute__ ((packed)); 150} __attribute__ ((packed));
146 151
152struct LRE_eckd_data {
153 struct {
154 unsigned char orientation:2;
155 unsigned char operation:6;
156 } __attribute__ ((packed)) operation;
157 struct {
158 unsigned char length_valid:1;
159 unsigned char length_scope:1;
160 unsigned char imbedded_ccw_valid:1;
161 unsigned char check_bytes:2;
162 unsigned char imbedded_count_valid:1;
163 unsigned char reserved:1;
164 unsigned char read_count_suffix:1;
165 } __attribute__ ((packed)) auxiliary;
166 __u8 imbedded_ccw;
167 __u8 count;
168 struct ch_t seek_addr;
169 struct chr_t search_arg;
170 __u8 sector;
171 __u16 length;
172 __u8 imbedded_count;
173 __u8 extended_operation;
174 __u16 extended_parameter_length;
175 __u8 extended_parameter[0];
176} __attribute__ ((packed));
177
147/* Prefix data for format 0x00 and 0x01 */ 178/* Prefix data for format 0x00 and 0x01 */
148struct PFX_eckd_data { 179struct PFX_eckd_data {
149 unsigned char format; 180 unsigned char format;
150 struct { 181 struct {
151 unsigned char define_extend:1; 182 unsigned char define_extent:1;
152 unsigned char time_stamp:1; 183 unsigned char time_stamp:1;
153 unsigned char verify_base:1; 184 unsigned char verify_base:1;
154 unsigned char hyper_pav:1; 185 unsigned char hyper_pav:1;
@@ -158,9 +189,8 @@ struct PFX_eckd_data {
158 __u8 aux; 189 __u8 aux;
159 __u8 base_lss; 190 __u8 base_lss;
160 __u8 reserved[7]; 191 __u8 reserved[7];
161 struct DE_eckd_data define_extend; 192 struct DE_eckd_data define_extent;
162 struct LO_eckd_data locate_record; 193 struct LRE_eckd_data locate_record;
163 __u8 LO_extended_data[4];
164} __attribute__ ((packed)); 194} __attribute__ ((packed));
165 195
166struct dasd_eckd_characteristics { 196struct dasd_eckd_characteristics {
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c
index f8e05ce98621..9ce4209552ae 100644
--- a/drivers/s390/block/dasd_eer.c
+++ b/drivers/s390/block/dasd_eer.c
@@ -297,11 +297,12 @@ static void dasd_eer_write_standard_trigger(struct dasd_device *device,
297 struct dasd_eer_header header; 297 struct dasd_eer_header header;
298 unsigned long flags; 298 unsigned long flags;
299 struct eerbuffer *eerb; 299 struct eerbuffer *eerb;
300 char *sense;
300 301
301 /* go through cqr chain and count the valid sense data sets */ 302 /* go through cqr chain and count the valid sense data sets */
302 data_size = 0; 303 data_size = 0;
303 for (temp_cqr = cqr; temp_cqr; temp_cqr = temp_cqr->refers) 304 for (temp_cqr = cqr; temp_cqr; temp_cqr = temp_cqr->refers)
304 if (temp_cqr->irb.esw.esw0.erw.cons) 305 if (dasd_get_sense(&temp_cqr->irb))
305 data_size += 32; 306 data_size += 32;
306 307
307 header.total_size = sizeof(header) + data_size + 4; /* "EOR" */ 308 header.total_size = sizeof(header) + data_size + 4; /* "EOR" */
@@ -316,9 +317,11 @@ static void dasd_eer_write_standard_trigger(struct dasd_device *device,
316 list_for_each_entry(eerb, &bufferlist, list) { 317 list_for_each_entry(eerb, &bufferlist, list) {
317 dasd_eer_start_record(eerb, header.total_size); 318 dasd_eer_start_record(eerb, header.total_size);
318 dasd_eer_write_buffer(eerb, (char *) &header, sizeof(header)); 319 dasd_eer_write_buffer(eerb, (char *) &header, sizeof(header));
319 for (temp_cqr = cqr; temp_cqr; temp_cqr = temp_cqr->refers) 320 for (temp_cqr = cqr; temp_cqr; temp_cqr = temp_cqr->refers) {
320 if (temp_cqr->irb.esw.esw0.erw.cons) 321 sense = dasd_get_sense(&temp_cqr->irb);
321 dasd_eer_write_buffer(eerb, cqr->irb.ecw, 32); 322 if (sense)
323 dasd_eer_write_buffer(eerb, sense, 32);
324 }
322 dasd_eer_write_buffer(eerb, "EOR", 4); 325 dasd_eer_write_buffer(eerb, "EOR", 4);
323 } 326 }
324 spin_unlock_irqrestore(&bufferlock, flags); 327 spin_unlock_irqrestore(&bufferlock, flags);
@@ -451,6 +454,7 @@ int dasd_eer_enable(struct dasd_device *device)
451{ 454{
452 struct dasd_ccw_req *cqr; 455 struct dasd_ccw_req *cqr;
453 unsigned long flags; 456 unsigned long flags;
457 struct ccw1 *ccw;
454 458
455 if (device->eer_cqr) 459 if (device->eer_cqr)
456 return 0; 460 return 0;
@@ -468,10 +472,11 @@ int dasd_eer_enable(struct dasd_device *device)
468 cqr->expires = 10 * HZ; 472 cqr->expires = 10 * HZ;
469 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); 473 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
470 474
471 cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SNSS; 475 ccw = cqr->cpaddr;
472 cqr->cpaddr->count = SNSS_DATA_SIZE; 476 ccw->cmd_code = DASD_ECKD_CCW_SNSS;
473 cqr->cpaddr->flags = 0; 477 ccw->count = SNSS_DATA_SIZE;
474 cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; 478 ccw->flags = 0;
479 ccw->cda = (__u32)(addr_t) cqr->data;
475 480
476 cqr->buildclk = get_clock(); 481 cqr->buildclk = get_clock();
477 cqr->status = DASD_CQR_FILLED; 482 cqr->status = DASD_CQR_FILLED;
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 29991a9fa07a..7b314c1d471e 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -157,7 +157,8 @@ struct dasd_ccw_req {
157 struct dasd_block *block; /* the originating block device */ 157 struct dasd_block *block; /* the originating block device */
158 struct dasd_device *memdev; /* the device used to allocate this */ 158 struct dasd_device *memdev; /* the device used to allocate this */
159 struct dasd_device *startdev; /* device the request is started on */ 159 struct dasd_device *startdev; /* device the request is started on */
160 struct ccw1 *cpaddr; /* address of channel program */ 160 void *cpaddr; /* address of ccw or tcw */
161 unsigned char cpmode; /* 0 = cmd mode, 1 = itcw */
161 char status; /* status of this request */ 162 char status; /* status of this request */
162 short retries; /* A retry counter */ 163 short retries; /* A retry counter */
163 unsigned long flags; /* flags of this request */ 164 unsigned long flags; /* flags of this request */
@@ -573,12 +574,14 @@ int dasd_generic_notify(struct ccw_device *, int);
573void dasd_generic_handle_state_change(struct dasd_device *); 574void dasd_generic_handle_state_change(struct dasd_device *);
574 575
575int dasd_generic_read_dev_chars(struct dasd_device *, char *, void **, int); 576int dasd_generic_read_dev_chars(struct dasd_device *, char *, void **, int);
577char *dasd_get_sense(struct irb *);
576 578
577/* externals in dasd_devmap.c */ 579/* externals in dasd_devmap.c */
578extern int dasd_max_devindex; 580extern int dasd_max_devindex;
579extern int dasd_probeonly; 581extern int dasd_probeonly;
580extern int dasd_autodetect; 582extern int dasd_autodetect;
581extern int dasd_nopav; 583extern int dasd_nopav;
584extern int dasd_nofcx;
582 585
583int dasd_devmap_init(void); 586int dasd_devmap_init(void);
584void dasd_devmap_exit(void); 587void dasd_devmap_exit(void);