| .. | .. | 
|---|
| 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 |   */ | 
|---|