1 /* 2 * File...........: linux/drivers/s390/block/dasd_eckd.c 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 4 * Horst Hummel <Horst.Hummel@de.ibm.com> 5 * Carsten Otte <Cotte@de.ibm.com> 6 * Martin Schwidefsky <schwidefsky@de.ibm.com> 7 * Bugreports.to..: <Linux390@de.ibm.com> 8 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 9 * 10 * $Revision: 1.74 $ 11 */ 12 13 #include <linux/config.h> 14 #include <linux/stddef.h> 15 #include <linux/kernel.h> 16 #include <linux/slab.h> 17 #include <linux/hdreg.h> /* HDIO_GETGEO */ 18 #include <linux/bio.h> 19 #include <linux/module.h> 20 #include <linux/init.h> 21 22 #include <asm/debug.h> 23 #include <asm/idals.h> 24 #include <asm/ebcdic.h> 25 #include <asm/io.h> 26 #include <asm/todclk.h> 27 #include <asm/uaccess.h> 28 #include <asm/ccwdev.h> 29 30 #include "dasd_int.h" 31 #include "dasd_eckd.h" 32 33 #ifdef PRINTK_HEADER 34 #undef PRINTK_HEADER 35 #endif /* PRINTK_HEADER */ 36 #define PRINTK_HEADER "dasd(eckd):" 37 38 #define ECKD_C0(i) (i->home_bytes) 39 #define ECKD_F(i) (i->formula) 40 #define ECKD_F1(i) (ECKD_F(i)==0x01?(i->factors.f_0x01.f1):\ 41 (i->factors.f_0x02.f1)) 42 #define ECKD_F2(i) (ECKD_F(i)==0x01?(i->factors.f_0x01.f2):\ 43 (i->factors.f_0x02.f2)) 44 #define ECKD_F3(i) (ECKD_F(i)==0x01?(i->factors.f_0x01.f3):\ 45 (i->factors.f_0x02.f3)) 46 #define ECKD_F4(i) (ECKD_F(i)==0x02?(i->factors.f_0x02.f4):0) 47 #define ECKD_F5(i) (ECKD_F(i)==0x02?(i->factors.f_0x02.f5):0) 48 #define ECKD_F6(i) (i->factor6) 49 #define ECKD_F7(i) (i->factor7) 50 #define ECKD_F8(i) (i->factor8) 51 52 MODULE_LICENSE("GPL"); 53 54 static struct dasd_discipline dasd_eckd_discipline; 55 56 struct dasd_eckd_private { 57 struct dasd_eckd_characteristics rdc_data; 58 struct dasd_eckd_confdata conf_data; 59 struct dasd_eckd_path path_data; 60 struct eckd_count count_area[5]; 61 int init_cqr_status; 62 int uses_cdl; 63 struct attrib_data_t attrib; /* e.g. cache operations */ 64 }; 65 66 /* The ccw bus type uses this table to find devices that it sends to 67 * dasd_eckd_probe */ 68 static struct ccw_device_id dasd_eckd_ids[] = { 69 { CCW_DEVICE_DEVTYPE (0x3990, 0, 0x3390, 0), driver_info: 0x1}, 70 { CCW_DEVICE_DEVTYPE (0x2105, 0, 0x3390, 0), driver_info: 0x2}, 71 { CCW_DEVICE_DEVTYPE (0x3880, 0, 0x3390, 0), driver_info: 0x3}, 72 { CCW_DEVICE_DEVTYPE (0x3990, 0, 0x3380, 0), driver_info: 0x4}, 73 { CCW_DEVICE_DEVTYPE (0x2105, 0, 0x3380, 0), driver_info: 0x5}, 74 { CCW_DEVICE_DEVTYPE (0x9343, 0, 0x9345, 0), driver_info: 0x6}, 75 { CCW_DEVICE_DEVTYPE (0x2107, 0, 0x3390, 0), driver_info: 0x7}, 76 { CCW_DEVICE_DEVTYPE (0x2107, 0, 0x3380, 0), driver_info: 0x8}, 77 { CCW_DEVICE_DEVTYPE (0x1750, 0, 0x3390, 0), driver_info: 0x9}, 78 { CCW_DEVICE_DEVTYPE (0x1750, 0, 0x3380, 0), driver_info: 0xa}, 79 { /* end of list */ }, 80 }; 81 82 MODULE_DEVICE_TABLE(ccw, dasd_eckd_ids); 83 84 static struct ccw_driver dasd_eckd_driver; /* see below */ 85 86 /* initial attempt at a probe function. this can be simplified once 87 * the other detection code is gone */ 88 static int 89 dasd_eckd_probe (struct ccw_device *cdev) 90 { 91 int ret; 92 93 ret = dasd_generic_probe (cdev, &dasd_eckd_discipline); 94 if (ret) 95 return ret; 96 ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP | CCWDEV_ALLOW_FORCE); 97 return 0; 98 } 99 100 static int 101 dasd_eckd_set_online(struct ccw_device *cdev) 102 { 103 return dasd_generic_set_online (cdev, &dasd_eckd_discipline); 104 } 105 106 static struct ccw_driver dasd_eckd_driver = { 107 .name = "dasd-eckd", 108 .owner = THIS_MODULE, 109 .ids = dasd_eckd_ids, 110 .probe = dasd_eckd_probe, 111 .remove = dasd_generic_remove, 112 .set_offline = dasd_generic_set_offline, 113 .set_online = dasd_eckd_set_online, 114 .notify = dasd_generic_notify, 115 }; 116 117 static const int sizes_trk0[] = { 28, 148, 84 }; 118 #define LABEL_SIZE 140 119 120 static inline unsigned int 121 round_up_multiple(unsigned int no, unsigned int mult) 122 { 123 int rem = no % mult; 124 return (rem ? no - rem + mult : no); 125 } 126 127 static inline unsigned int 128 ceil_quot(unsigned int d1, unsigned int d2) 129 { 130 return (d1 + (d2 - 1)) / d2; 131 } 132 133 static inline int 134 bytes_per_record(struct dasd_eckd_characteristics *rdc, int kl, int dl) 135 { 136 unsigned int fl1, fl2, int1, int2; 137 int bpr; 138 139 switch (rdc->formula) { 140 case 0x01: 141 fl1 = round_up_multiple(ECKD_F2(rdc) + dl, ECKD_F1(rdc)); 142 fl2 = round_up_multiple(kl ? ECKD_F2(rdc) + kl : 0, 143 ECKD_F1(rdc)); 144 bpr = fl1 + fl2; 145 break; 146 case 0x02: 147 int1 = ceil_quot(dl + ECKD_F6(rdc), ECKD_F5(rdc) << 1); 148 int2 = ceil_quot(kl + ECKD_F6(rdc), ECKD_F5(rdc) << 1); 149 fl1 = round_up_multiple(ECKD_F1(rdc) * ECKD_F2(rdc) + dl + 150 ECKD_F6(rdc) + ECKD_F4(rdc) * int1, 151 ECKD_F1(rdc)); 152 fl2 = round_up_multiple(ECKD_F1(rdc) * ECKD_F3(rdc) + kl + 153 ECKD_F6(rdc) + ECKD_F4(rdc) * int2, 154 ECKD_F1(rdc)); 155 bpr = fl1 + fl2; 156 break; 157 default: 158 bpr = 0; 159 break; 160 } 161 return bpr; 162 } 163 164 static inline unsigned int 165 bytes_per_track(struct dasd_eckd_characteristics *rdc) 166 { 167 return *(unsigned int *) (rdc->byte_per_track) >> 8; 168 } 169 170 static inline unsigned int 171 recs_per_track(struct dasd_eckd_characteristics * rdc, 172 unsigned int kl, unsigned int dl) 173 { 174 int dn, kn; 175 176 switch (rdc->dev_type) { 177 case 0x3380: 178 if (kl) 179 return 1499 / (15 + 7 + ceil_quot(kl + 12, 32) + 180 ceil_quot(dl + 12, 32)); 181 else 182 return 1499 / (15 + ceil_quot(dl + 12, 32)); 183 case 0x3390: 184 dn = ceil_quot(dl + 6, 232) + 1; 185 if (kl) { 186 kn = ceil_quot(kl + 6, 232) + 1; 187 return 1729 / (10 + 9 + ceil_quot(kl + 6 * kn, 34) + 188 9 + ceil_quot(dl + 6 * dn, 34)); 189 } else 190 return 1729 / (10 + 9 + ceil_quot(dl + 6 * dn, 34)); 191 case 0x9345: 192 dn = ceil_quot(dl + 6, 232) + 1; 193 if (kl) { 194 kn = ceil_quot(kl + 6, 232) + 1; 195 return 1420 / (18 + 7 + ceil_quot(kl + 6 * kn, 34) + 196 ceil_quot(dl + 6 * dn, 34)); 197 } else 198 return 1420 / (18 + 7 + ceil_quot(dl + 6 * dn, 34)); 199 } 200 return 0; 201 } 202 203 static inline void 204 check_XRC (struct ccw1 *de_ccw, 205 struct DE_eckd_data *data, 206 struct dasd_device *device) 207 { 208 struct dasd_eckd_private *private; 209 210 private = (struct dasd_eckd_private *) device->private; 211 212 /* switch on System Time Stamp - needed for XRC Support */ 213 if (private->rdc_data.facilities.XRC_supported) { 214 215 data->ga_extended |= 0x08; /* switch on 'Time Stamp Valid' */ 216 data->ga_extended |= 0x02; /* switch on 'Extended Parameter' */ 217 218 data->ep_sys_time = get_clock (); 219 220 de_ccw->count = sizeof (struct DE_eckd_data); 221 de_ccw->flags |= CCW_FLAG_SLI; 222 } 223 224 return; 225 226 } /* end check_XRC */ 227 228 static inline void 229 define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk, 230 int totrk, int cmd, struct dasd_device * device) 231 { 232 struct dasd_eckd_private *private; 233 struct ch_t geo, beg, end; 234 235 private = (struct dasd_eckd_private *) device->private; 236 237 ccw->cmd_code = DASD_ECKD_CCW_DEFINE_EXTENT; 238 ccw->flags = 0; 239 ccw->count = 16; 240 ccw->cda = (__u32) __pa(data); 241 242 memset(data, 0, sizeof (struct DE_eckd_data)); 243 switch (cmd) { 244 case DASD_ECKD_CCW_READ_HOME_ADDRESS: 245 case DASD_ECKD_CCW_READ_RECORD_ZERO: 246 case DASD_ECKD_CCW_READ: 247 case DASD_ECKD_CCW_READ_MT: 248 case DASD_ECKD_CCW_READ_CKD: 249 case DASD_ECKD_CCW_READ_CKD_MT: 250 case DASD_ECKD_CCW_READ_KD: 251 case DASD_ECKD_CCW_READ_KD_MT: 252 case DASD_ECKD_CCW_READ_COUNT: 253 data->mask.perm = 0x1; 254 data->attributes.operation = private->attrib.operation; 255 break; 256 case DASD_ECKD_CCW_WRITE: 257 case DASD_ECKD_CCW_WRITE_MT: 258 case DASD_ECKD_CCW_WRITE_KD: 259 case DASD_ECKD_CCW_WRITE_KD_MT: 260 data->mask.perm = 0x02; 261 data->attributes.operation = private->attrib.operation; 262 check_XRC (ccw, data, device); 263 break; 264 case DASD_ECKD_CCW_WRITE_CKD: 265 case DASD_ECKD_CCW_WRITE_CKD_MT: 266 data->attributes.operation = DASD_BYPASS_CACHE; 267 check_XRC (ccw, data, device); 268 break; 269 case DASD_ECKD_CCW_ERASE: 270 case DASD_ECKD_CCW_WRITE_HOME_ADDRESS: 271 case DASD_ECKD_CCW_WRITE_RECORD_ZERO: 272 data->mask.perm = 0x3; 273 data->mask.auth = 0x1; 274 data->attributes.operation = DASD_BYPASS_CACHE; 275 check_XRC (ccw, data, device); 276 break; 277 default: 278 DEV_MESSAGE(KERN_ERR, device, "unknown opcode 0x%x", cmd); 279 break; 280 } 281 282 data->attributes.mode = 0x3; /* ECKD */ 283 284 if ((private->rdc_data.cu_type == 0x2105 || 285 private->rdc_data.cu_type == 0x2107 || 286 private->rdc_data.cu_type == 0x1750) 287 && !(private->uses_cdl && trk < 2)) 288 data->ga_extended |= 0x40; /* Regular Data Format Mode */ 289 290 geo.cyl = private->rdc_data.no_cyl; 291 geo.head = private->rdc_data.trk_per_cyl; 292 beg.cyl = trk / geo.head; 293 beg.head = trk % geo.head; 294 end.cyl = totrk / geo.head; 295 end.head = totrk % geo.head; 296 297 /* check for sequential prestage - enhance cylinder range */ 298 if (data->attributes.operation == DASD_SEQ_PRESTAGE || 299 data->attributes.operation == DASD_SEQ_ACCESS) { 300 301 if (end.cyl + private->attrib.nr_cyl < geo.cyl) 302 end.cyl += private->attrib.nr_cyl; 303 else 304 end.cyl = (geo.cyl - 1); 305 } 306 307 data->beg_ext.cyl = beg.cyl; 308 data->beg_ext.head = beg.head; 309 data->end_ext.cyl = end.cyl; 310 data->end_ext.head = end.head; 311 } 312 313 static inline void 314 locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, int trk, 315 int rec_on_trk, int no_rec, int cmd, 316 struct dasd_device * device, int reclen) 317 { 318 struct dasd_eckd_private *private; 319 int sector; 320 int dn, d; 321 322 private = (struct dasd_eckd_private *) device->private; 323 324 DBF_DEV_EVENT(DBF_INFO, device, 325 "Locate: trk %d, rec %d, no_rec %d, cmd %d, reclen %d", 326 trk, rec_on_trk, no_rec, cmd, reclen); 327 328 ccw->cmd_code = DASD_ECKD_CCW_LOCATE_RECORD; 329 ccw->flags = 0; 330 ccw->count = 16; 331 ccw->cda = (__u32) __pa(data); 332 333 memset(data, 0, sizeof (struct LO_eckd_data)); 334 sector = 0; 335 if (rec_on_trk) { 336 switch (private->rdc_data.dev_type) { 337 case 0x3390: 338 dn = ceil_quot(reclen + 6, 232); 339 d = 9 + ceil_quot(reclen + 6 * (dn + 1), 34); 340 sector = (49 + (rec_on_trk - 1) * (10 + d)) / 8; 341 break; 342 case 0x3380: 343 d = 7 + ceil_quot(reclen + 12, 32); 344 sector = (39 + (rec_on_trk - 1) * (8 + d)) / 7; 345 break; 346 } 347 } 348 data->sector = sector; 349 data->count = no_rec; 350 switch (cmd) { 351 case DASD_ECKD_CCW_WRITE_HOME_ADDRESS: 352 data->operation.orientation = 0x3; 353 data->operation.operation = 0x03; 354 break; 355 case DASD_ECKD_CCW_READ_HOME_ADDRESS: 356 data->operation.orientation = 0x3; 357 data->operation.operation = 0x16; 358 break; 359 case DASD_ECKD_CCW_WRITE_RECORD_ZERO: 360 data->operation.orientation = 0x1; 361 data->operation.operation = 0x03; 362 data->count++; 363 break; 364 case DASD_ECKD_CCW_READ_RECORD_ZERO: 365 data->operation.orientation = 0x3; 366 data->operation.operation = 0x16; 367 data->count++; 368 break; 369 case DASD_ECKD_CCW_WRITE: 370 case DASD_ECKD_CCW_WRITE_MT: 371 case DASD_ECKD_CCW_WRITE_KD: 372 case DASD_ECKD_CCW_WRITE_KD_MT: 373 data->auxiliary.last_bytes_used = 0x1; 374 data->length = reclen; 375 data->operation.operation = 0x01; 376 break; 377 case DASD_ECKD_CCW_WRITE_CKD: 378 case DASD_ECKD_CCW_WRITE_CKD_MT: 379 data->auxiliary.last_bytes_used = 0x1; 380 data->length = reclen; 381 data->operation.operation = 0x03; 382 break; 383 case DASD_ECKD_CCW_READ: 384 case DASD_ECKD_CCW_READ_MT: 385 case DASD_ECKD_CCW_READ_KD: 386 case DASD_ECKD_CCW_READ_KD_MT: 387 data->auxiliary.last_bytes_used = 0x1; 388 data->length = reclen; 389 data->operation.operation = 0x06; 390 break; 391 case DASD_ECKD_CCW_READ_CKD: 392 case DASD_ECKD_CCW_READ_CKD_MT: 393 data->auxiliary.last_bytes_used = 0x1; 394 data->length = reclen; 395 data->operation.operation = 0x16; 396 break; 397 case DASD_ECKD_CCW_READ_COUNT: 398 data->operation.operation = 0x06; 399 break; 400 case DASD_ECKD_CCW_ERASE: 401 data->length = reclen; 402 data->auxiliary.last_bytes_used = 0x1; 403 data->operation.operation = 0x0b; 404 break; 405 default: 406 DEV_MESSAGE(KERN_ERR, device, "unknown opcode 0x%x", cmd); 407 } 408 data->seek_addr.cyl = data->search_arg.cyl = 409 trk / private->rdc_data.trk_per_cyl; 410 data->seek_addr.head = data->search_arg.head = 411 trk % private->rdc_data.trk_per_cyl; 412 data->search_arg.record = rec_on_trk; 413 } 414 415 /* 416 * Returns 1 if the block is one of the special blocks that needs 417 * to get read/written with the KD variant of the command. 418 * That is DASD_ECKD_READ_KD_MT instead of DASD_ECKD_READ_MT and 419 * DASD_ECKD_WRITE_KD_MT instead of DASD_ECKD_WRITE_MT. 420 * Luckily the KD variants differ only by one bit (0x08) from the 421 * normal variant. So don't wonder about code like: 422 * if (dasd_eckd_cdl_special(blk_per_trk, recid)) 423 * ccw->cmd_code |= 0x8; 424 */ 425 static inline int 426 dasd_eckd_cdl_special(int blk_per_trk, int recid) 427 { 428 if (recid < 3) 429 return 1; 430 if (recid < blk_per_trk) 431 return 0; 432 if (recid < 2 * blk_per_trk) 433 return 1; 434 return 0; 435 } 436 437 /* 438 * Returns the record size for the special blocks of the cdl format. 439 * Only returns something useful if dasd_eckd_cdl_special is true 440 * for the recid. 441 */ 442 static inline int 443 dasd_eckd_cdl_reclen(int recid) 444 { 445 if (recid < 3) 446 return sizes_trk0[recid]; 447 return LABEL_SIZE; 448 } 449 450 static int 451 dasd_eckd_read_conf(struct dasd_device *device) 452 { 453 void *conf_data; 454 int conf_len, conf_data_saved; 455 int rc; 456 __u8 lpm; 457 struct dasd_eckd_private *private; 458 struct dasd_eckd_path *path_data; 459 460 private = (struct dasd_eckd_private *) device->private; 461 path_data = (struct dasd_eckd_path *) &private->path_data; 462 path_data->opm = ccw_device_get_path_mask(device->cdev); 463 lpm = 0x80; 464 conf_data_saved = 0; 465 466 /* get configuration data per operational path */ 467 for (lpm = 0x80; lpm; lpm>>= 1) { 468 if (lpm & path_data->opm){ 469 rc = read_conf_data_lpm(device->cdev, &conf_data, 470 &conf_len, lpm); 471 if (rc && rc != -EOPNOTSUPP) { /* -EOPNOTSUPP is ok */ 472 MESSAGE(KERN_WARNING, 473 "Read configuration data returned " 474 "error %d", rc); 475 return rc; 476 } 477 if (conf_data == NULL) { 478 MESSAGE(KERN_WARNING, "%s", "No configuration " 479 "data retrieved"); 480 continue; /* no errror */ 481 } 482 if (conf_len != sizeof (struct dasd_eckd_confdata)) { 483 MESSAGE(KERN_WARNING, 484 "sizes of configuration data mismatch" 485 "%d (read) vs %ld (expected)", 486 conf_len, 487 sizeof (struct dasd_eckd_confdata)); 488 kfree(conf_data); 489 continue; /* no errror */ 490 } 491 /* save first valid configuration data */ 492 if (!conf_data_saved){ 493 memcpy(&private->conf_data, conf_data, 494 sizeof (struct dasd_eckd_confdata)); 495 conf_data_saved++; 496 } 497 switch (((char *)conf_data)[242] & 0x07){ 498 case 0x02: 499 path_data->npm |= lpm; 500 break; 501 case 0x03: 502 path_data->ppm |= lpm; 503 break; 504 } 505 kfree(conf_data); 506 } 507 } 508 return 0; 509 } 510 511 512 static int 513 dasd_eckd_check_characteristics(struct dasd_device *device) 514 { 515 struct dasd_eckd_private *private; 516 void *rdc_data; 517 int rc; 518 519 private = (struct dasd_eckd_private *) device->private; 520 if (private == NULL) { 521 private = kmalloc(sizeof(struct dasd_eckd_private), 522 GFP_KERNEL | GFP_DMA); 523 if (private == NULL) { 524 DEV_MESSAGE(KERN_WARNING, device, "%s", 525 "memory allocation failed for private " 526 "data"); 527 return -ENOMEM; 528 } 529 memset(private, 0, sizeof(struct dasd_eckd_private)); 530 device->private = (void *) private; 531 } 532 /* Invalidate status of initial analysis. */ 533 private->init_cqr_status = -1; 534 /* Set default cache operations. */ 535 private->attrib.operation = DASD_NORMAL_CACHE; 536 private->attrib.nr_cyl = 0; 537 538 /* Read Device Characteristics */ 539 rdc_data = (void *) &(private->rdc_data); 540 rc = read_dev_chars(device->cdev, &rdc_data, 64); 541 if (rc) { 542 DEV_MESSAGE(KERN_WARNING, device, 543 "Read device characteristics returned error %d", 544 rc); 545 return rc; 546 } 547 548 DEV_MESSAGE(KERN_INFO, device, 549 "%04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d", 550 private->rdc_data.dev_type, 551 private->rdc_data.dev_model, 552 private->rdc_data.cu_type, 553 private->rdc_data.cu_model.model, 554 private->rdc_data.no_cyl, 555 private->rdc_data.trk_per_cyl, 556 private->rdc_data.sec_per_trk); 557 558 /* Read Configuration Data */ 559 rc = dasd_eckd_read_conf (device); 560 return rc; 561 562 } 563 564 static struct dasd_ccw_req * 565 dasd_eckd_analysis_ccw(struct dasd_device *device) 566 { 567 struct dasd_eckd_private *private; 568 struct eckd_count *count_data; 569 struct LO_eckd_data *LO_data; 570 struct dasd_ccw_req *cqr; 571 struct ccw1 *ccw; 572 int cplength, datasize; 573 int i; 574 575 private = (struct dasd_eckd_private *) device->private; 576 577 cplength = 8; 578 datasize = sizeof(struct DE_eckd_data) + 2*sizeof(struct LO_eckd_data); 579 cqr = dasd_smalloc_request(dasd_eckd_discipline.name, 580 cplength, datasize, device); 581 if (IS_ERR(cqr)) 582 return cqr; 583 ccw = cqr->cpaddr; 584 /* Define extent for the first 3 tracks. */ 585 define_extent(ccw++, cqr->data, 0, 2, 586 DASD_ECKD_CCW_READ_COUNT, device); 587 LO_data = cqr->data + sizeof (struct DE_eckd_data); 588 /* Locate record for the first 4 records on track 0. */ 589 ccw[-1].flags |= CCW_FLAG_CC; 590 locate_record(ccw++, LO_data++, 0, 0, 4, 591 DASD_ECKD_CCW_READ_COUNT, device, 0); 592 593 count_data = private->count_area; 594 for (i = 0; i < 4; i++) { 595 ccw[-1].flags |= CCW_FLAG_CC; 596 ccw->cmd_code = DASD_ECKD_CCW_READ_COUNT; 597 ccw->flags = 0; 598 ccw->count = 8; 599 ccw->cda = (__u32)(addr_t) count_data; 600 ccw++; 601 count_data++; 602 } 603 604 /* Locate record for the first record on track 2. */ 605 ccw[-1].flags |= CCW_FLAG_CC; 606 locate_record(ccw++, LO_data++, 2, 0, 1, 607 DASD_ECKD_CCW_READ_COUNT, device, 0); 608 /* Read count ccw. */ 609 ccw[-1].flags |= CCW_FLAG_CC; 610 ccw->cmd_code = DASD_ECKD_CCW_READ_COUNT; 611 ccw->flags = 0; 612 ccw->count = 8; 613 ccw->cda = (__u32)(addr_t) count_data; 614 615 cqr->device = device; 616 cqr->retries = 0; 617 cqr->buildclk = get_clock(); 618 cqr->status = DASD_CQR_FILLED; 619 return cqr; 620 } 621 622 /* 623 * This is the callback function for the init_analysis cqr. It saves 624 * the status of the initial analysis ccw before it frees it and kicks 625 * the device to continue the startup sequence. This will call 626 * dasd_eckd_do_analysis again (if the devices has not been marked 627 * for deletion in the meantime). 628 */ 629 static void 630 dasd_eckd_analysis_callback(struct dasd_ccw_req *init_cqr, void *data) 631 { 632 struct dasd_eckd_private *private; 633 struct dasd_device *device; 634 635 device = init_cqr->device; 636 private = (struct dasd_eckd_private *) device->private; 637 private->init_cqr_status = init_cqr->status; 638 dasd_sfree_request(init_cqr, device); 639 dasd_kick_device(device); 640 } 641 642 static int 643 dasd_eckd_start_analysis(struct dasd_device *device) 644 { 645 struct dasd_eckd_private *private; 646 struct dasd_ccw_req *init_cqr; 647 648 private = (struct dasd_eckd_private *) device->private; 649 init_cqr = dasd_eckd_analysis_ccw(device); 650 if (IS_ERR(init_cqr)) 651 return PTR_ERR(init_cqr); 652 init_cqr->callback = dasd_eckd_analysis_callback; 653 init_cqr->callback_data = NULL; 654 init_cqr->expires = 5*HZ; 655 dasd_add_request_head(init_cqr); 656 return -EAGAIN; 657 } 658 659 static int 660 dasd_eckd_end_analysis(struct dasd_device *device) 661 { 662 struct dasd_eckd_private *private; 663 struct eckd_count *count_area; 664 unsigned int sb, blk_per_trk; 665 int status, i; 666 667 private = (struct dasd_eckd_private *) device->private; 668 status = private->init_cqr_status; 669 private->init_cqr_status = -1; 670 if (status != DASD_CQR_DONE) { 671 DEV_MESSAGE(KERN_WARNING, device, "%s", 672 "volume analysis returned unformatted disk"); 673 return -EMEDIUMTYPE; 674 } 675 676 private->uses_cdl = 1; 677 /* Calculate number of blocks/records per track. */ 678 blk_per_trk = recs_per_track(&private->rdc_data, 0, device->bp_block); 679 /* Check Track 0 for Compatible Disk Layout */ 680 count_area = NULL; 681 for (i = 0; i < 3; i++) { 682 if (private->count_area[i].kl != 4 || 683 private->count_area[i].dl != dasd_eckd_cdl_reclen(i) - 4) { 684 private->uses_cdl = 0; 685 break; 686 } 687 } 688 if (i == 3) 689 count_area = &private->count_area[4]; 690 691 if (private->uses_cdl == 0) { 692 for (i = 0; i < 5; i++) { 693 if ((private->count_area[i].kl != 0) || 694 (private->count_area[i].dl != 695 private->count_area[0].dl)) 696 break; 697 } 698 if (i == 5) 699 count_area = &private->count_area[0]; 700 } else { 701 if (private->count_area[3].record == 1) 702 DEV_MESSAGE(KERN_WARNING, device, "%s", 703 "Trk 0: no records after VTOC!"); 704 } 705 if (count_area != NULL && count_area->kl == 0) { 706 /* we found notthing violating our disk layout */ 707 if (dasd_check_blocksize(count_area->dl) == 0) 708 device->bp_block = count_area->dl; 709 } 710 if (device->bp_block == 0) { 711 DEV_MESSAGE(KERN_WARNING, device, "%s", 712 "Volume has incompatible disk layout"); 713 return -EMEDIUMTYPE; 714 } 715 device->s2b_shift = 0; /* bits to shift 512 to get a block */ 716 for (sb = 512; sb < device->bp_block; sb = sb << 1) 717 device->s2b_shift++; 718 719 blk_per_trk = recs_per_track(&private->rdc_data, 0, device->bp_block); 720 device->blocks = (private->rdc_data.no_cyl * 721 private->rdc_data.trk_per_cyl * 722 blk_per_trk); 723 724 DEV_MESSAGE(KERN_INFO, device, 725 "(%dkB blks): %dkB at %dkB/trk %s", 726 (device->bp_block >> 10), 727 ((private->rdc_data.no_cyl * 728 private->rdc_data.trk_per_cyl * 729 blk_per_trk * (device->bp_block >> 9)) >> 1), 730 ((blk_per_trk * device->bp_block) >> 10), 731 private->uses_cdl ? 732 "compatible disk layout" : "linux disk layout"); 733 734 return 0; 735 } 736 737 static int 738 dasd_eckd_do_analysis(struct dasd_device *device) 739 { 740 struct dasd_eckd_private *private; 741 742 private = (struct dasd_eckd_private *) device->private; 743 if (private->init_cqr_status < 0) 744 return dasd_eckd_start_analysis(device); 745 else 746 return dasd_eckd_end_analysis(device); 747 } 748 749 static int 750 dasd_eckd_fill_geometry(struct dasd_device *device, struct hd_geometry *geo) 751 { 752 struct dasd_eckd_private *private; 753 754 private = (struct dasd_eckd_private *) device->private; 755 if (dasd_check_blocksize(device->bp_block) == 0) { 756 geo->sectors = recs_per_track(&private->rdc_data, 757 0, device->bp_block); 758 } 759 geo->cylinders = private->rdc_data.no_cyl; 760 geo->heads = private->rdc_data.trk_per_cyl; 761 return 0; 762 } 763 764 static struct dasd_ccw_req * 765 dasd_eckd_format_device(struct dasd_device * device, 766 struct format_data_t * fdata) 767 { 768 struct dasd_eckd_private *private; 769 struct dasd_ccw_req *fcp; 770 struct eckd_count *ect; 771 struct ccw1 *ccw; 772 void *data; 773 int rpt, cyl, head; 774 int cplength, datasize; 775 int i; 776 777 private = (struct dasd_eckd_private *) device->private; 778 rpt = recs_per_track(&private->rdc_data, 0, fdata->blksize); 779 cyl = fdata->start_unit / private->rdc_data.trk_per_cyl; 780 head = fdata->start_unit % private->rdc_data.trk_per_cyl; 781 782 /* Sanity checks. */ 783 if (fdata->start_unit >= 784 (private->rdc_data.no_cyl * private->rdc_data.trk_per_cyl)) { 785 DEV_MESSAGE(KERN_INFO, device, "Track no %d too big!", 786 fdata->start_unit); 787 return ERR_PTR(-EINVAL); 788 } 789 if (fdata->start_unit > fdata->stop_unit) { 790 DEV_MESSAGE(KERN_INFO, device, "Track %d reached! ending.", 791 fdata->start_unit); 792 return ERR_PTR(-EINVAL); 793 } 794 if (dasd_check_blocksize(fdata->blksize) != 0) { 795 DEV_MESSAGE(KERN_WARNING, device, 796 "Invalid blocksize %d...terminating!", 797 fdata->blksize); 798 return ERR_PTR(-EINVAL); 799 } 800 801 /* 802 * fdata->intensity is a bit string that tells us what to do: 803 * Bit 0: write record zero 804 * Bit 1: write home address, currently not supported 805 * Bit 2: invalidate tracks 806 * Bit 3: use OS/390 compatible disk layout (cdl) 807 * Only some bit combinations do make sense. 808 */ 809 switch (fdata->intensity) { 810 case 0x00: /* Normal format */ 811 case 0x08: /* Normal format, use cdl. */ 812 cplength = 2 + rpt; 813 datasize = sizeof(struct DE_eckd_data) + 814 sizeof(struct LO_eckd_data) + 815 rpt * sizeof(struct eckd_count); 816 break; 817 case 0x01: /* Write record zero and format track. */ 818 case 0x09: /* Write record zero and format track, use cdl. */ 819 cplength = 3 + rpt; 820 datasize = sizeof(struct DE_eckd_data) + 821 sizeof(struct LO_eckd_data) + 822 sizeof(struct eckd_count) + 823 rpt * sizeof(struct eckd_count); 824 break; 825 case 0x04: /* Invalidate track. */ 826 case 0x0c: /* Invalidate track, use cdl. */ 827 cplength = 3; 828 datasize = sizeof(struct DE_eckd_data) + 829 sizeof(struct LO_eckd_data) + 830 sizeof(struct eckd_count); 831 break; 832 default: 833 DEV_MESSAGE(KERN_WARNING, device, "Invalid flags 0x%x.", 834 fdata->intensity); 835 return ERR_PTR(-EINVAL); 836 } 837 /* Allocate the format ccw request. */ 838 fcp = dasd_smalloc_request(dasd_eckd_discipline.name, 839 cplength, datasize, device); 840 if (IS_ERR(fcp)) 841 return fcp; 842 843 data = fcp->data; 844 ccw = fcp->cpaddr; 845 846 switch (fdata->intensity & ~0x08) { 847 case 0x00: /* Normal format. */ 848 define_extent(ccw++, (struct DE_eckd_data *) data, 849 fdata->start_unit, fdata->start_unit, 850 DASD_ECKD_CCW_WRITE_CKD, device); 851 data += sizeof(struct DE_eckd_data); 852 ccw[-1].flags |= CCW_FLAG_CC; 853 locate_record(ccw++, (struct LO_eckd_data *) data, 854 fdata->start_unit, 0, rpt, 855 DASD_ECKD_CCW_WRITE_CKD, device, 856 fdata->blksize); 857 data += sizeof(struct LO_eckd_data); 858 break; 859 case 0x01: /* Write record zero + format track. */ 860 define_extent(ccw++, (struct DE_eckd_data *) data, 861 fdata->start_unit, fdata->start_unit, 862 DASD_ECKD_CCW_WRITE_RECORD_ZERO, 863 device); 864 data += sizeof(struct DE_eckd_data); 865 ccw[-1].flags |= CCW_FLAG_CC; 866 locate_record(ccw++, (struct LO_eckd_data *) data, 867 fdata->start_unit, 0, rpt + 1, 868 DASD_ECKD_CCW_WRITE_RECORD_ZERO, device, 869 device->bp_block); 870 data += sizeof(struct LO_eckd_data); 871 break; 872 case 0x04: /* Invalidate track. */ 873 define_extent(ccw++, (struct DE_eckd_data *) data, 874 fdata->start_unit, fdata->start_unit, 875 DASD_ECKD_CCW_WRITE_CKD, device); 876 data += sizeof(struct DE_eckd_data); 877 ccw[-1].flags |= CCW_FLAG_CC; 878 locate_record(ccw++, (struct LO_eckd_data *) data, 879 fdata->start_unit, 0, 1, 880 DASD_ECKD_CCW_WRITE_CKD, device, 8); 881 data += sizeof(struct LO_eckd_data); 882 break; 883 } 884 if (fdata->intensity & 0x01) { /* write record zero */ 885 ect = (struct eckd_count *) data; 886 data += sizeof(struct eckd_count); 887 ect->cyl = cyl; 888 ect->head = head; 889 ect->record = 0; 890 ect->kl = 0; 891 ect->dl = 8; 892 ccw[-1].flags |= CCW_FLAG_CC; 893 ccw->cmd_code = DASD_ECKD_CCW_WRITE_RECORD_ZERO; 894 ccw->flags = CCW_FLAG_SLI; 895 ccw->count = 8; 896 ccw->cda = (__u32)(addr_t) ect; 897 ccw++; 898 } 899 if ((fdata->intensity & ~0x08) & 0x04) { /* erase track */ 900 ect = (struct eckd_count *) data; 901 data += sizeof(struct eckd_count); 902 ect->cyl = cyl; 903 ect->head = head; 904 ect->record = 1; 905 ect->kl = 0; 906 ect->dl = 0; 907 ccw[-1].flags |= CCW_FLAG_CC; 908 ccw->cmd_code = DASD_ECKD_CCW_WRITE_CKD; 909 ccw->flags = CCW_FLAG_SLI; 910 ccw->count = 8; 911 ccw->cda = (__u32)(addr_t) ect; 912 } else { /* write remaining records */ 913 for (i = 0; i < rpt; i++) { 914 ect = (struct eckd_count *) data; 915 data += sizeof(struct eckd_count); 916 ect->cyl = cyl; 917 ect->head = head; 918 ect->record = i + 1; 919 ect->kl = 0; 920 ect->dl = fdata->blksize; 921 /* Check for special tracks 0-1 when formatting CDL */ 922 if ((fdata->intensity & 0x08) && 923 fdata->start_unit == 0) { 924 if (i < 3) { 925 ect->kl = 4; 926 ect->dl = sizes_trk0[i] - 4; 927 } 928 } 929 if ((fdata->intensity & 0x08) && 930 fdata->start_unit == 1) { 931 ect->kl = 44; 932 ect->dl = LABEL_SIZE - 44; 933 } 934 ccw[-1].flags |= CCW_FLAG_CC; 935 ccw->cmd_code = DASD_ECKD_CCW_WRITE_CKD; 936 ccw->flags = CCW_FLAG_SLI; 937 ccw->count = 8; 938 ccw->cda = (__u32)(addr_t) ect; 939 ccw++; 940 } 941 } 942 fcp->device = device; 943 fcp->retries = 2; /* set retry counter to enable ERP */ 944 fcp->buildclk = get_clock(); 945 fcp->status = DASD_CQR_FILLED; 946 return fcp; 947 } 948 949 static dasd_era_t 950 dasd_eckd_examine_error(struct dasd_ccw_req * cqr, struct irb * irb) 951 { 952 struct dasd_device *device = (struct dasd_device *) cqr->device; 953 struct ccw_device *cdev = device->cdev; 954 955 if (irb->scsw.cstat == 0x00 && 956 irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END)) 957 return dasd_era_none; 958 959 switch (cdev->id.cu_type) { 960 case 0x3990: 961 case 0x2105: 962 case 0x2107: 963 case 0x1750: 964 return dasd_3990_erp_examine(cqr, irb); 965 case 0x9343: 966 return dasd_9343_erp_examine(cqr, irb); 967 case 0x3880: 968 default: 969 DEV_MESSAGE(KERN_WARNING, device, "%s", 970 "default (unknown CU type) - RECOVERABLE return"); 971 return dasd_era_recover; 972 } 973 } 974 975 static dasd_erp_fn_t 976 dasd_eckd_erp_action(struct dasd_ccw_req * cqr) 977 { 978 struct dasd_device *device = (struct dasd_device *) cqr->device; 979 struct ccw_device *cdev = device->cdev; 980 981 switch (cdev->id.cu_type) { 982 case 0x3990: 983 case 0x2105: 984 case 0x2107: 985 case 0x1750: 986 return dasd_3990_erp_action; 987 case 0x9343: 988 case 0x3880: 989 default: 990 return dasd_default_erp_action; 991 } 992 } 993 994 static dasd_erp_fn_t 995 dasd_eckd_erp_postaction(struct dasd_ccw_req * cqr) 996 { 997 return dasd_default_erp_postaction; 998 } 999 1000 static struct dasd_ccw_req * 1001 dasd_eckd_build_cp(struct dasd_device * device, struct request *req) 1002 { 1003 struct dasd_eckd_private *private; 1004 unsigned long *idaws; 1005 struct LO_eckd_data *LO_data; 1006 struct dasd_ccw_req *cqr; 1007 struct ccw1 *ccw; 1008 struct bio *bio; 1009 struct bio_vec *bv; 1010 char *dst; 1011 unsigned int blksize, blk_per_trk, off; 1012 int count, cidaw, cplength, datasize; 1013 sector_t recid, first_rec, last_rec; 1014 sector_t first_trk, last_trk; 1015 unsigned int first_offs, last_offs; 1016 unsigned char cmd, rcmd; 1017 int i; 1018 1019 private = (struct dasd_eckd_private *) device->private; 1020 if (rq_data_dir(req) == READ) 1021 cmd = DASD_ECKD_CCW_READ_MT; 1022 else if (rq_data_dir(req) == WRITE) 1023 cmd = DASD_ECKD_CCW_WRITE_MT; 1024 else 1025 return ERR_PTR(-EINVAL); 1026 /* Calculate number of blocks/records per track. */ 1027 blksize = device->bp_block; 1028 blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize); 1029 /* Calculate record id of first and last block. */ 1030 first_rec = first_trk = req->sector >> device->s2b_shift; 1031 first_offs = sector_div(first_trk, blk_per_trk); 1032 last_rec = last_trk = 1033 (req->sector + req->nr_sectors - 1) >> device->s2b_shift; 1034 last_offs = sector_div(last_trk, blk_per_trk); 1035 /* Check struct bio and count the number of blocks for the request. */ 1036 count = 0; 1037 cidaw = 0; 1038 rq_for_each_bio(bio, req) { 1039 bio_for_each_segment(bv, bio, i) { 1040 if (bv->bv_len & (blksize - 1)) 1041 /* Eckd can only do full blocks. */ 1042 return ERR_PTR(-EINVAL); 1043 count += bv->bv_len >> (device->s2b_shift + 9); 1044 #if defined(CONFIG_64BIT) 1045 if (idal_is_needed (page_address(bv->bv_page), 1046 bv->bv_len)) 1047 cidaw += bv->bv_len >> (device->s2b_shift + 9); 1048 #endif 1049 } 1050 } 1051 /* Paranoia. */ 1052 if (count != last_rec - first_rec + 1) 1053 return ERR_PTR(-EINVAL); 1054 /* 1x define extent + 1x locate record + number of blocks */ 1055 cplength = 2 + count; 1056 /* 1x define extent + 1x locate record + cidaws*sizeof(long) */ 1057 datasize = sizeof(struct DE_eckd_data) + sizeof(struct LO_eckd_data) + 1058 cidaw * sizeof(unsigned long); 1059 /* Find out the number of additional locate record ccws for cdl. */ 1060 if (private->uses_cdl && first_rec < 2*blk_per_trk) { 1061 if (last_rec >= 2*blk_per_trk) 1062 count = 2*blk_per_trk - first_rec; 1063 cplength += count; 1064 datasize += count*sizeof(struct LO_eckd_data); 1065 } 1066 /* Allocate the ccw request. */ 1067 cqr = dasd_smalloc_request(dasd_eckd_discipline.name, 1068 cplength, datasize, device); 1069 if (IS_ERR(cqr)) 1070 return cqr; 1071 ccw = cqr->cpaddr; 1072 /* First ccw is define extent. */ 1073 define_extent(ccw++, cqr->data, first_trk, last_trk, cmd, device); 1074 /* Build locate_record+read/write/ccws. */ 1075 idaws = (unsigned long *) (cqr->data + sizeof(struct DE_eckd_data)); 1076 LO_data = (struct LO_eckd_data *) (idaws + cidaw); 1077 recid = first_rec; 1078 if (private->uses_cdl == 0 || recid > 2*blk_per_trk) { 1079 /* Only standard blocks so there is just one locate record. */ 1080 ccw[-1].flags |= CCW_FLAG_CC; 1081 locate_record(ccw++, LO_data++, first_trk, first_offs + 1, 1082 last_rec - recid + 1, cmd, device, blksize); 1083 } 1084 rq_for_each_bio(bio, req) bio_for_each_segment(bv, bio, i) { 1085 dst = page_address(bv->bv_page) + bv->bv_offset; 1086 if (dasd_page_cache) { 1087 char *copy = kmem_cache_alloc(dasd_page_cache, 1088 SLAB_DMA | __GFP_NOWARN); 1089 if (copy && rq_data_dir(req) == WRITE) 1090 memcpy(copy + bv->bv_offset, dst, bv->bv_len); 1091 if (copy) 1092 dst = copy + bv->bv_offset; 1093 } 1094 for (off = 0; off < bv->bv_len; off += blksize) { 1095 sector_t trkid = recid; 1096 unsigned int recoffs = sector_div(trkid, blk_per_trk); 1097 rcmd = cmd; 1098 count = blksize; 1099 /* Locate record for cdl special block ? */ 1100 if (private->uses_cdl && recid < 2*blk_per_trk) { 1101 if (dasd_eckd_cdl_special(blk_per_trk, recid)){ 1102 rcmd |= 0x8; 1103 count = dasd_eckd_cdl_reclen(recid); 1104 if (count < blksize && 1105 rq_data_dir(req) == READ) 1106 memset(dst + count, 0xe5, 1107 blksize - count); 1108 } 1109 ccw[-1].flags |= CCW_FLAG_CC; 1110 locate_record(ccw++, LO_data++, 1111 trkid, recoffs + 1, 1112 1, rcmd, device, count); 1113 } 1114 /* Locate record for standard blocks ? */ 1115 if (private->uses_cdl && recid == 2*blk_per_trk) { 1116 ccw[-1].flags |= CCW_FLAG_CC; 1117 locate_record(ccw++, LO_data++, 1118 trkid, recoffs + 1, 1119 last_rec - recid + 1, 1120 cmd, device, count); 1121 } 1122 /* Read/write ccw. */ 1123 ccw[-1].flags |= CCW_FLAG_CC; 1124 ccw->cmd_code = rcmd; 1125 ccw->count = count; 1126 if (idal_is_needed(dst, blksize)) { 1127 ccw->cda = (__u32)(addr_t) idaws; 1128 ccw->flags = CCW_FLAG_IDA; 1129 idaws = idal_create_words(idaws, dst, blksize); 1130 } else { 1131 ccw->cda = (__u32)(addr_t) dst; 1132 ccw->flags = 0; 1133 } 1134 ccw++; 1135 dst += blksize; 1136 recid++; 1137 } 1138 } 1139 if (req->flags & REQ_FAILFAST) 1140 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); 1141 cqr->device = device; 1142 cqr->expires = 5 * 60 * HZ; /* 5 minutes */ 1143 cqr->lpm = private->path_data.ppm; 1144 cqr->retries = 256; 1145 cqr->buildclk = get_clock(); 1146 cqr->status = DASD_CQR_FILLED; 1147 return cqr; 1148 } 1149 1150 static int 1151 dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req) 1152 { 1153 struct dasd_eckd_private *private; 1154 struct ccw1 *ccw; 1155 struct bio *bio; 1156 struct bio_vec *bv; 1157 char *dst, *cda; 1158 unsigned int blksize, blk_per_trk, off; 1159 sector_t recid; 1160 int i, status; 1161 1162 if (!dasd_page_cache) 1163 goto out; 1164 private = (struct dasd_eckd_private *) cqr->device->private; 1165 blksize = cqr->device->bp_block; 1166 blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize); 1167 recid = req->sector >> cqr->device->s2b_shift; 1168 ccw = cqr->cpaddr; 1169 /* Skip over define extent & locate record. */ 1170 ccw++; 1171 if (private->uses_cdl == 0 || recid > 2*blk_per_trk) 1172 ccw++; 1173 rq_for_each_bio(bio, req) bio_for_each_segment(bv, bio, i) { 1174 dst = page_address(bv->bv_page) + bv->bv_offset; 1175 for (off = 0; off < bv->bv_len; off += blksize) { 1176 /* Skip locate record. */ 1177 if (private->uses_cdl && recid <= 2*blk_per_trk) 1178 ccw++; 1179 if (dst) { 1180 if (ccw->flags & CCW_FLAG_IDA) 1181 cda = *((char **)((addr_t) ccw->cda)); 1182 else 1183 cda = (char *)((addr_t) ccw->cda); 1184 if (dst != cda) { 1185 if (rq_data_dir(req) == READ) 1186 memcpy(dst, cda, bv->bv_len); 1187 kmem_cache_free(dasd_page_cache, 1188 (void *)((addr_t)cda & PAGE_MASK)); 1189 } 1190 dst = NULL; 1191 } 1192 ccw++; 1193 recid++; 1194 } 1195 } 1196 out: 1197 status = cqr->status == DASD_CQR_DONE; 1198 dasd_sfree_request(cqr, cqr->device); 1199 return status; 1200 } 1201 1202 static int 1203 dasd_eckd_fill_info(struct dasd_device * device, 1204 struct dasd_information2_t * info) 1205 { 1206 struct dasd_eckd_private *private; 1207 1208 private = (struct dasd_eckd_private *) device->private; 1209 info->label_block = 2; 1210 info->FBA_layout = private->uses_cdl ? 0 : 1; 1211 info->format = private->uses_cdl ? DASD_FORMAT_CDL : DASD_FORMAT_LDL; 1212 info->characteristics_size = sizeof(struct dasd_eckd_characteristics); 1213 memcpy(info->characteristics, &private->rdc_data, 1214 sizeof(struct dasd_eckd_characteristics)); 1215 info->confdata_size = sizeof (struct dasd_eckd_confdata); 1216 memcpy(info->configuration_data, &private->conf_data, 1217 sizeof (struct dasd_eckd_confdata)); 1218 return 0; 1219 } 1220 1221 /* 1222 * SECTION: ioctl functions for eckd devices. 1223 */ 1224 1225 /* 1226 * Release device ioctl. 1227 * Buils a channel programm to releases a prior reserved 1228 * (see dasd_eckd_reserve) device. 1229 */ 1230 static int 1231 dasd_eckd_release(struct block_device *bdev, int no, long args) 1232 { 1233 struct dasd_device *device; 1234 struct dasd_ccw_req *cqr; 1235 int rc; 1236 1237 if (!capable(CAP_SYS_ADMIN)) 1238 return -EACCES; 1239 1240 device = bdev->bd_disk->private_data; 1241 if (device == NULL) 1242 return -ENODEV; 1243 1244 cqr = dasd_smalloc_request(dasd_eckd_discipline.name, 1245 1, 32, device); 1246 if (IS_ERR(cqr)) { 1247 DEV_MESSAGE(KERN_WARNING, device, "%s", 1248 "Could not allocate initialization request"); 1249 return PTR_ERR(cqr); 1250 } 1251 cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RELEASE; 1252 cqr->cpaddr->flags |= CCW_FLAG_SLI; 1253 cqr->cpaddr->count = 32; 1254 cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; 1255 cqr->device = device; 1256 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); 1257 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); 1258 cqr->retries = 0; 1259 cqr->expires = 2 * HZ; 1260 cqr->buildclk = get_clock(); 1261 cqr->status = DASD_CQR_FILLED; 1262 1263 rc = dasd_sleep_on_immediatly(cqr); 1264 1265 dasd_sfree_request(cqr, cqr->device); 1266 return rc; 1267 } 1268 1269 /* 1270 * Reserve device ioctl. 1271 * Options are set to 'synchronous wait for interrupt' and 1272 * 'timeout the request'. This leads to a terminate IO if 1273 * the interrupt is outstanding for a certain time. 1274 */ 1275 static int 1276 dasd_eckd_reserve(struct block_device *bdev, int no, long args) 1277 { 1278 struct dasd_device *device; 1279 struct dasd_ccw_req *cqr; 1280 int rc; 1281 1282 if (!capable(CAP_SYS_ADMIN)) 1283 return -EACCES; 1284 1285 device = bdev->bd_disk->private_data; 1286 if (device == NULL) 1287 return -ENODEV; 1288 1289 cqr = dasd_smalloc_request(dasd_eckd_discipline.name, 1290 1, 32, device); 1291 if (IS_ERR(cqr)) { 1292 DEV_MESSAGE(KERN_WARNING, device, "%s", 1293 "Could not allocate initialization request"); 1294 return PTR_ERR(cqr); 1295 } 1296 cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RESERVE; 1297 cqr->cpaddr->flags |= CCW_FLAG_SLI; 1298 cqr->cpaddr->count = 32; 1299 cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; 1300 cqr->device = device; 1301 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); 1302 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); 1303 cqr->retries = 0; 1304 cqr->expires = 2 * HZ; 1305 cqr->buildclk = get_clock(); 1306 cqr->status = DASD_CQR_FILLED; 1307 1308 rc = dasd_sleep_on_immediatly(cqr); 1309 1310 dasd_sfree_request(cqr, cqr->device); 1311 return rc; 1312 } 1313 1314 /* 1315 * Steal lock ioctl - unconditional reserve device. 1316 * Buils a channel programm to break a device's reservation. 1317 * (unconditional reserve) 1318 */ 1319 static int 1320 dasd_eckd_steal_lock(struct block_device *bdev, int no, long args) 1321 { 1322 struct dasd_device *device; 1323 struct dasd_ccw_req *cqr; 1324 int rc; 1325 1326 if (!capable(CAP_SYS_ADMIN)) 1327 return -EACCES; 1328 1329 device = bdev->bd_disk->private_data; 1330 if (device == NULL) 1331 return -ENODEV; 1332 1333 cqr = dasd_smalloc_request(dasd_eckd_discipline.name, 1334 1, 32, device); 1335 if (IS_ERR(cqr)) { 1336 DEV_MESSAGE(KERN_WARNING, device, "%s", 1337 "Could not allocate initialization request"); 1338 return PTR_ERR(cqr); 1339 } 1340 cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SLCK; 1341 cqr->cpaddr->flags |= CCW_FLAG_SLI; 1342 cqr->cpaddr->count = 32; 1343 cqr->cpaddr->cda = (__u32)(addr_t) cqr->data; 1344 cqr->device = device; 1345 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); 1346 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); 1347 cqr->retries = 0; 1348 cqr->expires = 2 * HZ; 1349 cqr->buildclk = get_clock(); 1350 cqr->status = DASD_CQR_FILLED; 1351 1352 rc = dasd_sleep_on_immediatly(cqr); 1353 1354 dasd_sfree_request(cqr, cqr->device); 1355 return rc; 1356 } 1357 1358 /* 1359 * Read performance statistics 1360 */ 1361 static int 1362 dasd_eckd_performance(struct block_device *bdev, int no, long args) 1363 { 1364 struct dasd_device *device; 1365 struct dasd_psf_prssd_data *prssdp; 1366 struct dasd_rssd_perf_stats_t *stats; 1367 struct dasd_ccw_req *cqr; 1368 struct ccw1 *ccw; 1369 int rc; 1370 1371 device = bdev->bd_disk->private_data; 1372 if (device == NULL) 1373 return -ENODEV; 1374 1375 cqr = dasd_smalloc_request(dasd_eckd_discipline.name, 1376 1 /* PSF */ + 1 /* RSSD */ , 1377 (sizeof (struct dasd_psf_prssd_data) + 1378 sizeof (struct dasd_rssd_perf_stats_t)), 1379 device); 1380 if (IS_ERR(cqr)) { 1381 DEV_MESSAGE(KERN_WARNING, device, "%s", 1382 "Could not allocate initialization request"); 1383 return PTR_ERR(cqr); 1384 } 1385 cqr->device = device; 1386 cqr->retries = 0; 1387 cqr->expires = 10 * HZ; 1388 1389 /* Prepare for Read Subsystem Data */ 1390 prssdp = (struct dasd_psf_prssd_data *) cqr->data; 1391 memset(prssdp, 0, sizeof (struct dasd_psf_prssd_data)); 1392 prssdp->order = PSF_ORDER_PRSSD; 1393 prssdp->suborder = 0x01; /* Perfomance Statistics */ 1394 prssdp->varies[1] = 0x01; /* Perf Statistics for the Subsystem */ 1395 1396 ccw = cqr->cpaddr; 1397 ccw->cmd_code = DASD_ECKD_CCW_PSF; 1398 ccw->count = sizeof (struct dasd_psf_prssd_data); 1399 ccw->flags |= CCW_FLAG_CC; 1400 ccw->cda = (__u32)(addr_t) prssdp; 1401 1402 /* Read Subsystem Data - Performance Statistics */ 1403 stats = (struct dasd_rssd_perf_stats_t *) (prssdp + 1); 1404 memset(stats, 0, sizeof (struct dasd_rssd_perf_stats_t)); 1405 1406 ccw++; 1407 ccw->cmd_code = DASD_ECKD_CCW_RSSD; 1408 ccw->count = sizeof (struct dasd_rssd_perf_stats_t); 1409 ccw->cda = (__u32)(addr_t) stats; 1410 1411 cqr->buildclk = get_clock(); 1412 cqr->status = DASD_CQR_FILLED; 1413 rc = dasd_sleep_on(cqr); 1414 if (rc == 0) { 1415 /* Prepare for Read Subsystem Data */ 1416 prssdp = (struct dasd_psf_prssd_data *) cqr->data; 1417 stats = (struct dasd_rssd_perf_stats_t *) (prssdp + 1); 1418 rc = copy_to_user((long __user *) args, (long *) stats, 1419 sizeof(struct dasd_rssd_perf_stats_t)); 1420 } 1421 dasd_sfree_request(cqr, cqr->device); 1422 return rc; 1423 } 1424 1425 /* 1426 * Get attributes (cache operations) 1427 * Returnes the cache attributes used in Define Extend (DE). 1428 */ 1429 static int 1430 dasd_eckd_get_attrib (struct block_device *bdev, int no, long args) 1431 { 1432 struct dasd_device *device; 1433 struct dasd_eckd_private *private; 1434 struct attrib_data_t attrib; 1435 int rc; 1436 1437 if (!capable(CAP_SYS_ADMIN)) 1438 return -EACCES; 1439 if (!args) 1440 return -EINVAL; 1441 1442 device = bdev->bd_disk->private_data; 1443 if (device == NULL) 1444 return -ENODEV; 1445 1446 private = (struct dasd_eckd_private *) device->private; 1447 attrib = private->attrib; 1448 1449 rc = copy_to_user((long __user *) args, (long *) &attrib, 1450 sizeof (struct attrib_data_t)); 1451 1452 return rc; 1453 } 1454 1455 /* 1456 * Set attributes (cache operations) 1457 * Stores the attributes for cache operation to be used in Define Extend (DE). 1458 */ 1459 static int 1460 dasd_eckd_set_attrib(struct block_device *bdev, int no, long args) 1461 { 1462 struct dasd_device *device; 1463 struct dasd_eckd_private *private; 1464 struct attrib_data_t attrib; 1465 1466 if (!capable(CAP_SYS_ADMIN)) 1467 return -EACCES; 1468 if (!args) 1469 return -EINVAL; 1470 1471 device = bdev->bd_disk->private_data; 1472 if (device == NULL) 1473 return -ENODEV; 1474 1475 if (copy_from_user(&attrib, (void __user *) args, 1476 sizeof (struct attrib_data_t))) { 1477 return -EFAULT; 1478 } 1479 private = (struct dasd_eckd_private *) device->private; 1480 private->attrib = attrib; 1481 1482 DEV_MESSAGE(KERN_INFO, device, 1483 "cache operation mode set to %x (%i cylinder prestage)", 1484 private->attrib.operation, private->attrib.nr_cyl); 1485 return 0; 1486 } 1487 1488 /* 1489 * Print sense data and related channel program. 1490 * Parts are printed because printk buffer is only 1024 bytes. 1491 */ 1492 static void 1493 dasd_eckd_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req, 1494 struct irb *irb) 1495 { 1496 char *page; 1497 struct ccw1 *act, *end, *last; 1498 int len, sl, sct, count; 1499 1500 page = (char *) get_zeroed_page(GFP_ATOMIC); 1501 if (page == NULL) { 1502 DEV_MESSAGE(KERN_ERR, device, " %s", 1503 "No memory to dump sense data"); 1504 return; 1505 } 1506 len = sprintf(page, KERN_ERR PRINTK_HEADER 1507 " I/O status report for device %s:\n", 1508 device->cdev->dev.bus_id); 1509 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 1510 " in req: %p CS: 0x%02X DS: 0x%02X\n", req, 1511 irb->scsw.cstat, irb->scsw.dstat); 1512 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 1513 " device %s: Failing CCW: %p\n", 1514 device->cdev->dev.bus_id, 1515 (void *) (addr_t) irb->scsw.cpa); 1516 if (irb->esw.esw0.erw.cons) { 1517 for (sl = 0; sl < 4; sl++) { 1518 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 1519 " Sense(hex) %2d-%2d:", 1520 (8 * sl), ((8 * sl) + 7)); 1521 1522 for (sct = 0; sct < 8; sct++) { 1523 len += sprintf(page + len, " %02x", 1524 irb->ecw[8 * sl + sct]); 1525 } 1526 len += sprintf(page + len, "\n"); 1527 } 1528 1529 if (irb->ecw[27] & DASD_SENSE_BIT_0) { 1530 /* 24 Byte Sense Data */ 1531 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 1532 " 24 Byte: %x MSG %x, " 1533 "%s MSGb to SYSOP\n", 1534 irb->ecw[7] >> 4, irb->ecw[7] & 0x0f, 1535 irb->ecw[1] & 0x10 ? "" : "no"); 1536 } else { 1537 /* 32 Byte Sense Data */ 1538 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 1539 " 32 Byte: Format: %x " 1540 "Exception class %x\n", 1541 irb->ecw[6] & 0x0f, irb->ecw[22] >> 4); 1542 } 1543 } else { 1544 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 1545 " SORRY - NO VALID SENSE AVAILABLE\n"); 1546 } 1547 MESSAGE_LOG(KERN_ERR, "%s", 1548 page + sizeof(KERN_ERR PRINTK_HEADER)); 1549 1550 /* dump the Channel Program */ 1551 /* print first CCWs (maximum 8) */ 1552 act = req->cpaddr; 1553 for (last = act; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++); 1554 end = min(act + 8, last); 1555 len = sprintf(page, KERN_ERR PRINTK_HEADER 1556 " Related CP in req: %p\n", req); 1557 while (act <= end) { 1558 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 1559 " CCW %p: %08X %08X DAT:", 1560 act, ((int *) act)[0], ((int *) act)[1]); 1561 for (count = 0; count < 32 && count < act->count; 1562 count += sizeof(int)) 1563 len += sprintf(page + len, " %08X", 1564 ((int *) (addr_t) act->cda) 1565 [(count>>2)]); 1566 len += sprintf(page + len, "\n"); 1567 act++; 1568 } 1569 MESSAGE_LOG(KERN_ERR, "%s", 1570 page + sizeof(KERN_ERR PRINTK_HEADER)); 1571 1572 /* print failing CCW area */ 1573 len = 0; 1574 if (act < ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2) { 1575 act = ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2; 1576 len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n"); 1577 } 1578 end = min((struct ccw1 *)(addr_t) irb->scsw.cpa + 2, last); 1579 while (act <= end) { 1580 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 1581 " CCW %p: %08X %08X DAT:", 1582 act, ((int *) act)[0], ((int *) act)[1]); 1583 for (count = 0; count < 32 && count < act->count; 1584 count += sizeof(int)) 1585 len += sprintf(page + len, " %08X", 1586 ((int *) (addr_t) act->cda) 1587 [(count>>2)]); 1588 len += sprintf(page + len, "\n"); 1589 act++; 1590 } 1591 1592 /* print last CCWs */ 1593 if (act < last - 2) { 1594 act = last - 2; 1595 len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n"); 1596 } 1597 while (act <= last) { 1598 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 1599 " CCW %p: %08X %08X DAT:", 1600 act, ((int *) act)[0], ((int *) act)[1]); 1601 for (count = 0; count < 32 && count < act->count; 1602 count += sizeof(int)) 1603 len += sprintf(page + len, " %08X", 1604 ((int *) (addr_t) act->cda) 1605 [(count>>2)]); 1606 len += sprintf(page + len, "\n"); 1607 act++; 1608 } 1609 if (len > 0) 1610 MESSAGE_LOG(KERN_ERR, "%s", 1611 page + sizeof(KERN_ERR PRINTK_HEADER)); 1612 free_page((unsigned long) page); 1613 } 1614 1615 /* 1616 * max_blocks is dependent on the amount of storage that is available 1617 * in the static io buffer for each device. Currently each device has 1618 * 8192 bytes (=2 pages). For 64 bit one dasd_mchunkt_t structure has 1619 * 24 bytes, the struct dasd_ccw_req has 136 bytes and each block can use 1620 * up to 16 bytes (8 for the ccw and 8 for the idal pointer). In 1621 * addition we have one define extent ccw + 16 bytes of data and one 1622 * locate record ccw + 16 bytes of data. That makes: 1623 * (8192 - 24 - 136 - 8 - 16 - 8 - 16) / 16 = 499 blocks at maximum. 1624 * We want to fit two into the available memory so that we can immediately 1625 * start the next request if one finishes off. That makes 249.5 blocks 1626 * for one request. Give a little safety and the result is 240. 1627 */ 1628 static struct dasd_discipline dasd_eckd_discipline = { 1629 .owner = THIS_MODULE, 1630 .name = "ECKD", 1631 .ebcname = "ECKD", 1632 .max_blocks = 240, 1633 .check_device = dasd_eckd_check_characteristics, 1634 .do_analysis = dasd_eckd_do_analysis, 1635 .fill_geometry = dasd_eckd_fill_geometry, 1636 .start_IO = dasd_start_IO, 1637 .term_IO = dasd_term_IO, 1638 .format_device = dasd_eckd_format_device, 1639 .examine_error = dasd_eckd_examine_error, 1640 .erp_action = dasd_eckd_erp_action, 1641 .erp_postaction = dasd_eckd_erp_postaction, 1642 .build_cp = dasd_eckd_build_cp, 1643 .free_cp = dasd_eckd_free_cp, 1644 .dump_sense = dasd_eckd_dump_sense, 1645 .fill_info = dasd_eckd_fill_info, 1646 }; 1647 1648 static int __init 1649 dasd_eckd_init(void) 1650 { 1651 int ret; 1652 1653 dasd_ioctl_no_register(THIS_MODULE, BIODASDGATTR, 1654 dasd_eckd_get_attrib); 1655 dasd_ioctl_no_register(THIS_MODULE, BIODASDSATTR, 1656 dasd_eckd_set_attrib); 1657 dasd_ioctl_no_register(THIS_MODULE, BIODASDPSRD, 1658 dasd_eckd_performance); 1659 dasd_ioctl_no_register(THIS_MODULE, BIODASDRLSE, 1660 dasd_eckd_release); 1661 dasd_ioctl_no_register(THIS_MODULE, BIODASDRSRV, 1662 dasd_eckd_reserve); 1663 dasd_ioctl_no_register(THIS_MODULE, BIODASDSLCK, 1664 dasd_eckd_steal_lock); 1665 1666 ASCEBC(dasd_eckd_discipline.ebcname, 4); 1667 1668 ret = ccw_driver_register(&dasd_eckd_driver); 1669 if (ret) { 1670 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDGATTR, 1671 dasd_eckd_get_attrib); 1672 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDSATTR, 1673 dasd_eckd_set_attrib); 1674 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDPSRD, 1675 dasd_eckd_performance); 1676 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDRLSE, 1677 dasd_eckd_release); 1678 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDRSRV, 1679 dasd_eckd_reserve); 1680 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDSLCK, 1681 dasd_eckd_steal_lock); 1682 return ret; 1683 } 1684 1685 dasd_generic_auto_online(&dasd_eckd_driver); 1686 return 0; 1687 } 1688 1689 static void __exit 1690 dasd_eckd_cleanup(void) 1691 { 1692 ccw_driver_unregister(&dasd_eckd_driver); 1693 1694 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDGATTR, 1695 dasd_eckd_get_attrib); 1696 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDSATTR, 1697 dasd_eckd_set_attrib); 1698 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDPSRD, 1699 dasd_eckd_performance); 1700 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDRLSE, 1701 dasd_eckd_release); 1702 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDRSRV, 1703 dasd_eckd_reserve); 1704 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDSLCK, 1705 dasd_eckd_steal_lock); 1706 } 1707 1708 module_init(dasd_eckd_init); 1709 module_exit(dasd_eckd_cleanup); 1710 1711 /* 1712 * Overrides for Emacs so that we follow Linus's tabbing style. 1713 * Emacs will notice this stuff at the end of the file and automatically 1714 * adjust the settings for this buffer only. This must remain at the end 1715 * of the file. 1716 * --------------------------------------------------------------------------- 1717 * Local variables: 1718 * c-indent-level: 4 1719 * c-brace-imaginary-offset: 0 1720 * c-brace-offset: -4 1721 * c-argdecl-indent: 4 1722 * c-label-offset: -4 1723 * c-continued-statement-offset: 4 1724 * c-continued-brace-offset: 0 1725 * indent-tabs-mode: 1 1726 * tab-width: 8 1727 * End: 1728 */ 1729