| .. | .. |
|---|
| 1 | | -/** |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 2 | +/* |
|---|
| 2 | 3 | * IBM Accelerator Family 'GenWQE' |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * (C) Copyright IBM Corp. 2013 |
|---|
| .. | .. |
|---|
| 7 | 8 | * Author: Joerg-Stephan Vogt <jsvogt@de.ibm.com> |
|---|
| 8 | 9 | * Author: Michael Jung <mijung@gmx.net> |
|---|
| 9 | 10 | * Author: Michael Ruettger <michael@ibmra.de> |
|---|
| 10 | | - * |
|---|
| 11 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 12 | | - * it under the terms of the GNU General Public License (version 2 only) |
|---|
| 13 | | - * as published by the Free Software Foundation. |
|---|
| 14 | | - * |
|---|
| 15 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 16 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 17 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 18 | | - * GNU General Public License for more details. |
|---|
| 19 | 11 | */ |
|---|
| 20 | 12 | |
|---|
| 21 | 13 | /* |
|---|
| .. | .. |
|---|
| 23 | 15 | */ |
|---|
| 24 | 16 | |
|---|
| 25 | 17 | #include <linux/kernel.h> |
|---|
| 26 | | -#include <linux/dma-mapping.h> |
|---|
| 27 | 18 | #include <linux/sched.h> |
|---|
| 28 | 19 | #include <linux/vmalloc.h> |
|---|
| 29 | 20 | #include <linux/page-flags.h> |
|---|
| 30 | 21 | #include <linux/scatterlist.h> |
|---|
| 31 | 22 | #include <linux/hugetlb.h> |
|---|
| 32 | 23 | #include <linux/iommu.h> |
|---|
| 33 | | -#include <linux/delay.h> |
|---|
| 34 | 24 | #include <linux/pci.h> |
|---|
| 35 | 25 | #include <linux/dma-mapping.h> |
|---|
| 36 | 26 | #include <linux/ctype.h> |
|---|
| 37 | 27 | #include <linux/module.h> |
|---|
| 38 | 28 | #include <linux/platform_device.h> |
|---|
| 39 | 29 | #include <linux/delay.h> |
|---|
| 40 | | -#include <asm/pgtable.h> |
|---|
| 30 | +#include <linux/pgtable.h> |
|---|
| 41 | 31 | |
|---|
| 42 | 32 | #include "genwqe_driver.h" |
|---|
| 43 | 33 | #include "card_base.h" |
|---|
| .. | .. |
|---|
| 139 | 129 | |
|---|
| 140 | 130 | /** |
|---|
| 141 | 131 | * genwqe_read_app_id() - Extract app_id |
|---|
| 132 | + * @cd: genwqe device descriptor |
|---|
| 133 | + * @app_name: carrier used to pass-back name |
|---|
| 134 | + * @len: length of data for name |
|---|
| 142 | 135 | * |
|---|
| 143 | 136 | * app_unitcfg need to be filled with valid data first |
|---|
| 144 | 137 | */ |
|---|
| .. | .. |
|---|
| 193 | 186 | * @init: initial crc (0xffffffff at start) |
|---|
| 194 | 187 | * |
|---|
| 195 | 188 | * polynomial = x^32 * + x^29 + x^18 + x^14 + x^3 + 1 (0x20044009) |
|---|
| 196 | | - |
|---|
| 189 | + * |
|---|
| 197 | 190 | * Example: 4 bytes 0x01 0x02 0x03 0x04 with init=0xffffffff should |
|---|
| 198 | 191 | * result in a crc32 of 0xf33cb7d3. |
|---|
| 199 | 192 | * |
|---|
| .. | .. |
|---|
| 220 | 213 | if (get_order(size) >= MAX_ORDER) |
|---|
| 221 | 214 | return NULL; |
|---|
| 222 | 215 | |
|---|
| 223 | | - return dma_zalloc_coherent(&cd->pci_dev->dev, size, dma_handle, |
|---|
| 224 | | - GFP_KERNEL); |
|---|
| 216 | + return dma_alloc_coherent(&cd->pci_dev->dev, size, dma_handle, |
|---|
| 217 | + GFP_KERNEL); |
|---|
| 225 | 218 | } |
|---|
| 226 | 219 | |
|---|
| 227 | 220 | void __genwqe_free_consistent(struct genwqe_dev *cd, size_t size, |
|---|
| .. | .. |
|---|
| 287 | 280 | return roundup(len, PAGE_SIZE); |
|---|
| 288 | 281 | } |
|---|
| 289 | 282 | |
|---|
| 290 | | -/** |
|---|
| 283 | +/* |
|---|
| 291 | 284 | * genwqe_alloc_sync_sgl() - Allocate memory for sgl and overlapping pages |
|---|
| 292 | 285 | * |
|---|
| 293 | 286 | * Allocates memory for sgl and overlapping pages. Pages which might |
|---|
| .. | .. |
|---|
| 470 | 463 | |
|---|
| 471 | 464 | /** |
|---|
| 472 | 465 | * genwqe_free_sync_sgl() - Free memory for sgl and overlapping pages |
|---|
| 466 | + * @cd: genwqe device descriptor |
|---|
| 467 | + * @sgl: scatter gather list describing user-space memory |
|---|
| 473 | 468 | * |
|---|
| 474 | 469 | * After the DMA transfer has been completed we free the memory for |
|---|
| 475 | 470 | * the sgl and the cached pages. Data is being transferred from cached |
|---|
| .. | .. |
|---|
| 522 | 517 | sgl->sgl_dma_addr = 0x0; |
|---|
| 523 | 518 | sgl->sgl_size = 0; |
|---|
| 524 | 519 | return rc; |
|---|
| 525 | | -} |
|---|
| 526 | | - |
|---|
| 527 | | -/** |
|---|
| 528 | | - * genwqe_free_user_pages() - Give pinned pages back |
|---|
| 529 | | - * |
|---|
| 530 | | - * Documentation of get_user_pages is in mm/gup.c: |
|---|
| 531 | | - * |
|---|
| 532 | | - * If the page is written to, set_page_dirty (or set_page_dirty_lock, |
|---|
| 533 | | - * as appropriate) must be called after the page is finished with, and |
|---|
| 534 | | - * before put_page is called. |
|---|
| 535 | | - */ |
|---|
| 536 | | -static int genwqe_free_user_pages(struct page **page_list, |
|---|
| 537 | | - unsigned int nr_pages, int dirty) |
|---|
| 538 | | -{ |
|---|
| 539 | | - unsigned int i; |
|---|
| 540 | | - |
|---|
| 541 | | - for (i = 0; i < nr_pages; i++) { |
|---|
| 542 | | - if (page_list[i] != NULL) { |
|---|
| 543 | | - if (dirty) |
|---|
| 544 | | - set_page_dirty_lock(page_list[i]); |
|---|
| 545 | | - put_page(page_list[i]); |
|---|
| 546 | | - } |
|---|
| 547 | | - } |
|---|
| 548 | | - return 0; |
|---|
| 549 | 520 | } |
|---|
| 550 | 521 | |
|---|
| 551 | 522 | /** |
|---|
| .. | .. |
|---|
| 607 | 578 | m->dma_list = (dma_addr_t *)(m->page_list + m->nr_pages); |
|---|
| 608 | 579 | |
|---|
| 609 | 580 | /* pin user pages in memory */ |
|---|
| 610 | | - rc = get_user_pages_fast(data & PAGE_MASK, /* page aligned addr */ |
|---|
| 581 | + rc = pin_user_pages_fast(data & PAGE_MASK, /* page aligned addr */ |
|---|
| 611 | 582 | m->nr_pages, |
|---|
| 612 | | - m->write, /* readable/writable */ |
|---|
| 583 | + m->write ? FOLL_WRITE : 0, /* readable/writable */ |
|---|
| 613 | 584 | m->page_list); /* ptrs to pages */ |
|---|
| 614 | 585 | if (rc < 0) |
|---|
| 615 | | - goto fail_get_user_pages; |
|---|
| 586 | + goto fail_pin_user_pages; |
|---|
| 616 | 587 | |
|---|
| 617 | | - /* assumption: get_user_pages can be killed by signals. */ |
|---|
| 588 | + /* assumption: pin_user_pages can be killed by signals. */ |
|---|
| 618 | 589 | if (rc < m->nr_pages) { |
|---|
| 619 | | - genwqe_free_user_pages(m->page_list, rc, m->write); |
|---|
| 590 | + unpin_user_pages_dirty_lock(m->page_list, rc, m->write); |
|---|
| 620 | 591 | rc = -EFAULT; |
|---|
| 621 | | - goto fail_get_user_pages; |
|---|
| 592 | + goto fail_pin_user_pages; |
|---|
| 622 | 593 | } |
|---|
| 623 | 594 | |
|---|
| 624 | 595 | rc = genwqe_map_pages(cd, m->page_list, m->nr_pages, m->dma_list); |
|---|
| .. | .. |
|---|
| 628 | 599 | return 0; |
|---|
| 629 | 600 | |
|---|
| 630 | 601 | fail_free_user_pages: |
|---|
| 631 | | - genwqe_free_user_pages(m->page_list, m->nr_pages, m->write); |
|---|
| 602 | + unpin_user_pages_dirty_lock(m->page_list, m->nr_pages, m->write); |
|---|
| 632 | 603 | |
|---|
| 633 | | - fail_get_user_pages: |
|---|
| 604 | + fail_pin_user_pages: |
|---|
| 634 | 605 | kfree(m->page_list); |
|---|
| 635 | 606 | m->page_list = NULL; |
|---|
| 636 | 607 | m->dma_list = NULL; |
|---|
| .. | .. |
|---|
| 660 | 631 | genwqe_unmap_pages(cd, m->dma_list, m->nr_pages); |
|---|
| 661 | 632 | |
|---|
| 662 | 633 | if (m->page_list) { |
|---|
| 663 | | - genwqe_free_user_pages(m->page_list, m->nr_pages, m->write); |
|---|
| 664 | | - |
|---|
| 634 | + unpin_user_pages_dirty_lock(m->page_list, m->nr_pages, |
|---|
| 635 | + m->write); |
|---|
| 665 | 636 | kfree(m->page_list); |
|---|
| 666 | 637 | m->page_list = NULL; |
|---|
| 667 | 638 | m->dma_list = NULL; |
|---|
| .. | .. |
|---|
| 744 | 715 | /** |
|---|
| 745 | 716 | * genwqe_set_interrupt_capability() - Configure MSI capability structure |
|---|
| 746 | 717 | * @cd: pointer to the device |
|---|
| 718 | + * @count: number of vectors to allocate |
|---|
| 747 | 719 | * Return: 0 if no error |
|---|
| 748 | 720 | */ |
|---|
| 749 | 721 | int genwqe_set_interrupt_capability(struct genwqe_dev *cd, int count) |
|---|
| .. | .. |
|---|
| 772 | 744 | * @i: index to desired entry |
|---|
| 773 | 745 | * @m: maximum possible entries |
|---|
| 774 | 746 | * @addr: addr which is read |
|---|
| 775 | | - * @index: index in debug array |
|---|
| 747 | + * @idx: index in debug array |
|---|
| 776 | 748 | * @val: read value |
|---|
| 777 | 749 | */ |
|---|
| 778 | 750 | static int set_reg_idx(struct genwqe_dev *cd, struct genwqe_reg *r, |
|---|
| .. | .. |
|---|
| 852 | 824 | |
|---|
| 853 | 825 | /** |
|---|
| 854 | 826 | * genwqe_ffdc_buff_size() - Calculates the number of dump registers |
|---|
| 827 | + * @cd: genwqe device descriptor |
|---|
| 828 | + * @uid: unit ID |
|---|
| 855 | 829 | */ |
|---|
| 856 | 830 | int genwqe_ffdc_buff_size(struct genwqe_dev *cd, int uid) |
|---|
| 857 | 831 | { |
|---|
| .. | .. |
|---|
| 905 | 879 | |
|---|
| 906 | 880 | /** |
|---|
| 907 | 881 | * genwqe_ffdc_buff_read() - Implements LogoutExtendedErrorRegisters procedure |
|---|
| 882 | + * @cd: genwqe device descriptor |
|---|
| 883 | + * @uid: unit ID |
|---|
| 884 | + * @regs: register information |
|---|
| 885 | + * @max_regs: number of register entries |
|---|
| 908 | 886 | */ |
|---|
| 909 | 887 | int genwqe_ffdc_buff_read(struct genwqe_dev *cd, int uid, |
|---|
| 910 | 888 | struct genwqe_reg *regs, unsigned int max_regs) |
|---|
| .. | .. |
|---|
| 990 | 968 | |
|---|
| 991 | 969 | /** |
|---|
| 992 | 970 | * genwqe_write_vreg() - Write register in virtual window |
|---|
| 971 | + * @cd: genwqe device descriptor |
|---|
| 972 | + * @reg: register (byte) offset within BAR |
|---|
| 973 | + * @val: value to write |
|---|
| 974 | + * @func: PCI virtual function |
|---|
| 993 | 975 | * |
|---|
| 994 | 976 | * Note, these registers are only accessible to the PF through the |
|---|
| 995 | 977 | * VF-window. It is not intended for the VF to access. |
|---|
| .. | .. |
|---|
| 1003 | 985 | |
|---|
| 1004 | 986 | /** |
|---|
| 1005 | 987 | * genwqe_read_vreg() - Read register in virtual window |
|---|
| 988 | + * @cd: genwqe device descriptor |
|---|
| 989 | + * @reg: register (byte) offset within BAR |
|---|
| 990 | + * @func: PCI virtual function |
|---|
| 1006 | 991 | * |
|---|
| 1007 | 992 | * Note, these registers are only accessible to the PF through the |
|---|
| 1008 | 993 | * VF-window. It is not intended for the VF to access. |
|---|
| .. | .. |
|---|
| 1015 | 1000 | |
|---|
| 1016 | 1001 | /** |
|---|
| 1017 | 1002 | * genwqe_base_clock_frequency() - Deteremine base clock frequency of the card |
|---|
| 1003 | + * @cd: genwqe device descriptor |
|---|
| 1018 | 1004 | * |
|---|
| 1019 | 1005 | * Note: From a design perspective it turned out to be a bad idea to |
|---|
| 1020 | 1006 | * use codes here to specifiy the frequency/speed values. An old |
|---|
| .. | .. |
|---|
| 1039 | 1025 | |
|---|
| 1040 | 1026 | /** |
|---|
| 1041 | 1027 | * genwqe_stop_traps() - Stop traps |
|---|
| 1028 | + * @cd: genwqe device descriptor |
|---|
| 1042 | 1029 | * |
|---|
| 1043 | 1030 | * Before reading out the analysis data, we need to stop the traps. |
|---|
| 1044 | 1031 | */ |
|---|
| .. | .. |
|---|
| 1049 | 1036 | |
|---|
| 1050 | 1037 | /** |
|---|
| 1051 | 1038 | * genwqe_start_traps() - Start traps |
|---|
| 1039 | + * @cd: genwqe device descriptor |
|---|
| 1052 | 1040 | * |
|---|
| 1053 | 1041 | * After having read the data, we can/must enable the traps again. |
|---|
| 1054 | 1042 | */ |
|---|