1 /* 2 * File...........: linux/drivers/s390/block/dasd_diag.c 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 4 * Based on.......: linux/drivers/s390/block/mdisk.c 5 * ...............: by Hartmunt Penner <hpenner@de.ibm.com> 6 * Bugreports.to..: <Linux390@de.ibm.com> 7 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 8 * 9 * $Revision: 1.53 $ 10 */ 11 12 #include <linux/config.h> 13 #include <linux/stddef.h> 14 #include <linux/kernel.h> 15 #include <linux/slab.h> 16 #include <linux/hdreg.h> 17 #include <linux/bio.h> 18 #include <linux/module.h> 19 #include <linux/init.h> 20 #include <linux/jiffies.h> 21 22 #include <asm/dasd.h> 23 #include <asm/debug.h> 24 #include <asm/ebcdic.h> 25 #include <asm/io.h> 26 #include <asm/s390_ext.h> 27 #include <asm/todclk.h> 28 #include <asm/vtoc.h> 29 30 #include "dasd_int.h" 31 #include "dasd_diag.h" 32 33 #define PRINTK_HEADER "dasd(diag):" 34 35 MODULE_LICENSE("GPL"); 36 37 /* The maximum number of blocks per request (max_blocks) is dependent on the 38 * amount of storage that is available in the static I/O buffer for each 39 * device. Currently each device gets 2 pages. We want to fit two requests 40 * into the available memory so that we can immediately start the next if one 41 * finishes. */ 42 #define DIAG_MAX_BLOCKS (((2 * PAGE_SIZE - sizeof(struct dasd_ccw_req) - \ 43 sizeof(struct dasd_diag_req)) / \ 44 sizeof(struct dasd_diag_bio)) / 2) 45 #define DIAG_MAX_RETRIES 32 46 #define DIAG_TIMEOUT 50 * HZ 47 48 struct dasd_discipline dasd_diag_discipline; 49 50 struct dasd_diag_private { 51 struct dasd_diag_characteristics rdc_data; 52 struct dasd_diag_rw_io iob; 53 struct dasd_diag_init_io iib; 54 blocknum_t pt_block; 55 }; 56 57 struct dasd_diag_req { 58 unsigned int block_count; 59 struct dasd_diag_bio bio[0]; 60 }; 61 62 static const u8 DASD_DIAG_CMS1[] = { 0xc3, 0xd4, 0xe2, 0xf1 };/* EBCDIC CMS1 */ 63 64 /* Perform DIAG250 call with block I/O parameter list iob (input and output) 65 * and function code cmd. 66 * In case of an exception return 3. Otherwise return result of bitwise OR of 67 * resulting condition code and DIAG return code. */ 68 static __inline__ int 69 dia250(void *iob, int cmd) 70 { 71 typedef union { 72 struct dasd_diag_init_io init_io; 73 struct dasd_diag_rw_io rw_io; 74 } addr_type; 75 int rc; 76 77 __asm__ __volatile__( 78 #ifdef CONFIG_64BIT 79 " lghi %0,3\n" 80 " lgr 0,%3\n" 81 " diag 0,%2,0x250\n" 82 "0: ipm %0\n" 83 " srl %0,28\n" 84 " or %0,1\n" 85 "1:\n" 86 ".section __ex_table,\"a\"\n" 87 " .align 8\n" 88 " .quad 0b,1b\n" 89 ".previous\n" 90 #else 91 " lhi %0,3\n" 92 " lr 0,%3\n" 93 " diag 0,%2,0x250\n" 94 "0: ipm %0\n" 95 " srl %0,28\n" 96 " or %0,1\n" 97 "1:\n" 98 ".section __ex_table,\"a\"\n" 99 " .align 4\n" 100 " .long 0b,1b\n" 101 ".previous\n" 102 #endif 103 : "=&d" (rc), "=m" (*(addr_type *) iob) 104 : "d" (cmd), "d" (iob), "m" (*(addr_type *) iob) 105 : "0", "1", "cc"); 106 return rc; 107 } 108 109 /* Initialize block I/O to DIAG device using the specified blocksize and 110 * block offset. On success, return zero and set end_block to contain the 111 * number of blocks on the device minus the specified offset. Return non-zero 112 * otherwise. */ 113 static __inline__ int 114 mdsk_init_io(struct dasd_device *device, unsigned int blocksize, 115 blocknum_t offset, blocknum_t *end_block) 116 { 117 struct dasd_diag_private *private; 118 struct dasd_diag_init_io *iib; 119 int rc; 120 121 private = (struct dasd_diag_private *) device->private; 122 iib = &private->iib; 123 memset(iib, 0, sizeof (struct dasd_diag_init_io)); 124 125 iib->dev_nr = _ccw_device_get_device_number(device->cdev); 126 iib->block_size = blocksize; 127 iib->offset = offset; 128 iib->flaga = DASD_DIAG_FLAGA_DEFAULT; 129 130 rc = dia250(iib, INIT_BIO); 131 132 if ((rc & 3) == 0 && end_block) 133 *end_block = iib->end_block; 134 135 return rc; 136 } 137 138 /* Remove block I/O environment for device. Return zero on success, non-zero 139 * otherwise. */ 140 static __inline__ int 141 mdsk_term_io(struct dasd_device * device) 142 { 143 struct dasd_diag_private *private; 144 struct dasd_diag_init_io *iib; 145 int rc; 146 147 private = (struct dasd_diag_private *) device->private; 148 iib = &private->iib; 149 memset(iib, 0, sizeof (struct dasd_diag_init_io)); 150 iib->dev_nr = _ccw_device_get_device_number(device->cdev); 151 rc = dia250(iib, TERM_BIO); 152 return rc; 153 } 154 155 /* Error recovery for failed DIAG requests - try to reestablish the DIAG 156 * environment. */ 157 static void 158 dasd_diag_erp(struct dasd_device *device) 159 { 160 int rc; 161 162 mdsk_term_io(device); 163 rc = mdsk_init_io(device, device->bp_block, 0, NULL); 164 if (rc) 165 DEV_MESSAGE(KERN_WARNING, device, "DIAG ERP unsuccessful, " 166 "rc=%d", rc); 167 } 168 169 /* Start a given request at the device. Return zero on success, non-zero 170 * otherwise. */ 171 static int 172 dasd_start_diag(struct dasd_ccw_req * cqr) 173 { 174 struct dasd_device *device; 175 struct dasd_diag_private *private; 176 struct dasd_diag_req *dreq; 177 int rc; 178 179 device = cqr->device; 180 if (cqr->retries < 0) { 181 DEV_MESSAGE(KERN_WARNING, device, "DIAG start_IO: request %p " 182 "- no retry left)", cqr); 183 cqr->status = DASD_CQR_FAILED; 184 return -EIO; 185 } 186 private = (struct dasd_diag_private *) device->private; 187 dreq = (struct dasd_diag_req *) cqr->data; 188 189 private->iob.dev_nr = _ccw_device_get_device_number(device->cdev); 190 private->iob.key = 0; 191 private->iob.flags = DASD_DIAG_RWFLAG_ASYNC; 192 private->iob.block_count = dreq->block_count; 193 private->iob.interrupt_params = (addr_t) cqr; 194 private->iob.bio_list = dreq->bio; 195 private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT; 196 197 cqr->startclk = get_clock(); 198 cqr->starttime = jiffies; 199 cqr->retries--; 200 201 rc = dia250(&private->iob, RW_BIO); 202 switch (rc) { 203 case 0: /* Synchronous I/O finished successfully */ 204 cqr->stopclk = get_clock(); 205 cqr->status = DASD_CQR_DONE; 206 /* Indicate to calling function that only a dasd_schedule_bh() 207 and no timer is needed */ 208 rc = -EACCES; 209 break; 210 case 8: /* Asynchronous I/O was started */ 211 cqr->status = DASD_CQR_IN_IO; 212 rc = 0; 213 break; 214 default: /* Error condition */ 215 cqr->status = DASD_CQR_QUEUED; 216 DEV_MESSAGE(KERN_WARNING, device, "dia250 returned rc=%d", rc); 217 dasd_diag_erp(device); 218 rc = -EIO; 219 break; 220 } 221 return rc; 222 } 223 224 /* Terminate given request at the device. */ 225 static int 226 dasd_diag_term_IO(struct dasd_ccw_req * cqr) 227 { 228 struct dasd_device *device; 229 230 device = cqr->device; 231 mdsk_term_io(device); 232 mdsk_init_io(device, device->bp_block, 0, NULL); 233 cqr->status = DASD_CQR_CLEAR; 234 cqr->stopclk = get_clock(); 235 dasd_schedule_bh(device); 236 return 0; 237 } 238 239 /* Handle external interruption. */ 240 static void 241 dasd_ext_handler(struct pt_regs *regs, __u16 code) 242 { 243 struct dasd_ccw_req *cqr, *next; 244 struct dasd_device *device; 245 unsigned long long expires; 246 unsigned long flags; 247 u8 int_code, status; 248 addr_t ip; 249 int rc; 250 251 int_code = *((u8 *) DASD_DIAG_LC_INT_CODE); 252 status = *((u8 *) DASD_DIAG_LC_INT_STATUS); 253 switch (int_code) { 254 case DASD_DIAG_CODE_31BIT: 255 ip = (addr_t) *((u32 *) DASD_DIAG_LC_INT_PARM_31BIT); 256 break; 257 case DASD_DIAG_CODE_64BIT: 258 ip = (addr_t) *((u64 *) DASD_DIAG_LC_INT_PARM_64BIT); 259 break; 260 default: 261 return; 262 } 263 if (!ip) { /* no intparm: unsolicited interrupt */ 264 MESSAGE(KERN_DEBUG, "%s", "caught unsolicited interrupt"); 265 return; 266 } 267 cqr = (struct dasd_ccw_req *) ip; 268 device = (struct dasd_device *) cqr->device; 269 if (strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) { 270 DEV_MESSAGE(KERN_WARNING, device, 271 " magic number of dasd_ccw_req 0x%08X doesn't" 272 " match discipline 0x%08X", 273 cqr->magic, *(int *) (&device->discipline->name)); 274 return; 275 } 276 277 /* get irq lock to modify request queue */ 278 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); 279 280 /* Check for a pending clear operation */ 281 if (cqr->status == DASD_CQR_CLEAR) { 282 cqr->status = DASD_CQR_QUEUED; 283 dasd_clear_timer(device); 284 dasd_schedule_bh(device); 285 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); 286 return; 287 } 288 289 cqr->stopclk = get_clock(); 290 291 expires = 0; 292 if (status == 0) { 293 cqr->status = DASD_CQR_DONE; 294 /* Start first request on queue if possible -> fast_io. */ 295 if (!list_empty(&device->ccw_queue)) { 296 next = list_entry(device->ccw_queue.next, 297 struct dasd_ccw_req, list); 298 if (next->status == DASD_CQR_QUEUED) { 299 rc = dasd_start_diag(next); 300 if (rc == 0) 301 expires = next->expires; 302 else if (rc != -EACCES) 303 DEV_MESSAGE(KERN_WARNING, device, "%s", 304 "Interrupt fastpath " 305 "failed!"); 306 } 307 } 308 } else { 309 cqr->status = DASD_CQR_QUEUED; 310 DEV_MESSAGE(KERN_WARNING, device, "interrupt status for " 311 "request %p was %d (%d retries left)", cqr, status, 312 cqr->retries); 313 dasd_diag_erp(device); 314 } 315 316 if (expires != 0) 317 dasd_set_timer(device, expires); 318 else 319 dasd_clear_timer(device); 320 dasd_schedule_bh(device); 321 322 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); 323 } 324 325 /* Check whether device can be controlled by DIAG discipline. Return zero on 326 * success, non-zero otherwise. */ 327 static int 328 dasd_diag_check_device(struct dasd_device *device) 329 { 330 struct dasd_diag_private *private; 331 struct dasd_diag_characteristics *rdc_data; 332 struct dasd_diag_bio bio; 333 struct vtoc_cms_label *label; 334 blocknum_t end_block; 335 unsigned int sb, bsize; 336 int rc; 337 338 private = (struct dasd_diag_private *) device->private; 339 if (private == NULL) { 340 private = kmalloc(sizeof(struct dasd_diag_private),GFP_KERNEL); 341 if (private == NULL) { 342 DEV_MESSAGE(KERN_WARNING, device, "%s", 343 "memory allocation failed for private data"); 344 return -ENOMEM; 345 } 346 device->private = (void *) private; 347 } 348 /* Read Device Characteristics */ 349 rdc_data = (void *) &(private->rdc_data); 350 rdc_data->dev_nr = _ccw_device_get_device_number(device->cdev); 351 rdc_data->rdc_len = sizeof (struct dasd_diag_characteristics); 352 353 rc = diag210((struct diag210 *) rdc_data); 354 if (rc) { 355 DEV_MESSAGE(KERN_WARNING, device, "failed to retrieve device " 356 "information (rc=%d)", rc); 357 return -ENOTSUPP; 358 } 359 360 /* Figure out position of label block */ 361 switch (private->rdc_data.vdev_class) { 362 case DEV_CLASS_FBA: 363 private->pt_block = 1; 364 break; 365 case DEV_CLASS_ECKD: 366 private->pt_block = 2; 367 break; 368 default: 369 DEV_MESSAGE(KERN_WARNING, device, "unsupported device class " 370 "(class=%d)", private->rdc_data.vdev_class); 371 return -ENOTSUPP; 372 } 373 374 DBF_DEV_EVENT(DBF_INFO, device, 375 "%04X: %04X on real %04X/%02X", 376 rdc_data->dev_nr, 377 rdc_data->vdev_type, 378 rdc_data->rdev_type, rdc_data->rdev_model); 379 380 /* terminate all outstanding operations */ 381 mdsk_term_io(device); 382 383 /* figure out blocksize of device */ 384 label = (struct vtoc_cms_label *) get_zeroed_page(GFP_KERNEL); 385 if (label == NULL) { 386 DEV_MESSAGE(KERN_WARNING, device, "%s", 387 "No memory to allocate initialization request"); 388 return -ENOMEM; 389 } 390 rc = 0; 391 end_block = 0; 392 /* try all sizes - needed for ECKD devices */ 393 for (bsize = 512; bsize <= PAGE_SIZE; bsize <<= 1) { 394 mdsk_init_io(device, bsize, 0, &end_block); 395 memset(&bio, 0, sizeof (struct dasd_diag_bio)); 396 bio.type = MDSK_READ_REQ; 397 bio.block_number = private->pt_block + 1; 398 bio.buffer = label; 399 memset(&private->iob, 0, sizeof (struct dasd_diag_rw_io)); 400 private->iob.dev_nr = rdc_data->dev_nr; 401 private->iob.key = 0; 402 private->iob.flags = 0; /* do synchronous io */ 403 private->iob.block_count = 1; 404 private->iob.interrupt_params = 0; 405 private->iob.bio_list = &bio; 406 private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT; 407 rc = dia250(&private->iob, RW_BIO); 408 if (rc == 3) { 409 DEV_MESSAGE(KERN_WARNING, device, "%s", 410 "DIAG call failed"); 411 rc = -EOPNOTSUPP; 412 goto out; 413 } 414 mdsk_term_io(device); 415 if (rc == 0) 416 break; 417 } 418 if (bsize > PAGE_SIZE) { 419 DEV_MESSAGE(KERN_WARNING, device, "device access failed " 420 "(rc=%d)", rc); 421 rc = -EIO; 422 goto out; 423 } 424 /* check for label block */ 425 if (memcmp(label->label_id, DASD_DIAG_CMS1, 426 sizeof(DASD_DIAG_CMS1)) == 0) { 427 /* get formatted blocksize from label block */ 428 bsize = (unsigned int) label->block_size; 429 device->blocks = (unsigned long) label->block_count; 430 } else 431 device->blocks = end_block; 432 device->bp_block = bsize; 433 device->s2b_shift = 0; /* bits to shift 512 to get a block */ 434 for (sb = 512; sb < bsize; sb = sb << 1) 435 device->s2b_shift++; 436 rc = mdsk_init_io(device, device->bp_block, 0, NULL); 437 if (rc) { 438 DEV_MESSAGE(KERN_WARNING, device, "DIAG initialization " 439 "failed (rc=%d)", rc); 440 rc = -EIO; 441 } else { 442 DEV_MESSAGE(KERN_INFO, device, 443 "(%ld B/blk): %ldkB", 444 (unsigned long) device->bp_block, 445 (unsigned long) (device->blocks << 446 device->s2b_shift) >> 1); 447 } 448 out: 449 free_page((long) label); 450 return rc; 451 } 452 453 /* Fill in virtual disk geometry for device. Return zero on success, non-zero 454 * otherwise. */ 455 static int 456 dasd_diag_fill_geometry(struct dasd_device *device, struct hd_geometry *geo) 457 { 458 if (dasd_check_blocksize(device->bp_block) != 0) 459 return -EINVAL; 460 geo->cylinders = (device->blocks << device->s2b_shift) >> 10; 461 geo->heads = 16; 462 geo->sectors = 128 >> device->s2b_shift; 463 return 0; 464 } 465 466 static dasd_era_t 467 dasd_diag_examine_error(struct dasd_ccw_req * cqr, struct irb * stat) 468 { 469 return dasd_era_fatal; 470 } 471 472 static dasd_erp_fn_t 473 dasd_diag_erp_action(struct dasd_ccw_req * cqr) 474 { 475 return dasd_default_erp_action; 476 } 477 478 static dasd_erp_fn_t 479 dasd_diag_erp_postaction(struct dasd_ccw_req * cqr) 480 { 481 return dasd_default_erp_postaction; 482 } 483 484 /* Create DASD request from block device request. Return pointer to new 485 * request on success, ERR_PTR otherwise. */ 486 static struct dasd_ccw_req * 487 dasd_diag_build_cp(struct dasd_device * device, struct request *req) 488 { 489 struct dasd_ccw_req *cqr; 490 struct dasd_diag_req *dreq; 491 struct dasd_diag_bio *dbio; 492 struct bio *bio; 493 struct bio_vec *bv; 494 char *dst; 495 unsigned int count, datasize; 496 sector_t recid, first_rec, last_rec; 497 unsigned int blksize, off; 498 unsigned char rw_cmd; 499 int i; 500 501 if (rq_data_dir(req) == READ) 502 rw_cmd = MDSK_READ_REQ; 503 else if (rq_data_dir(req) == WRITE) 504 rw_cmd = MDSK_WRITE_REQ; 505 else 506 return ERR_PTR(-EINVAL); 507 blksize = device->bp_block; 508 /* Calculate record id of first and last block. */ 509 first_rec = req->sector >> device->s2b_shift; 510 last_rec = (req->sector + req->nr_sectors - 1) >> device->s2b_shift; 511 /* Check struct bio and count the number of blocks for the request. */ 512 count = 0; 513 rq_for_each_bio(bio, req) { 514 bio_for_each_segment(bv, bio, i) { 515 if (bv->bv_len & (blksize - 1)) 516 /* Fba can only do full blocks. */ 517 return ERR_PTR(-EINVAL); 518 count += bv->bv_len >> (device->s2b_shift + 9); 519 } 520 } 521 /* Paranoia. */ 522 if (count != last_rec - first_rec + 1) 523 return ERR_PTR(-EINVAL); 524 /* Build the request */ 525 datasize = sizeof(struct dasd_diag_req) + 526 count*sizeof(struct dasd_diag_bio); 527 cqr = dasd_smalloc_request(dasd_diag_discipline.name, 0, 528 datasize, device); 529 if (IS_ERR(cqr)) 530 return cqr; 531 532 dreq = (struct dasd_diag_req *) cqr->data; 533 dreq->block_count = count; 534 dbio = dreq->bio; 535 recid = first_rec; 536 rq_for_each_bio(bio, req) { 537 bio_for_each_segment(bv, bio, i) { 538 dst = page_address(bv->bv_page) + bv->bv_offset; 539 for (off = 0; off < bv->bv_len; off += blksize) { 540 memset(dbio, 0, sizeof (struct dasd_diag_bio)); 541 dbio->type = rw_cmd; 542 dbio->block_number = recid + 1; 543 dbio->buffer = dst; 544 dbio++; 545 dst += blksize; 546 recid++; 547 } 548 } 549 } 550 cqr->retries = DIAG_MAX_RETRIES; 551 cqr->buildclk = get_clock(); 552 if (req->flags & REQ_FAILFAST) 553 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); 554 cqr->device = device; 555 cqr->expires = DIAG_TIMEOUT; 556 cqr->status = DASD_CQR_FILLED; 557 return cqr; 558 } 559 560 /* Release DASD request. Return non-zero if request was successful, zero 561 * otherwise. */ 562 static int 563 dasd_diag_free_cp(struct dasd_ccw_req *cqr, struct request *req) 564 { 565 int status; 566 567 status = cqr->status == DASD_CQR_DONE; 568 dasd_sfree_request(cqr, cqr->device); 569 return status; 570 } 571 572 /* Fill in IOCTL data for device. */ 573 static int 574 dasd_diag_fill_info(struct dasd_device * device, 575 struct dasd_information2_t * info) 576 { 577 struct dasd_diag_private *private; 578 579 private = (struct dasd_diag_private *) device->private; 580 info->label_block = (unsigned int) private->pt_block; 581 info->FBA_layout = 1; 582 info->format = DASD_FORMAT_LDL; 583 info->characteristics_size = sizeof (struct dasd_diag_characteristics); 584 memcpy(info->characteristics, 585 &((struct dasd_diag_private *) device->private)->rdc_data, 586 sizeof (struct dasd_diag_characteristics)); 587 info->confdata_size = 0; 588 return 0; 589 } 590 591 static void 592 dasd_diag_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req, 593 struct irb *stat) 594 { 595 DEV_MESSAGE(KERN_ERR, device, "%s", 596 "dump sense not available for DIAG data"); 597 } 598 599 struct dasd_discipline dasd_diag_discipline = { 600 .owner = THIS_MODULE, 601 .name = "DIAG", 602 .ebcname = "DIAG", 603 .max_blocks = DIAG_MAX_BLOCKS, 604 .check_device = dasd_diag_check_device, 605 .fill_geometry = dasd_diag_fill_geometry, 606 .start_IO = dasd_start_diag, 607 .term_IO = dasd_diag_term_IO, 608 .examine_error = dasd_diag_examine_error, 609 .erp_action = dasd_diag_erp_action, 610 .erp_postaction = dasd_diag_erp_postaction, 611 .build_cp = dasd_diag_build_cp, 612 .free_cp = dasd_diag_free_cp, 613 .dump_sense = dasd_diag_dump_sense, 614 .fill_info = dasd_diag_fill_info, 615 }; 616 617 static int __init 618 dasd_diag_init(void) 619 { 620 if (!MACHINE_IS_VM) { 621 MESSAGE_LOG(KERN_INFO, 622 "Machine is not VM: %s " 623 "discipline not initializing", 624 dasd_diag_discipline.name); 625 return -ENODEV; 626 } 627 ASCEBC(dasd_diag_discipline.ebcname, 4); 628 629 ctl_set_bit(0, 9); 630 register_external_interrupt(0x2603, dasd_ext_handler); 631 dasd_diag_discipline_pointer = &dasd_diag_discipline; 632 return 0; 633 } 634 635 static void __exit 636 dasd_diag_cleanup(void) 637 { 638 unregister_external_interrupt(0x2603, dasd_ext_handler); 639 ctl_clear_bit(0, 9); 640 dasd_diag_discipline_pointer = NULL; 641 } 642 643 module_init(dasd_diag_init); 644 module_exit(dasd_diag_cleanup); 645