.. | .. |
---|
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, |
---|