| .. | .. |
|---|
| 58 | 58 | |
|---|
| 59 | 59 | struct dasd_diag_req { |
|---|
| 60 | 60 | unsigned int block_count; |
|---|
| 61 | | - struct dasd_diag_bio bio[0]; |
|---|
| 61 | + struct dasd_diag_bio bio[]; |
|---|
| 62 | 62 | }; |
|---|
| 63 | 63 | |
|---|
| 64 | 64 | static const u8 DASD_DIAG_CMS1[] = { 0xc3, 0xd4, 0xe2, 0xf1 };/* EBCDIC CMS1 */ |
|---|
| .. | .. |
|---|
| 319 | 319 | struct dasd_diag_characteristics *rdc_data; |
|---|
| 320 | 320 | struct vtoc_cms_label *label; |
|---|
| 321 | 321 | struct dasd_block *block; |
|---|
| 322 | | - struct dasd_diag_bio bio; |
|---|
| 322 | + struct dasd_diag_bio *bio; |
|---|
| 323 | 323 | unsigned int sb, bsize; |
|---|
| 324 | 324 | blocknum_t end_block; |
|---|
| 325 | 325 | int rc; |
|---|
| .. | .. |
|---|
| 395 | 395 | rc = -ENOMEM; |
|---|
| 396 | 396 | goto out; |
|---|
| 397 | 397 | } |
|---|
| 398 | + bio = kzalloc(sizeof(*bio), GFP_KERNEL); |
|---|
| 399 | + if (bio == NULL) { |
|---|
| 400 | + DBF_DEV_EVENT(DBF_WARNING, device, "%s", |
|---|
| 401 | + "No memory to allocate initialization bio"); |
|---|
| 402 | + rc = -ENOMEM; |
|---|
| 403 | + goto out_label; |
|---|
| 404 | + } |
|---|
| 398 | 405 | rc = 0; |
|---|
| 399 | 406 | end_block = 0; |
|---|
| 400 | 407 | /* try all sizes - needed for ECKD devices */ |
|---|
| 401 | 408 | for (bsize = 512; bsize <= PAGE_SIZE; bsize <<= 1) { |
|---|
| 402 | 409 | mdsk_init_io(device, bsize, 0, &end_block); |
|---|
| 403 | | - memset(&bio, 0, sizeof (struct dasd_diag_bio)); |
|---|
| 404 | | - bio.type = MDSK_READ_REQ; |
|---|
| 405 | | - bio.block_number = private->pt_block + 1; |
|---|
| 406 | | - bio.buffer = label; |
|---|
| 410 | + memset(bio, 0, sizeof(*bio)); |
|---|
| 411 | + bio->type = MDSK_READ_REQ; |
|---|
| 412 | + bio->block_number = private->pt_block + 1; |
|---|
| 413 | + bio->buffer = label; |
|---|
| 407 | 414 | memset(&private->iob, 0, sizeof (struct dasd_diag_rw_io)); |
|---|
| 408 | 415 | private->iob.dev_nr = rdc_data->dev_nr; |
|---|
| 409 | 416 | private->iob.key = 0; |
|---|
| 410 | 417 | private->iob.flags = 0; /* do synchronous io */ |
|---|
| 411 | 418 | private->iob.block_count = 1; |
|---|
| 412 | 419 | private->iob.interrupt_params = 0; |
|---|
| 413 | | - private->iob.bio_list = &bio; |
|---|
| 420 | + private->iob.bio_list = bio; |
|---|
| 414 | 421 | private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT; |
|---|
| 415 | 422 | rc = dia250(&private->iob, RW_BIO); |
|---|
| 416 | 423 | if (rc == 3) { |
|---|
| 417 | 424 | pr_warn("%s: A 64-bit DIAG call failed\n", |
|---|
| 418 | 425 | dev_name(&device->cdev->dev)); |
|---|
| 419 | 426 | rc = -EOPNOTSUPP; |
|---|
| 420 | | - goto out_label; |
|---|
| 427 | + goto out_bio; |
|---|
| 421 | 428 | } |
|---|
| 422 | 429 | mdsk_term_io(device); |
|---|
| 423 | 430 | if (rc == 0) |
|---|
| .. | .. |
|---|
| 427 | 434 | pr_warn("%s: Accessing the DASD failed because of an incorrect format (rc=%d)\n", |
|---|
| 428 | 435 | dev_name(&device->cdev->dev), rc); |
|---|
| 429 | 436 | rc = -EIO; |
|---|
| 430 | | - goto out_label; |
|---|
| 437 | + goto out_bio; |
|---|
| 431 | 438 | } |
|---|
| 432 | 439 | /* check for label block */ |
|---|
| 433 | 440 | if (memcmp(label->label_id, DASD_DIAG_CMS1, |
|---|
| .. | .. |
|---|
| 457 | 464 | (rc == 4) ? ", read-only device" : ""); |
|---|
| 458 | 465 | rc = 0; |
|---|
| 459 | 466 | } |
|---|
| 467 | +out_bio: |
|---|
| 468 | + kfree(bio); |
|---|
| 460 | 469 | out_label: |
|---|
| 461 | 470 | free_page((long) label); |
|---|
| 462 | 471 | out: |
|---|
| .. | .. |
|---|
| 506 | 515 | struct req_iterator iter; |
|---|
| 507 | 516 | struct bio_vec bv; |
|---|
| 508 | 517 | char *dst; |
|---|
| 509 | | - unsigned int count, datasize; |
|---|
| 518 | + unsigned int count; |
|---|
| 510 | 519 | sector_t recid, first_rec, last_rec; |
|---|
| 511 | 520 | unsigned int blksize, off; |
|---|
| 512 | 521 | unsigned char rw_cmd; |
|---|
| .. | .. |
|---|
| 534 | 543 | if (count != last_rec - first_rec + 1) |
|---|
| 535 | 544 | return ERR_PTR(-EINVAL); |
|---|
| 536 | 545 | /* Build the request */ |
|---|
| 537 | | - datasize = sizeof(struct dasd_diag_req) + |
|---|
| 538 | | - count*sizeof(struct dasd_diag_bio); |
|---|
| 539 | | - cqr = dasd_smalloc_request(DASD_DIAG_MAGIC, 0, datasize, memdev, |
|---|
| 540 | | - blk_mq_rq_to_pdu(req)); |
|---|
| 546 | + cqr = dasd_smalloc_request(DASD_DIAG_MAGIC, 0, struct_size(dreq, bio, count), |
|---|
| 547 | + memdev, blk_mq_rq_to_pdu(req)); |
|---|
| 541 | 548 | if (IS_ERR(cqr)) |
|---|
| 542 | 549 | return cqr; |
|---|
| 543 | 550 | |
|---|
| .. | .. |
|---|
| 615 | 622 | "dump sense not available for DIAG data"); |
|---|
| 616 | 623 | } |
|---|
| 617 | 624 | |
|---|
| 625 | +/* |
|---|
| 626 | + * Initialize block layer request queue. |
|---|
| 627 | + */ |
|---|
| 628 | +static void dasd_diag_setup_blk_queue(struct dasd_block *block) |
|---|
| 629 | +{ |
|---|
| 630 | + unsigned int logical_block_size = block->bp_block; |
|---|
| 631 | + struct request_queue *q = block->request_queue; |
|---|
| 632 | + int max; |
|---|
| 633 | + |
|---|
| 634 | + max = DIAG_MAX_BLOCKS << block->s2b_shift; |
|---|
| 635 | + blk_queue_flag_set(QUEUE_FLAG_NONROT, q); |
|---|
| 636 | + q->limits.max_dev_sectors = max; |
|---|
| 637 | + blk_queue_logical_block_size(q, logical_block_size); |
|---|
| 638 | + blk_queue_max_hw_sectors(q, max); |
|---|
| 639 | + blk_queue_max_segments(q, USHRT_MAX); |
|---|
| 640 | + /* With page sized segments each segment can be translated into one idaw/tidaw */ |
|---|
| 641 | + blk_queue_max_segment_size(q, PAGE_SIZE); |
|---|
| 642 | + blk_queue_segment_boundary(q, PAGE_SIZE - 1); |
|---|
| 643 | +} |
|---|
| 644 | + |
|---|
| 645 | +static int dasd_diag_pe_handler(struct dasd_device *device, __u8 tbvpm) |
|---|
| 646 | +{ |
|---|
| 647 | + return dasd_generic_verify_path(device, tbvpm); |
|---|
| 648 | +} |
|---|
| 649 | + |
|---|
| 618 | 650 | static struct dasd_discipline dasd_diag_discipline = { |
|---|
| 619 | 651 | .owner = THIS_MODULE, |
|---|
| 620 | 652 | .name = "DIAG", |
|---|
| 621 | 653 | .ebcname = "DIAG", |
|---|
| 622 | | - .max_blocks = DIAG_MAX_BLOCKS, |
|---|
| 623 | 654 | .check_device = dasd_diag_check_device, |
|---|
| 624 | | - .verify_path = dasd_generic_verify_path, |
|---|
| 655 | + .pe_handler = dasd_diag_pe_handler, |
|---|
| 625 | 656 | .fill_geometry = dasd_diag_fill_geometry, |
|---|
| 657 | + .setup_blk_queue = dasd_diag_setup_blk_queue, |
|---|
| 626 | 658 | .start_IO = dasd_start_diag, |
|---|
| 627 | 659 | .term_IO = dasd_diag_term_IO, |
|---|
| 628 | 660 | .handle_terminated_request = dasd_diag_handle_terminated_request, |
|---|