| @@ -99,6 +99,7 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); · 98 unmodified lines |
| 99 | 99 | #endif |
| 100 | 100 | |
| 101 | 101 | static void sd_config_discard(struct scsi_disk *, unsigned int); |
| 102 | +static void sd_config_write_same(struct scsi_disk *); |
| 102 | 103 | static int sd_revalidate_disk(struct gendisk *); |
| 103 | 104 | static void sd_unlock_native_capacity(struct gendisk *disk); |
| 104 | 105 | static int sd_probe(struct device *); |
| @@ -395,6 +396,45 @@ sd_store_max_medium_access_timeouts(struct device *dev, · 290 unmodified lines |
| 395 | 396 | return err ? err : count; |
| 396 | 397 | } |
| 397 | 398 | |
| 399 | +static ssize_t |
| 400 | +sd_show_write_same_blocks(struct device *dev, struct device_attribute *attr, |
| 401 | + char *buf) |
| 402 | +{ |
| 403 | + struct scsi_disk *sdkp = to_scsi_disk(dev); |
| 404 | + |
| 405 | + return snprintf(buf, 20, "%u\n", sdkp->max_ws_blocks); |
| 406 | +} |
| 407 | + |
| 408 | +static ssize_t |
| 409 | +sd_store_write_same_blocks(struct device *dev, struct device_attribute *attr, |
| 410 | + const char *buf, size_t count) |
| 411 | +{ |
| 412 | + struct scsi_disk *sdkp = to_scsi_disk(dev); |
| 413 | + struct scsi_device *sdp = sdkp->device; |
| 414 | + unsigned long max; |
| 415 | + int err; |
| 416 | + |
| 417 | + if (!capable(CAP_SYS_ADMIN)) |
| 418 | + return -EACCES; |
| 419 | + |
| 420 | + if (sdp->type != TYPE_DISK) |
| 421 | + return -EINVAL; |
| 422 | + |
| 423 | + err = kstrtoul(buf, 10, &max); |
| 424 | + |
| 425 | + if (err) |
| 426 | + return err; |
| 427 | + |
| 428 | + if (max == 0) |
| 429 | + sdp->no_write_same = 1; |
| 430 | + else if (max <= SD_MAX_WS16_BLOCKS) |
| 431 | + sdkp->max_ws_blocks = max; |
| 432 | + |
| 433 | + sd_config_write_same(sdkp); |
| 434 | + |
| 435 | + return count; |
| 436 | +} |
| 437 | + |
| 398 | 438 | static struct device_attribute sd_disk_attrs[] = { |
| 399 | 439 | __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, |
| 400 | 440 | sd_store_cache_type), |
| @@ -410,6 +450,8 @@ static struct device_attribute sd_disk_attrs[] = { · 9 unmodified lines |
| 410 | 450 | __ATTR(thin_provisioning, S_IRUGO, sd_show_thin_provisioning, NULL), |
| 411 | 451 | __ATTR(provisioning_mode, S_IRUGO|S_IWUSR, sd_show_provisioning_mode, |
| 412 | 452 | sd_store_provisioning_mode), |
| 453 | + __ATTR(max_write_same_blocks, S_IRUGO|S_IWUSR, |
| 454 | + sd_show_write_same_blocks, sd_store_write_same_blocks), |
| 413 | 455 | __ATTR(max_medium_access_timeouts, S_IRUGO|S_IWUSR, |
| 414 | 456 | sd_show_max_medium_access_timeouts, |
| 415 | 457 | sd_store_max_medium_access_timeouts), |
| @@ -561,19 +603,23 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode) · 145 unmodified lines |
| 561 | 603 | return; |
| 562 | 604 | |
| 563 | 605 | case SD_LBP_UNMAP: |
| 564 | | − max_blocks = min_not_zero(sdkp->max_unmap_blocks, 0xffffffff); |
| 606 | + max_blocks = min_not_zero(sdkp->max_unmap_blocks, |
| 607 | + (u32)SD_MAX_WS16_BLOCKS); |
| 565 | 608 | break; |
| 566 | 609 | |
| 567 | 610 | case SD_LBP_WS16: |
| 568 | | − max_blocks = min_not_zero(sdkp->max_ws_blocks, 0xffffffff); |
| 611 | + max_blocks = min_not_zero(sdkp->max_ws_blocks, |
| 612 | + (u32)SD_MAX_WS16_BLOCKS); |
| 569 | 613 | break; |
| 570 | 614 | |
| 571 | 615 | case SD_LBP_WS10: |
| 572 | | − max_blocks = min_not_zero(sdkp->max_ws_blocks, (u32)0xffff); |
| 616 | + max_blocks = min_not_zero(sdkp->max_ws_blocks, |
| 617 | + (u32)SD_MAX_WS10_BLOCKS); |
| 573 | 618 | break; |
| 574 | 619 | |
| 575 | 620 | case SD_LBP_ZERO: |
| 576 | | − max_blocks = min_not_zero(sdkp->max_ws_blocks, (u32)0xffff); |
| 621 | + max_blocks = min_not_zero(sdkp->max_ws_blocks, |
| 622 | + (u32)SD_MAX_WS10_BLOCKS); |
| 577 | 623 | q->limits.discard_zeroes_data = 1; |
| 578 | 624 | break; |
| 579 | 625 | } |
| @@ -583,29 +629,26 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode) · 3 unmodified lines |
| 583 | 629 | } |
| 584 | 630 | |
| 585 | 631 | /** |
| 586 | | − * scsi_setup_discard_cmnd - unmap blocks on thinly provisioned device |
| 632 | + * sd_setup_discard_cmnd - unmap blocks on thinly provisioned device |
| 587 | 633 | * @sdp: scsi device to operate one |
| 588 | 634 | * @rq: Request to prepare |
| 589 | 635 | * |
| 590 | 636 | * Will issue either UNMAP or WRITE SAME(16) depending on preference |
| 591 | 637 | * indicated by target device. |
| 592 | 638 | **/ |
| 593 | | −static int scsi_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) |
| 639 | +static int sd_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) |
| 594 | 640 | { |
| 595 | 641 | struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); |
| 596 | | − struct bio *bio = rq->bio; |
| 597 | | − sector_t sector = bio->bi_sector; |
| 598 | | − unsigned int nr_sectors = bio_sectors(bio); |
| 642 | + sector_t sector = blk_rq_pos(rq); |
| 643 | + unsigned int nr_sectors = blk_rq_sectors(rq); |
| 644 | + unsigned int nr_bytes = blk_rq_bytes(rq); |
| 599 | 645 | unsigned int len; |
| 600 | 646 | int ret; |
| 601 | 647 | char *buf; |
| 602 | 648 | struct page *page; |
| 603 | 649 | |
| 604 | | − if (sdkp->device->sector_size == 4096) { |
| 605 | | − sector >>= 3; |
| 606 | | − nr_sectors >>= 3; |
| 607 | | − } |
| 608 | | − |
| 650 | + sector >>= ilog2(sdp->sector_size) - 9; |
| 651 | + nr_sectors >>= ilog2(sdp->sector_size) - 9; |
| 609 | 652 | rq->timeout = SD_TIMEOUT; |
| 610 | 653 | |
| 611 | 654 | memset(rq->cmd, 0, rq->cmd_len); |
| @@ -660,6 +703,7 @@ static int scsi_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) · 48 unmodified lines |
| 660 | 703 | blk_add_request_payload(rq, page, len); |
| 661 | 704 | ret = scsi_setup_blk_pc_cmnd(sdp, rq); |
| 662 | 705 | rq->buffer = page_address(page); |
| 706 | + rq->__data_len = nr_bytes; |
| 663 | 707 | |
| 664 | 708 | out: |
| 665 | 709 | if (ret != BLKPREP_OK) { |
| @@ -669,6 +713,83 @@ out: · 3 unmodified lines |
| 669 | 713 | return ret; |
| 670 | 714 | } |
| 671 | 715 | |
| 716 | +static void sd_config_write_same(struct scsi_disk *sdkp) |
| 717 | +{ |
| 718 | + struct request_queue *q = sdkp->disk->queue; |
| 719 | + unsigned int logical_block_size = sdkp->device->sector_size; |
| 720 | + unsigned int blocks = 0; |
| 721 | + |
| 722 | + if (sdkp->device->no_write_same) { |
| 723 | + sdkp->max_ws_blocks = 0; |
| 724 | + goto out; |
| 725 | + } |
| 726 | + |
| 727 | + /* Some devices can not handle block counts above 0xffff despite |
| 728 | + * supporting WRITE SAME(16). Consequently we default to 64k |
| 729 | + * blocks per I/O unless the device explicitly advertises a |
| 730 | + * bigger limit. |
| 731 | + */ |
| 732 | + if (sdkp->max_ws_blocks == 0) |
| 733 | + sdkp->max_ws_blocks = SD_MAX_WS10_BLOCKS; |
| 734 | + |
| 735 | + if (sdkp->ws16 || sdkp->max_ws_blocks > SD_MAX_WS10_BLOCKS) |
| 736 | + blocks = min_not_zero(sdkp->max_ws_blocks, |
| 737 | + (u32)SD_MAX_WS16_BLOCKS); |
| 738 | + else |
| 739 | + blocks = min_not_zero(sdkp->max_ws_blocks, |
| 740 | + (u32)SD_MAX_WS10_BLOCKS); |
| 741 | + |
| 742 | +out: |
| 743 | + blk_queue_max_write_same_sectors(q, blocks * (logical_block_size >> 9)); |
| 744 | +} |
| 745 | + |
| 746 | +/** |
| 747 | + * sd_setup_write_same_cmnd - write the same data to multiple blocks |
| 748 | + * @sdp: scsi device to operate one |
| 749 | + * @rq: Request to prepare |
| 750 | + * |
| 751 | + * Will issue either WRITE SAME(10) or WRITE SAME(16) depending on |
| 752 | + * preference indicated by target device. |
| 753 | + **/ |
| 754 | +static int sd_setup_write_same_cmnd(struct scsi_device *sdp, struct request *rq) |
| 755 | +{ |
| 756 | + struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); |
| 757 | + struct bio *bio = rq->bio; |
| 758 | + sector_t sector = blk_rq_pos(rq); |
| 759 | + unsigned int nr_sectors = blk_rq_sectors(rq); |
| 760 | + unsigned int nr_bytes = blk_rq_bytes(rq); |
| 761 | + int ret; |
| 762 | + |
| 763 | + if (sdkp->device->no_write_same) |
| 764 | + return BLKPREP_KILL; |
| 765 | + |
| 766 | + BUG_ON(bio_offset(bio) || bio_iovec(bio)->bv_len != sdp->sector_size); |
| 767 | + |
| 768 | + sector >>= ilog2(sdp->sector_size) - 9; |
| 769 | + nr_sectors >>= ilog2(sdp->sector_size) - 9; |
| 770 | + |
| 771 | + rq->__data_len = sdp->sector_size; |
| 772 | + rq->timeout = SD_WRITE_SAME_TIMEOUT; |
| 773 | + memset(rq->cmd, 0, rq->cmd_len); |
| 774 | + |
| 775 | + if (sdkp->ws16 || sector > 0xffffffff || nr_sectors > 0xffff) { |
| 776 | + rq->cmd_len = 16; |
| 777 | + rq->cmd[0] = WRITE_SAME_16; |
| 778 | + put_unaligned_be64(sector, &rq->cmd[2]); |
| 779 | + put_unaligned_be32(nr_sectors, &rq->cmd[10]); |
| 780 | + } else { |
| 781 | + rq->cmd_len = 10; |
| 782 | + rq->cmd[0] = WRITE_SAME; |
| 783 | + put_unaligned_be32(sector, &rq->cmd[2]); |
| 784 | + put_unaligned_be16(nr_sectors, &rq->cmd[7]); |
| 785 | + } |
| 786 | + |
| 787 | + ret = scsi_setup_blk_pc_cmnd(sdp, rq); |
| 788 | + rq->__data_len = nr_bytes; |
| 789 | + |
| 790 | + return ret; |
| 791 | +} |
| 792 | + |
| 672 | 793 | static int scsi_setup_flush_cmnd(struct scsi_device *sdp, struct request *rq) |
| 673 | 794 | { |
| 674 | 795 | rq->timeout = SD_FLUSH_TIMEOUT; |
| @@ -712,7 +833,10 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) · 37 unmodified lines |
| 712 | 833 | * block PC requests to make life easier. |
| 713 | 834 | */ |
| 714 | 835 | if (rq->cmd_flags & REQ_DISCARD) { |
| 715 | | − ret = scsi_setup_discard_cmnd(sdp, rq); |
| 836 | + ret = sd_setup_discard_cmnd(sdp, rq); |
| 837 | + goto out; |
| 838 | + } else if (rq->cmd_flags & REQ_WRITE_SAME) { |
| 839 | + ret = sd_setup_write_same_cmnd(sdp, rq); |
| 716 | 840 | goto out; |
| 717 | 841 | } else if (rq->cmd_flags & REQ_FLUSH) { |
| 718 | 842 | ret = scsi_setup_flush_cmnd(sdp, rq); |
| @@ -1482,12 +1606,21 @@ static int sd_done(struct scsi_cmnd *SCpnt) · 763 unmodified lines |
| 1482 | 1606 | unsigned int good_bytes = result ? 0 : scsi_bufflen(SCpnt); |
| 1483 | 1607 | struct scsi_sense_hdr sshdr; |
| 1484 | 1608 | struct scsi_disk *sdkp = scsi_disk(SCpnt->request->rq_disk); |
| 1609 | + struct request *req = SCpnt->request; |
| 1485 | 1610 | int sense_valid = 0; |
| 1486 | 1611 | int sense_deferred = 0; |
| 1487 | 1612 | unsigned char op = SCpnt->cmnd[0]; |
| 1613 | + unsigned char unmap = SCpnt->cmnd[1] & 8; |
| 1488 | 1614 | |
| 1489 | | − if ((SCpnt->request->cmd_flags & REQ_DISCARD) && !result) |
| 1490 | | − scsi_set_resid(SCpnt, 0); |
| 1615 | + if (req->cmd_flags & REQ_DISCARD || req->cmd_flags & REQ_WRITE_SAME) { |
| 1616 | + if (!result) { |
| 1617 | + good_bytes = blk_rq_bytes(req); |
| 1618 | + scsi_set_resid(SCpnt, 0); |
| 1619 | + } else { |
| 1620 | + good_bytes = 0; |
| 1621 | + scsi_set_resid(SCpnt, blk_rq_bytes(req)); |
| 1622 | + } |
| 1623 | + } |
| 1491 | 1624 | |
| 1492 | 1625 | if (result) { |
| 1493 | 1626 | sense_valid = scsi_command_normalize_sense(SCpnt, &sshdr); |
| @@ -1536,9 +1669,25 @@ static int sd_done(struct scsi_cmnd *SCpnt) · 42 unmodified lines |
| 1536 | 1669 | if (sshdr.asc == 0x10) /* DIX: Host detected corruption */ |
| 1537 | 1670 | good_bytes = sd_completed_bytes(SCpnt); |
| 1538 | 1671 | /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */ |
| 1539 | | − if ((sshdr.asc == 0x20 || sshdr.asc == 0x24) && |
| 1540 | | − (op == UNMAP || op == WRITE_SAME_16 || op == WRITE_SAME)) |
| 1541 | | − sd_config_discard(sdkp, SD_LBP_DISABLE); |
| 1672 | + if (sshdr.asc == 0x20 || sshdr.asc == 0x24) { |
| 1673 | + switch (op) { |
| 1674 | + case UNMAP: |
| 1675 | + sd_config_discard(sdkp, SD_LBP_DISABLE); |
| 1676 | + break; |
| 1677 | + case WRITE_SAME_16: |
| 1678 | + case WRITE_SAME: |
| 1679 | + if (unmap) |
| 1680 | + sd_config_discard(sdkp, SD_LBP_DISABLE); |
| 1681 | + else { |
| 1682 | + sdkp->device->no_write_same = 1; |
| 1683 | + sd_config_write_same(sdkp); |
| 1684 | + |
| 1685 | + good_bytes = 0; |
| 1686 | + req->__data_len = blk_rq_bytes(req); |
| 1687 | + req->cmd_flags |= REQ_QUIET; |
| 1688 | + } |
| 1689 | + } |
| 1690 | + } |
| 1542 | 1691 | break; |
| 1543 | 1692 | default: |
| 1544 | 1693 | break; |
| @@ -2374,9 +2523,7 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) · 829 unmodified lines |
| 2374 | 2523 | if (buffer[3] == 0x3c) { |
| 2375 | 2524 | unsigned int lba_count, desc_count; |
| 2376 | 2525 | |
| 2377 | | − sdkp->max_ws_blocks = |
| 2378 | | − (u32) min_not_zero(get_unaligned_be64(&buffer[36]), |
| 2379 | | − (u64)0xffffffff); |
| 2526 | + sdkp->max_ws_blocks = (u32)get_unaligned_be64(&buffer[36]); |
| 2380 | 2527 | |
| 2381 | 2528 | if (!sdkp->lbpme) |
| 2382 | 2529 | goto out; |
| @@ -2469,6 +2616,13 @@ static void sd_read_block_provisioning(struct scsi_disk *sdkp) · 86 unmodified lines |
| 2469 | 2616 | kfree(buffer); |
| 2470 | 2617 | } |
| 2471 | 2618 | |
| 2619 | +static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer) |
| 2620 | +{ |
| 2621 | + if (scsi_report_opcode(sdkp->device, buffer, SD_BUF_SIZE, |
| 2622 | + WRITE_SAME_16)) |
| 2623 | + sdkp->ws16 = 1; |
| 2624 | +} |
| 2625 | + |
| 2472 | 2626 | static int sd_try_extended_inquiry(struct scsi_device *sdp) |
| 2473 | 2627 | { |
| 2474 | 2628 | /* |
| @@ -2528,6 +2682,7 @@ static int sd_revalidate_disk(struct gendisk *disk) · 53 unmodified lines |
| 2528 | 2682 | sd_read_write_protect_flag(sdkp, buffer); |
| 2529 | 2683 | sd_read_cache_type(sdkp, buffer); |
| 2530 | 2684 | sd_read_app_tag_own(sdkp, buffer); |
| 2685 | + sd_read_write_same(sdkp, buffer); |
| 2531 | 2686 | } |
| 2532 | 2687 | |
| 2533 | 2688 | sdkp->first_scan = 0; |
| @@ -2545,6 +2700,7 @@ static int sd_revalidate_disk(struct gendisk *disk) · 11 unmodified lines |
| 2545 | 2700 | blk_queue_flush(sdkp->disk->queue, flush); |
| 2546 | 2701 | |
| 2547 | 2702 | set_capacity(disk, sdkp->capacity); |
| 2703 | + sd_config_write_same(sdkp); |
| 2548 | 2704 | kfree(buffer); |
| 2549 | 2705 | |
| 2550 | 2706 | out: |