Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

NTB: Handle 64bit BAR sizes

64bit BAR sizes are permissible with an NTB device. To support them
various modifications and clean-ups were required, most significantly
using 2 32bit scratch pad registers for each BAR.

Also, modify the driver to allow more than 2 Memory Windows.

Signed-off-by: Jon Mason <jon.mason@intel.com>

Jon Mason 113fc505 cc0f868d

+77 -52
+2 -2
drivers/ntb/ntb_hw.c
··· 1027 1027 ndev->mw[i].vbase = 1028 1028 ioremap_wc(pci_resource_start(pdev, MW_TO_BAR(i)), 1029 1029 ndev->mw[i].bar_sz); 1030 - dev_info(&pdev->dev, "MW %d size %d\n", i, 1031 - (u32) pci_resource_len(pdev, MW_TO_BAR(i))); 1030 + dev_info(&pdev->dev, "MW %d size %llu\n", i, 1031 + pci_resource_len(pdev, MW_TO_BAR(i))); 1032 1032 if (!ndev->mw[i].vbase) { 1033 1033 dev_warn(&pdev->dev, "Cannot remap BAR %d\n", 1034 1034 MW_TO_BAR(i));
+75 -50
drivers/ntb/ntb_transport.c
··· 58 58 #include <linux/ntb.h> 59 59 #include "ntb_hw.h" 60 60 61 - #define NTB_TRANSPORT_VERSION 2 61 + #define NTB_TRANSPORT_VERSION 3 62 62 63 63 static unsigned int transport_mtu = 0x401E; 64 64 module_param(transport_mtu, uint, 0644); ··· 173 173 174 174 enum { 175 175 VERSION = 0, 176 - MW0_SZ, 177 - MW1_SZ, 178 - NUM_QPS, 179 176 QP_LINKS, 177 + NUM_QPS, 178 + NUM_MWS, 179 + MW0_SZ_HIGH, 180 + MW0_SZ_LOW, 181 + MW1_SZ_HIGH, 182 + MW1_SZ_LOW, 180 183 MAX_SPAD, 181 184 }; 182 185 ··· 529 526 return 0; 530 527 } 531 528 529 + static void ntb_free_mw(struct ntb_transport *nt, int num_mw) 530 + { 531 + struct ntb_transport_mw *mw = &nt->mw[num_mw]; 532 + struct pci_dev *pdev = ntb_query_pdev(nt->ndev); 533 + 534 + if (!mw->virt_addr) 535 + return; 536 + 537 + dma_free_coherent(&pdev->dev, mw->size, mw->virt_addr, mw->dma_addr); 538 + mw->virt_addr = NULL; 539 + } 540 + 532 541 static void ntb_qp_link_cleanup(struct work_struct *work) 533 542 { 534 543 struct ntb_transport_qp *qp = container_of(work, ··· 619 604 u32 val; 620 605 int rc, i; 621 606 622 - /* send the local info */ 623 - rc = ntb_write_remote_spad(ndev, VERSION, NTB_TRANSPORT_VERSION); 624 - if (rc) { 625 - dev_err(&pdev->dev, "Error writing %x to remote spad %d\n", 626 - 0, VERSION); 627 - goto out; 607 + /* send the local info, in the opposite order of the way we read it */ 608 + for (i = 0; i < NTB_NUM_MW; i++) { 609 + rc = ntb_write_remote_spad(ndev, MW0_SZ_HIGH + (i * 2), 610 + ntb_get_mw_size(ndev, i) >> 32); 611 + if (rc) { 612 + dev_err(&pdev->dev, "Error writing %u to remote spad %d\n", 613 + (u32)(ntb_get_mw_size(ndev, i) >> 32), 614 + MW0_SZ_HIGH + (i * 2)); 615 + goto out; 616 + } 617 + 618 + rc = ntb_write_remote_spad(ndev, MW0_SZ_LOW + (i * 2), 619 + (u32) ntb_get_mw_size(ndev, i)); 620 + if (rc) { 621 + dev_err(&pdev->dev, "Error writing %u to remote spad %d\n", 622 + (u32) ntb_get_mw_size(ndev, i), 623 + MW0_SZ_LOW + (i * 2)); 624 + goto out; 625 + } 628 626 } 629 627 630 - rc = ntb_write_remote_spad(ndev, MW0_SZ, ntb_get_mw_size(ndev, 0)); 628 + rc = ntb_write_remote_spad(ndev, NUM_MWS, NTB_NUM_MW); 631 629 if (rc) { 632 630 dev_err(&pdev->dev, "Error writing %x to remote spad %d\n", 633 - (u32) ntb_get_mw_size(ndev, 0), MW0_SZ); 634 - goto out; 635 - } 636 - 637 - rc = ntb_write_remote_spad(ndev, MW1_SZ, ntb_get_mw_size(ndev, 1)); 638 - if (rc) { 639 - dev_err(&pdev->dev, "Error writing %x to remote spad %d\n", 640 - (u32) ntb_get_mw_size(ndev, 1), MW1_SZ); 631 + NTB_NUM_MW, NUM_MWS); 641 632 goto out; 642 633 } 643 634 ··· 654 633 goto out; 655 634 } 656 635 657 - rc = ntb_read_local_spad(nt->ndev, QP_LINKS, &val); 658 - if (rc) { 659 - dev_err(&pdev->dev, "Error reading spad %d\n", QP_LINKS); 660 - goto out; 661 - } 662 - 663 - rc = ntb_write_remote_spad(ndev, QP_LINKS, val); 636 + rc = ntb_write_remote_spad(ndev, VERSION, NTB_TRANSPORT_VERSION); 664 637 if (rc) { 665 638 dev_err(&pdev->dev, "Error writing %x to remote spad %d\n", 666 - val, QP_LINKS); 639 + NTB_TRANSPORT_VERSION, VERSION); 667 640 goto out; 668 641 } 669 642 ··· 682 667 goto out; 683 668 dev_dbg(&pdev->dev, "Remote max number of qps = %d\n", val); 684 669 685 - rc = ntb_read_remote_spad(ndev, MW0_SZ, &val); 670 + rc = ntb_read_remote_spad(ndev, NUM_MWS, &val); 686 671 if (rc) { 687 - dev_err(&pdev->dev, "Error reading remote spad %d\n", MW0_SZ); 672 + dev_err(&pdev->dev, "Error reading remote spad %d\n", NUM_MWS); 688 673 goto out; 689 674 } 690 675 691 - if (!val) 676 + if (val != NTB_NUM_MW) 692 677 goto out; 693 - dev_dbg(&pdev->dev, "Remote MW0 size = %d\n", val); 678 + dev_dbg(&pdev->dev, "Remote number of mws = %d\n", val); 694 679 695 - rc = ntb_set_mw(nt, 0, val); 696 - if (rc) 697 - goto out; 680 + for (i = 0; i < NTB_NUM_MW; i++) { 681 + u64 val64; 698 682 699 - rc = ntb_read_remote_spad(ndev, MW1_SZ, &val); 700 - if (rc) { 701 - dev_err(&pdev->dev, "Error reading remote spad %d\n", MW1_SZ); 702 - goto out; 683 + rc = ntb_read_remote_spad(ndev, MW0_SZ_HIGH + (i * 2), &val); 684 + if (rc) { 685 + dev_err(&pdev->dev, "Error reading remote spad %d\n", 686 + MW0_SZ_HIGH + (i * 2)); 687 + goto out1; 688 + } 689 + 690 + val64 = (u64) val << 32; 691 + 692 + rc = ntb_read_remote_spad(ndev, MW0_SZ_LOW + (i * 2), &val); 693 + if (rc) { 694 + dev_err(&pdev->dev, "Error reading remote spad %d\n", 695 + MW0_SZ_LOW + (i * 2)); 696 + goto out1; 697 + } 698 + 699 + val64 |= val; 700 + 701 + dev_dbg(&pdev->dev, "Remote MW%d size = %llu\n", i, val64); 702 + 703 + rc = ntb_set_mw(nt, i, val64); 704 + if (rc) 705 + goto out1; 703 706 } 704 - 705 - if (!val) 706 - goto out; 707 - dev_dbg(&pdev->dev, "Remote MW1 size = %d\n", val); 708 - 709 - rc = ntb_set_mw(nt, 1, val); 710 - if (rc) 711 - goto out; 712 707 713 708 nt->transport_link = NTB_LINK_UP; 714 709 ··· 733 708 734 709 return; 735 710 711 + out1: 712 + for (i = 0; i < NTB_NUM_MW; i++) 713 + ntb_free_mw(nt, i); 736 714 out: 737 715 if (ntb_hw_link_status(ndev)) 738 716 schedule_delayed_work(&nt->link_work, ··· 925 897 pdev = ntb_query_pdev(nt->ndev); 926 898 927 899 for (i = 0; i < NTB_NUM_MW; i++) 928 - if (nt->mw[i].virt_addr) 929 - dma_free_coherent(&pdev->dev, nt->mw[i].size, 930 - nt->mw[i].virt_addr, 931 - nt->mw[i].dma_addr); 900 + ntb_free_mw(nt, i); 932 901 933 902 kfree(nt->qps); 934 903 ntb_unregister_transport(nt->ndev);