diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-01 09:51:57 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-01 09:51:57 -0800 |
commit | 5d8515bc232172963a4cef007e97b08c5e4d0533 (patch) | |
tree | 13e774dbe2d663ca1fbf2a77933ef8deabd4d507 /drivers/staging | |
parent | db5933225f2fe50d3b91ebbba73ed9c3b703b99a (diff) | |
parent | 3384e01179eff2b2fe91ba7bcad98ee2be5f87f7 (diff) | |
download | linux-5d8515bc232172963a4cef007e97b08c5e4d0533.tar.bz2 |
Merge tag 'staging-4.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging/IIO updates from Greg KH:
"Here is the big Staging and IIO driver patches for 4.16-rc1.
There is the normal amount of new IIO drivers added, like all
releases.
The networking IPX and the ncpfs filesystem are moved into the staging
tree, as they are on their way out of the kernel due to lack of use
anymore.
The visorbus subsystem finall has started moving out of the staging
tree to the "real" part of the kernel, and the most and fsl-mc
codebases are almost ready to move out, that will probably happen for
4.17-rc1 if all goes well.
Other than that, there is a bunch of license header cleanups in the
tree, along with the normal amount of coding style churn that we all
know and love for this codebase. I also got frustrated at the
Meltdown/Spectre mess and took it out on the dgnc tty driver, deleting
huge chunks of it that were never even being used.
Full details of everything is in the shortlog.
All of these patches have been in linux-next for a while with no
reported issues"
* tag 'staging-4.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (627 commits)
staging: rtlwifi: remove redundant initialization of 'cfg_cmd'
staging: rtl8723bs: remove a couple of redundant initializations
staging: comedi: reformat lines to 80 chars or less
staging: lustre: separate a connection destroy from free struct kib_conn
Staging: rtl8723bs: Use !x instead of NULL comparison
Staging: rtl8723bs: Remove dead code
Staging: rtl8723bs: Change names to conform to the kernel code
staging: ccree: Fix missing blank line after declaration
staging: rtl8188eu: remove redundant initialization of 'pwrcfgcmd'
staging: rtlwifi: remove unused RTLHALMAC_ST and RTLPHYDM_ST
staging: fbtft: remove unused FB_TFT_SSD1325 kconfig
staging: comedi: dt2811: remove redundant initialization of 'ns'
staging: wilc1000: fix alignments to match open parenthesis
staging: wilc1000: removed unnecessary defined enums typedef
staging: wilc1000: remove unnecessary use of parentheses
staging: rtl8192u: remove redundant initialization of 'timeout'
staging: sm750fb: fix CamelCase for dispSet var
staging: lustre: lnet/selftest: fix compile error on UP build
staging: rtl8723bs: hal_com_phycfg: Remove unneeded semicolons
staging: rts5208: Fix "seg_no" calculation in reset_ms_card()
...
Diffstat (limited to 'drivers/staging')
742 files changed, 21526 insertions, 25978 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 554683912cff..e95ab683331e 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -26,6 +26,10 @@ if STAGING source "drivers/staging/irda/net/Kconfig" +source "drivers/staging/ipx/Kconfig" + +source "drivers/staging/ncpfs/Kconfig" + source "drivers/staging/wlan-ng/Kconfig" source "drivers/staging/comedi/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 6e536020029a..af8cd6a3a1f6 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -3,6 +3,8 @@ obj-y += media/ obj-y += typec/ +obj-$(CONFIG_IPX) += ipx/ +obj-$(CONFIG_NCP_FS) += ncpfs/ obj-$(CONFIG_IRDA) += irda/net/ obj-$(CONFIG_IRDA) += irda/drivers/ obj-$(CONFIG_PRISM2_USB) += wlan-ng/ diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index 372ce9913e6d..bbdc53b686dd 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* mm/ashmem.c * * Anonymous Shared Memory Subsystem, ashmem @@ -5,15 +6,6 @@ * Copyright (C) 2008 Google, Inc. * * Robert Love <rlove@google.com> - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #define pr_fmt(fmt) "ashmem: " fmt @@ -818,7 +810,23 @@ static long compat_ashmem_ioctl(struct file *file, unsigned int cmd, return ashmem_ioctl(file, cmd, arg); } #endif +#ifdef CONFIG_PROC_FS +static void ashmem_show_fdinfo(struct seq_file *m, struct file *file) +{ + struct ashmem_area *asma = file->private_data; + + mutex_lock(&ashmem_mutex); + + if (asma->file) + seq_printf(m, "inode:\t%ld\n", file_inode(asma->file)->i_ino); + + if (asma->name[ASHMEM_NAME_PREFIX_LEN] != '\0') + seq_printf(m, "name:\t%s\n", + asma->name + ASHMEM_NAME_PREFIX_LEN); + mutex_unlock(&ashmem_mutex); +} +#endif static const struct file_operations ashmem_fops = { .owner = THIS_MODULE, .open = ashmem_open, @@ -830,6 +838,9 @@ static const struct file_operations ashmem_fops = { #ifdef CONFIG_COMPAT .compat_ioctl = compat_ashmem_ioctl, #endif +#ifdef CONFIG_PROC_FS + .show_fdinfo = ashmem_show_fdinfo, +#endif }; static struct miscdevice ashmem_misc = { @@ -864,12 +875,18 @@ static int __init ashmem_init(void) goto out_free2; } - register_shrinker(&ashmem_shrinker); + ret = register_shrinker(&ashmem_shrinker); + if (ret) { + pr_err("failed to register shrinker!\n"); + goto out_demisc; + } pr_info("initialized\n"); return 0; +out_demisc: + misc_deregister(&ashmem_misc); out_free2: kmem_cache_destroy(ashmem_range_cachep); out_free1: diff --git a/drivers/staging/android/ashmem.h b/drivers/staging/android/ashmem.h index 5abcfd7aa706..60d7208f110a 100644 --- a/drivers/staging/android/ashmem.h +++ b/drivers/staging/android/ashmem.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0 OR Apache-2.0) /* * include/linux/ashmem.h * diff --git a/drivers/staging/android/ion/ion-ioctl.c b/drivers/staging/android/ion/ion-ioctl.c index c78989351f9c..a8d3cc412fb9 100644 --- a/drivers/staging/android/ion/ion-ioctl.c +++ b/drivers/staging/android/ion/ion-ioctl.c @@ -1,16 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * * Copyright (C) 2011 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <linux/kernel.h> @@ -70,8 +60,10 @@ long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return -EFAULT; ret = validate_ioctl_arg(cmd, &data); - if (WARN_ON_ONCE(ret)) + if (ret) { + pr_warn_once("%s: ioctl validate failed\n", __func__); return ret; + } if (!(dir & _IOC_WRITE)) memset(&data, 0, sizeof(data)); diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index f480885e346b..57e0d8035b2e 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -1,42 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * * drivers/staging/android/ion/ion.c * * Copyright (C) 2011 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ +#include <linux/anon_inodes.h> +#include <linux/debugfs.h> #include <linux/device.h> +#include <linux/dma-buf.h> #include <linux/err.h> +#include <linux/export.h> #include <linux/file.h> #include <linux/freezer.h> #include <linux/fs.h> -#include <linux/anon_inodes.h> +#include <linux/idr.h> #include <linux/kthread.h> #include <linux/list.h> #include <linux/memblock.h> #include <linux/miscdevice.h> -#include <linux/export.h> #include <linux/mm.h> #include <linux/mm_types.h> #include <linux/rbtree.h> -#include <linux/slab.h> +#include <linux/sched/task.h> #include <linux/seq_file.h> +#include <linux/slab.h> #include <linux/uaccess.h> #include <linux/vmalloc.h> -#include <linux/debugfs.h> -#include <linux/dma-buf.h> -#include <linux/idr.h> -#include <linux/sched/task.h> #include "ion.h" @@ -539,6 +529,7 @@ void ion_device_add_heap(struct ion_heap *heap) { struct dentry *debug_file; struct ion_device *dev = internal_dev; + int ret; if (!heap->ops->allocate || !heap->ops->free) pr_err("%s: can not add heap with invalid ops struct.\n", @@ -550,8 +541,11 @@ void ion_device_add_heap(struct ion_heap *heap) if (heap->flags & ION_HEAP_FLAG_DEFER_FREE) ion_heap_init_deferred_free(heap); - if ((heap->flags & ION_HEAP_FLAG_DEFER_FREE) || heap->ops->shrink) - ion_heap_init_shrinker(heap); + if ((heap->flags & ION_HEAP_FLAG_DEFER_FREE) || heap->ops->shrink) { + ret = ion_heap_init_shrinker(heap); + if (ret) + pr_err("%s: Failed to register shrinker\n", __func__); + } heap->dev = dev; down_write(&dev->lock); @@ -567,9 +561,9 @@ void ion_device_add_heap(struct ion_heap *heap) char debug_name[64]; snprintf(debug_name, 64, "%s_shrink", heap->name); - debug_file = debugfs_create_file( - debug_name, 0644, dev->debug_root, heap, - &debug_shrink_fops); + debug_file = debugfs_create_file(debug_name, + 0644, dev->debug_root, heap, + &debug_shrink_fops); if (!debug_file) { char buf[256], *path; diff --git a/drivers/staging/android/ion/ion.h b/drivers/staging/android/ion/ion.h index f5f9cd63f8e9..a238f23c9116 100644 --- a/drivers/staging/android/ion/ion.h +++ b/drivers/staging/android/ion/ion.h @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * drivers/staging/android/ion/ion.h * * Copyright (C) 2011 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #ifndef _ION_H @@ -189,7 +180,8 @@ struct ion_heap { wait_queue_head_t waitqueue; struct task_struct *task; - int (*debug_show)(struct ion_heap *heap, struct seq_file *, void *); + int (*debug_show)(struct ion_heap *heap, struct seq_file *s, + void *unused); }; /** @@ -238,7 +230,7 @@ int ion_alloc(size_t len, * this function will be called to setup a shrinker to shrink the freelists * and call the heap's shrink op. */ -void ion_heap_init_shrinker(struct ion_heap *heap); +int ion_heap_init_shrinker(struct ion_heap *heap); /** * ion_heap_init_deferred_free -- initialize deferred free functionality diff --git a/drivers/staging/android/ion/ion_carveout_heap.c b/drivers/staging/android/ion/ion_carveout_heap.c index fee7650d6fbb..e129237a0417 100644 --- a/drivers/staging/android/ion/ion_carveout_heap.c +++ b/drivers/staging/android/ion/ion_carveout_heap.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * drivers/staging/android/ion/ion_carveout_heap.c * * Copyright (C) 2011 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <linux/spinlock.h> #include <linux/dma-mapping.h> diff --git a/drivers/staging/android/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c index 102c09398317..159d72f5bc42 100644 --- a/drivers/staging/android/ion/ion_chunk_heap.c +++ b/drivers/staging/android/ion/ion_chunk_heap.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * drivers/staging/android/ion/ion_chunk_heap.c * * Copyright (C) 2012 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <linux/dma-mapping.h> #include <linux/err.h> diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c index 86196ffd2faf..94e06925c712 100644 --- a/drivers/staging/android/ion/ion_cma_heap.c +++ b/drivers/staging/android/ion/ion_cma_heap.c @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * drivers/staging/android/ion/ion_cma_heap.c * * Copyright (C) Linaro 2012 * Author: <benjamin.gaignard@linaro.org> for ST-Ericsson. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <linux/device.h> diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c index 91faa7f035b9..772dad65396e 100644 --- a/drivers/staging/android/ion/ion_heap.c +++ b/drivers/staging/android/ion/ion_heap.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * drivers/staging/android/ion/ion_heap.c * * Copyright (C) 2011 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <linux/err.h> @@ -306,11 +297,12 @@ static unsigned long ion_heap_shrink_scan(struct shrinker *shrinker, return freed; } -void ion_heap_init_shrinker(struct ion_heap *heap) +int ion_heap_init_shrinker(struct ion_heap *heap) { heap->shrinker.count_objects = ion_heap_shrink_count; heap->shrinker.scan_objects = ion_heap_shrink_scan; heap->shrinker.seeks = DEFAULT_SEEKS; heap->shrinker.batch = 0; - register_shrinker(&heap->shrinker); + + return register_shrinker(&heap->shrinker); } diff --git a/drivers/staging/android/ion/ion_page_pool.c b/drivers/staging/android/ion/ion_page_pool.c index 817849df9de3..b3017f12835f 100644 --- a/drivers/staging/android/ion/ion_page_pool.c +++ b/drivers/staging/android/ion/ion_page_pool.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * drivers/staging/android/ion/ion_mem_pool.c * * Copyright (C) 2011 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <linux/debugfs.h> diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index 4dc5d7a589c2..bc19cdd30637 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * drivers/staging/android/ion/ion_system_heap.c * * Copyright (C) 2011 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <asm/page.h> @@ -371,7 +362,7 @@ static int ion_system_contig_heap_allocate(struct ion_heap *heap, unsigned long i; int ret; - page = alloc_pages(low_order_gfp_flags, order); + page = alloc_pages(low_order_gfp_flags | __GFP_NOWARN, order); if (!page) return -ENOMEM; diff --git a/drivers/staging/android/uapi/ashmem.h b/drivers/staging/android/uapi/ashmem.h index 13df42d200b7..5b531af6820e 100644 --- a/drivers/staging/android/uapi/ashmem.h +++ b/drivers/staging/android/uapi/ashmem.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0 OR Apache-2.0) /* * drivers/staging/android/uapi/ashmem.h * diff --git a/drivers/staging/android/uapi/ion.h b/drivers/staging/android/uapi/ion.h index 9e21451149d0..825d3e95ccd3 100644 --- a/drivers/staging/android/uapi/ion.h +++ b/drivers/staging/android/uapi/ion.h @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * drivers/staging/android/uapi/ion.h * * Copyright (C) 2011 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #ifndef _UAPI_LINUX_ION_H diff --git a/drivers/staging/ccree/Documentation/devicetree/bindings/crypto/arm-cryptocell.txt b/drivers/staging/ccree/Documentation/devicetree/bindings/crypto/arm-cryptocell.txt deleted file mode 100644 index 2ea65175c032..000000000000 --- a/drivers/staging/ccree/Documentation/devicetree/bindings/crypto/arm-cryptocell.txt +++ /dev/null @@ -1,27 +0,0 @@ -Arm TrustZone CryptoCell cryptographic accelerators - -Required properties: -- compatible: must be "arm,cryptocell-712-ree". -- reg: shall contain base register location and length. - Typically length is 0x10000. -- interrupts: shall contain the interrupt for the device. - -Optional properties: -- interrupt-parent: can designate the interrupt controller the - device interrupt is connected to, if needed. -- clocks: may contain the clock handling the device, if needed. -- power-domains: may contain a reference to the PM domain, if applicable. - - -Examples: - -Zynq FPGA device ----------------- - - arm_cc7x: arm_cc7x@80000000 { - compatible = "arm,cryptocell-712-ree"; - interrupt-parent = <&intc>; - interrupts = < 0 30 4 >; - reg = < 0x80000000 0x10000 >; - }; - diff --git a/drivers/staging/ccree/Kconfig b/drivers/staging/ccree/Kconfig index 0b3092ba2fcb..c94dfe8adb63 100644 --- a/drivers/staging/ccree/Kconfig +++ b/drivers/staging/ccree/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + config CRYPTO_DEV_CCREE tristate "Support for ARM TrustZone CryptoCell C7XX family of Crypto accelerators" depends on CRYPTO && CRYPTO_HW && OF && HAS_DMA diff --git a/drivers/staging/ccree/Makefile b/drivers/staging/ccree/Makefile index ae702f3b5369..bdc27970f95f 100644 --- a/drivers/staging/ccree/Makefile +++ b/drivers/staging/ccree/Makefile @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 + obj-$(CONFIG_CRYPTO_DEV_CCREE) := ccree.o -ccree-y := ssi_driver.o ssi_sysfs.o ssi_buffer_mgr.o ssi_request_mgr.o ssi_cipher.o ssi_hash.o ssi_aead.o ssi_ivgen.o ssi_sram_mgr.o ssi_pm.o -ccree-$(CONFIG_CRYPTO_FIPS) += ssi_fips.o +ccree-y := cc_driver.o cc_buffer_mgr.o cc_request_mgr.o cc_cipher.o cc_hash.o cc_aead.o cc_ivgen.o cc_sram_mgr.o +ccree-$(CONFIG_CRYPTO_FIPS) += cc_fips.o +ccree-$(CONFIG_DEBUG_FS) += cc_debugfs.o +ccree-$(CONFIG_PM) += cc_pm.o diff --git a/drivers/staging/ccree/TODO b/drivers/staging/ccree/TODO index c9f5754d062d..b8e163d98f91 100644 --- a/drivers/staging/ccree/TODO +++ b/drivers/staging/ccree/TODO @@ -6,25 +6,5 @@ * * ************************************************************************* -ccree specific items -a.k.a stuff fixing for this driver to move out of staging -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +1. ??? -1. Move to using Crypto Engine to handle backlog queueing. -2. Remove synchronous algorithm support leftovers. -3. Separate platform specific code for FIPS and power management into separate platform modules. -4. Drop legacy kernel support code. -5. Move most (all?) #ifdef CONFIG into inline functions. -6. Remove all unused definitions. -7. Re-factor to accomediate newer/older HW revisions besides the 712. -8. Handle the many checkpatch errors. -9. Implement ahash import/export correctly. -10. Go through a proper review of DT bindings and sysfs ABI -11. Sort out FIPS mode: bake tests into testmgr, sort out behaviour on error, - figure if 3DES weak key check is needed - -Kernel infrastructure items -a.k.a stuff we either neither need to fix in the kernel or understand what we're doing wrong -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -1. ahash import/export context has a PAGE_SIZE/8 size limit. We need more. -2. Crypto Engine seems to be built for HW with hardware queue depth of 1, we have 600++. diff --git a/drivers/staging/ccree/ssi_aead.c b/drivers/staging/ccree/cc_aead.c index ba0954e4d2e5..b58413172231 100644 --- a/drivers/staging/ccree/ssi_aead.c +++ b/drivers/staging/ccree/cc_aead.c @@ -1,41 +1,19 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ #include <linux/kernel.h> #include <linux/module.h> -#include <linux/platform_device.h> #include <crypto/algapi.h> -#include <crypto/internal/skcipher.h> -#include <crypto/internal/hash.h> #include <crypto/internal/aead.h> -#include <crypto/sha.h> -#include <crypto/ctr.h> #include <crypto/authenc.h> -#include <crypto/aes.h> #include <crypto/des.h> #include <linux/rtnetlink.h> -#include <linux/version.h> -#include "ssi_config.h" -#include "ssi_driver.h" -#include "ssi_buffer_mgr.h" -#include "ssi_aead.h" -#include "ssi_request_mgr.h" -#include "ssi_hash.h" -#include "ssi_sysfs.h" -#include "ssi_sram_mgr.h" +#include "cc_driver.h" +#include "cc_buffer_mgr.h" +#include "cc_aead.h" +#include "cc_request_mgr.h" +#include "cc_hash.h" +#include "cc_sram_mgr.h" #define template_aead template_u.aead @@ -51,8 +29,8 @@ /* Value of each ICV_CMP byte (of 8) in case of success */ #define ICV_VERIF_OK 0x01 -struct ssi_aead_handle { - ssi_sram_addr_t sram_workspace_addr; +struct cc_aead_handle { + cc_sram_addr_t sram_workspace_addr; struct list_head aead_list; }; @@ -68,8 +46,8 @@ struct cc_xcbc_s { dma_addr_t xcbc_keys_dma_addr; }; -struct ssi_aead_ctx { - struct ssi_drvdata *drvdata; +struct cc_aead_ctx { + struct cc_drvdata *drvdata; u8 ctr_nonce[MAX_NONCE_SIZE]; /* used for ctr3686 iv and aes ccm */ u8 *enckey; dma_addr_t enckey_dma_addr; @@ -90,9 +68,9 @@ static inline bool valid_assoclen(struct aead_request *req) return ((req->assoclen == 16) || (req->assoclen == 20)); } -static void ssi_aead_exit(struct crypto_aead *tfm) +static void cc_aead_exit(struct crypto_aead *tfm) { - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); struct device *dev = drvdata_to_dev(ctx->drvdata); dev_dbg(dev, "Clearing context @%p for %s\n", crypto_aead_ctx(tfm), @@ -100,7 +78,8 @@ static void ssi_aead_exit(struct crypto_aead *tfm) /* Unmap enckey buffer */ if (ctx->enckey) { - dma_free_coherent(dev, AES_MAX_KEY_SIZE, ctx->enckey, ctx->enckey_dma_addr); + dma_free_coherent(dev, AES_MAX_KEY_SIZE, ctx->enckey, + ctx->enckey_dma_addr); dev_dbg(dev, "Freed enckey DMA buffer enckey_dma_addr=%pad\n", &ctx->enckey_dma_addr); ctx->enckey_dma_addr = 0; @@ -143,22 +122,22 @@ static void ssi_aead_exit(struct crypto_aead *tfm) } } -static int ssi_aead_init(struct crypto_aead *tfm) +static int cc_aead_init(struct crypto_aead *tfm) { struct aead_alg *alg = crypto_aead_alg(tfm); - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); - struct ssi_crypto_alg *ssi_alg = - container_of(alg, struct ssi_crypto_alg, aead_alg); - struct device *dev = drvdata_to_dev(ssi_alg->drvdata); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_crypto_alg *cc_alg = + container_of(alg, struct cc_crypto_alg, aead_alg); + struct device *dev = drvdata_to_dev(cc_alg->drvdata); dev_dbg(dev, "Initializing context @%p for %s\n", ctx, crypto_tfm_alg_name(&tfm->base)); /* Initialize modes in instance */ - ctx->cipher_mode = ssi_alg->cipher_mode; - ctx->flow_mode = ssi_alg->flow_mode; - ctx->auth_mode = ssi_alg->auth_mode; - ctx->drvdata = ssi_alg->drvdata; + ctx->cipher_mode = cc_alg->cipher_mode; + ctx->flow_mode = cc_alg->flow_mode; + ctx->auth_mode = cc_alg->auth_mode; + ctx->drvdata = cc_alg->drvdata; crypto_aead_set_reqsize(tfm, sizeof(struct aead_req_ctx)); /* Allocate key buffer, cache line aligned */ @@ -221,23 +200,25 @@ static int ssi_aead_init(struct crypto_aead *tfm) return 0; init_failed: - ssi_aead_exit(tfm); + cc_aead_exit(tfm); return -ENOMEM; } -static void ssi_aead_complete(struct device *dev, void *ssi_req, void __iomem *cc_base) +static void cc_aead_complete(struct device *dev, void *cc_req, int err) { - struct aead_request *areq = (struct aead_request *)ssi_req; + struct aead_request *areq = (struct aead_request *)cc_req; struct aead_req_ctx *areq_ctx = aead_request_ctx(areq); - struct crypto_aead *tfm = crypto_aead_reqtfm(ssi_req); - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); - int err = 0; + struct crypto_aead *tfm = crypto_aead_reqtfm(cc_req); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); - ssi_buffer_mgr_unmap_aead_request(dev, areq); + cc_unmap_aead_request(dev, areq); /* Restore ordinary iv pointer */ areq->iv = areq_ctx->backup_iv; + if (err) + goto done; + if (areq_ctx->gen_ctx.op_type == DRV_CRYPTO_DIRECTION_DECRYPT) { if (memcmp(areq_ctx->mac_buf, areq_ctx->icv_virt_addr, ctx->authsize) != 0) { @@ -246,36 +227,43 @@ static void ssi_aead_complete(struct device *dev, void *ssi_req, void __iomem *c /* In case of payload authentication failure, MUST NOT * revealed the decrypted message --> zero its memory. */ - ssi_buffer_mgr_zero_sgl(areq->dst, areq_ctx->cryptlen); + cc_zero_sgl(areq->dst, areq_ctx->cryptlen); err = -EBADMSG; } } else { /*ENCRYPT*/ - if (unlikely(areq_ctx->is_icv_fragmented)) - ssi_buffer_mgr_copy_scatterlist_portion( - dev, areq_ctx->mac_buf, areq_ctx->dst_sgl, - areq->cryptlen + areq_ctx->dst_offset, - (areq->cryptlen + areq_ctx->dst_offset + - ctx->authsize), - SSI_SG_FROM_BUF); - - /* If an IV was generated, copy it back to the user provided buffer. */ + if (areq_ctx->is_icv_fragmented) { + u32 skip = areq->cryptlen + areq_ctx->dst_offset; + + cc_copy_sg_portion(dev, areq_ctx->mac_buf, + areq_ctx->dst_sgl, skip, + (skip + ctx->authsize), + CC_SG_FROM_BUF); + } + + /* If an IV was generated, copy it back to the user provided + * buffer. + */ if (areq_ctx->backup_giv) { if (ctx->cipher_mode == DRV_CIPHER_CTR) - memcpy(areq_ctx->backup_giv, areq_ctx->ctr_iv + CTR_RFC3686_NONCE_SIZE, CTR_RFC3686_IV_SIZE); + memcpy(areq_ctx->backup_giv, areq_ctx->ctr_iv + + CTR_RFC3686_NONCE_SIZE, + CTR_RFC3686_IV_SIZE); else if (ctx->cipher_mode == DRV_CIPHER_CCM) - memcpy(areq_ctx->backup_giv, areq_ctx->ctr_iv + CCM_BLOCK_IV_OFFSET, CCM_BLOCK_IV_SIZE); + memcpy(areq_ctx->backup_giv, areq_ctx->ctr_iv + + CCM_BLOCK_IV_OFFSET, CCM_BLOCK_IV_SIZE); } } - +done: aead_request_complete(areq, err); } -static int xcbc_setkey(struct cc_hw_desc *desc, struct ssi_aead_ctx *ctx) +static int xcbc_setkey(struct cc_hw_desc *desc, struct cc_aead_ctx *ctx) { /* Load the AES key */ hw_desc_init(&desc[0]); - /* We are using for the source/user key the same buffer as for the output keys, - * because after this key loading it is not needed anymore + /* We are using for the source/user key the same buffer + * as for the output keys, * because after this key loading it + * is not needed anymore */ set_din_type(&desc[0], DMA_DLLI, ctx->auth_state.xcbc.xcbc_keys_dma_addr, ctx->auth_keylen, @@ -309,7 +297,7 @@ static int xcbc_setkey(struct cc_hw_desc *desc, struct ssi_aead_ctx *ctx) return 4; } -static int hmac_setkey(struct cc_hw_desc *desc, struct ssi_aead_ctx *ctx) +static int hmac_setkey(struct cc_hw_desc *desc, struct cc_aead_ctx *ctx) { unsigned int hmac_pad_const[2] = { HMAC_IPAD_CONST, HMAC_OPAD_CONST }; unsigned int digest_ofs = 0; @@ -328,8 +316,8 @@ static int hmac_setkey(struct cc_hw_desc *desc, struct ssi_aead_ctx *ctx) hw_desc_init(&desc[idx]); set_cipher_mode(&desc[idx], hash_mode); set_din_sram(&desc[idx], - ssi_ahash_get_larval_digest_sram_addr( - ctx->drvdata, ctx->auth_mode), + cc_larval_digest_addr(ctx->drvdata, + ctx->auth_mode), digest_size); set_flow_mode(&desc[idx], S_DIN_to_HASH); set_setup_mode(&desc[idx], SETUP_LOAD_STATE0); @@ -378,7 +366,7 @@ static int hmac_setkey(struct cc_hw_desc *desc, struct ssi_aead_ctx *ctx) return idx; } -static int validate_keys_sizes(struct ssi_aead_ctx *ctx) +static int validate_keys_sizes(struct cc_aead_ctx *ctx) { struct device *dev = drvdata_to_dev(ctx->drvdata); @@ -390,9 +378,9 @@ static int validate_keys_sizes(struct ssi_aead_ctx *ctx) case DRV_HASH_SHA256: break; case DRV_HASH_XCBC_MAC: - if ((ctx->auth_keylen != AES_KEYSIZE_128) && - (ctx->auth_keylen != AES_KEYSIZE_192) && - (ctx->auth_keylen != AES_KEYSIZE_256)) + if (ctx->auth_keylen != AES_KEYSIZE_128 && + ctx->auth_keylen != AES_KEYSIZE_192 && + ctx->auth_keylen != AES_KEYSIZE_256) return -ENOTSUPP; break; case DRV_HASH_NULL: /* Not authenc (e.g., CCM) - no auth_key) */ @@ -404,16 +392,16 @@ static int validate_keys_sizes(struct ssi_aead_ctx *ctx) return -EINVAL; } /* Check cipher key size */ - if (unlikely(ctx->flow_mode == S_DIN_to_DES)) { + if (ctx->flow_mode == S_DIN_to_DES) { if (ctx->enc_keylen != DES3_EDE_KEY_SIZE) { dev_err(dev, "Invalid cipher(3DES) key size: %u\n", ctx->enc_keylen); return -EINVAL; } } else { /* Default assumed to be AES ciphers */ - if ((ctx->enc_keylen != AES_KEYSIZE_128) && - (ctx->enc_keylen != AES_KEYSIZE_192) && - (ctx->enc_keylen != AES_KEYSIZE_256)) { + if (ctx->enc_keylen != AES_KEYSIZE_128 && + ctx->enc_keylen != AES_KEYSIZE_192 && + ctx->enc_keylen != AES_KEYSIZE_256) { dev_err(dev, "Invalid cipher(AES) key size: %u\n", ctx->enc_keylen); return -EINVAL; @@ -427,14 +415,14 @@ static int validate_keys_sizes(struct ssi_aead_ctx *ctx) * (copy to intenral buffer or hash in case of key longer than block */ static int -ssi_get_plain_hmac_key(struct crypto_aead *tfm, const u8 *key, unsigned int keylen) +cc_get_plain_hmac_key(struct crypto_aead *tfm, const u8 *key, + unsigned int keylen) { dma_addr_t key_dma_addr = 0; - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); struct device *dev = drvdata_to_dev(ctx->drvdata); - u32 larval_addr = ssi_ahash_get_larval_digest_sram_addr( - ctx->drvdata, ctx->auth_mode); - struct ssi_crypto_req ssi_req = {}; + u32 larval_addr = cc_larval_digest_addr(ctx->drvdata, ctx->auth_mode); + struct cc_crypto_req cc_req = {}; unsigned int blocksize; unsigned int digestsize; unsigned int hashmode; @@ -457,9 +445,10 @@ ssi_get_plain_hmac_key(struct crypto_aead *tfm, const u8 *key, unsigned int keyl hashmode = DRV_HASH_HW_SHA256; } - if (likely(keylen != 0)) { - key_dma_addr = dma_map_single(dev, (void *)key, keylen, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(dev, key_dma_addr))) { + if (keylen != 0) { + key_dma_addr = dma_map_single(dev, (void *)key, keylen, + DMA_TO_DEVICE); + if (dma_mapping_error(dev, key_dma_addr)) { dev_err(dev, "Mapping key va=0x%p len=%u for DMA failed\n", key, keylen); return -ENOMEM; @@ -537,22 +526,22 @@ ssi_get_plain_hmac_key(struct crypto_aead *tfm, const u8 *key, unsigned int keyl idx++; } - rc = send_request(ctx->drvdata, &ssi_req, desc, idx, 0); - if (unlikely(rc != 0)) + rc = cc_send_sync_request(ctx->drvdata, &cc_req, desc, idx); + if (rc) dev_err(dev, "send_request() failed (rc=%d)\n", rc); - if (likely(key_dma_addr != 0)) + if (key_dma_addr) dma_unmap_single(dev, key_dma_addr, keylen, DMA_TO_DEVICE); return rc; } static int -ssi_aead_setkey(struct crypto_aead *tfm, const u8 *key, unsigned int keylen) +cc_aead_setkey(struct crypto_aead *tfm, const u8 *key, unsigned int keylen) { - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); struct rtattr *rta = (struct rtattr *)key; - struct ssi_crypto_req ssi_req = {}; + struct cc_crypto_req cc_req = {}; struct crypto_authenc_key_param *param; struct cc_hw_desc desc[MAX_AEAD_SETKEY_SEQ]; int seq_len = 0, rc = -EINVAL; @@ -586,8 +575,9 @@ ssi_aead_setkey(struct crypto_aead *tfm, const u8 *key, unsigned int keylen) /* Copy nonce from last 4 bytes in CTR key to * first 4 bytes in CTR IV */ - memcpy(ctx->ctr_nonce, key + ctx->auth_keylen + ctx->enc_keylen - - CTR_RFC3686_NONCE_SIZE, CTR_RFC3686_NONCE_SIZE); + memcpy(ctx->ctr_nonce, key + ctx->auth_keylen + + ctx->enc_keylen - CTR_RFC3686_NONCE_SIZE, + CTR_RFC3686_NONCE_SIZE); /* Set CTR key size */ ctx->enc_keylen -= CTR_RFC3686_NONCE_SIZE; } @@ -597,7 +587,7 @@ ssi_aead_setkey(struct crypto_aead *tfm, const u8 *key, unsigned int keylen) } rc = validate_keys_sizes(ctx); - if (unlikely(rc != 0)) + if (rc) goto badkey; /* STAT_PHASE_1: Copy key to ctx */ @@ -609,8 +599,8 @@ ssi_aead_setkey(struct crypto_aead *tfm, const u8 *key, unsigned int keylen) if (ctx->auth_mode == DRV_HASH_XCBC_MAC) { memcpy(ctx->auth_state.xcbc.xcbc_keys, key, ctx->auth_keylen); } else if (ctx->auth_mode != DRV_HASH_NULL) { /* HMAC */ - rc = ssi_get_plain_hmac_key(tfm, key, ctx->auth_keylen); - if (rc != 0) + rc = cc_get_plain_hmac_key(tfm, key, ctx->auth_keylen); + if (rc) goto badkey; } @@ -635,8 +625,8 @@ ssi_aead_setkey(struct crypto_aead *tfm, const u8 *key, unsigned int keylen) /* STAT_PHASE_3: Submit sequence to HW */ if (seq_len > 0) { /* For CCM there is no sequence to setup the key */ - rc = send_request(ctx->drvdata, &ssi_req, desc, seq_len, 0); - if (unlikely(rc != 0)) { + rc = cc_send_sync_request(ctx->drvdata, &cc_req, desc, seq_len); + if (rc) { dev_err(dev, "send_request() failed (rc=%d)\n", rc); goto setkey_error; } @@ -652,10 +642,10 @@ setkey_error: return rc; } -#if SSI_CC_HAS_AES_CCM -static int ssi_rfc4309_ccm_setkey(struct crypto_aead *tfm, const u8 *key, unsigned int keylen) +static int cc_rfc4309_ccm_setkey(struct crypto_aead *tfm, const u8 *key, + unsigned int keylen) { - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); if (keylen < 3) return -EINVAL; @@ -663,20 +653,18 @@ static int ssi_rfc4309_ccm_setkey(struct crypto_aead *tfm, const u8 *key, unsign keylen -= 3; memcpy(ctx->ctr_nonce, key + keylen, 3); - return ssi_aead_setkey(tfm, key, keylen); + return cc_aead_setkey(tfm, key, keylen); } -#endif /*SSI_CC_HAS_AES_CCM*/ -static int ssi_aead_setauthsize( - struct crypto_aead *authenc, - unsigned int authsize) +static int cc_aead_setauthsize(struct crypto_aead *authenc, + unsigned int authsize) { - struct ssi_aead_ctx *ctx = crypto_aead_ctx(authenc); + struct cc_aead_ctx *ctx = crypto_aead_ctx(authenc); struct device *dev = drvdata_to_dev(ctx->drvdata); /* Unsupported auth. sizes */ - if ((authsize == 0) || - (authsize > crypto_aead_maxauthsize(authenc))) { + if (authsize == 0 || + authsize > crypto_aead_maxauthsize(authenc)) { return -ENOTSUPP; } @@ -686,9 +674,8 @@ static int ssi_aead_setauthsize( return 0; } -#if SSI_CC_HAS_AES_CCM -static int ssi_rfc4309_ccm_setauthsize(struct crypto_aead *authenc, - unsigned int authsize) +static int cc_rfc4309_ccm_setauthsize(struct crypto_aead *authenc, + unsigned int authsize) { switch (authsize) { case 8: @@ -699,11 +686,11 @@ static int ssi_rfc4309_ccm_setauthsize(struct crypto_aead *authenc, return -EINVAL; } - return ssi_aead_setauthsize(authenc, authsize); + return cc_aead_setauthsize(authenc, authsize); } -static int ssi_ccm_setauthsize(struct crypto_aead *authenc, - unsigned int authsize) +static int cc_ccm_setauthsize(struct crypto_aead *authenc, + unsigned int authsize) { switch (authsize) { case 4: @@ -718,46 +705,41 @@ static int ssi_ccm_setauthsize(struct crypto_aead *authenc, return -EINVAL; } - return ssi_aead_setauthsize(authenc, authsize); + return cc_aead_setauthsize(authenc, authsize); } -#endif /*SSI_CC_HAS_AES_CCM*/ - -static inline void -ssi_aead_create_assoc_desc( - struct aead_request *areq, - unsigned int flow_mode, - struct cc_hw_desc desc[], - unsigned int *seq_size) + +static void cc_set_assoc_desc(struct aead_request *areq, unsigned int flow_mode, + struct cc_hw_desc desc[], unsigned int *seq_size) { struct crypto_aead *tfm = crypto_aead_reqtfm(areq); - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); struct aead_req_ctx *areq_ctx = aead_request_ctx(areq); - enum ssi_req_dma_buf_type assoc_dma_type = areq_ctx->assoc_buff_type; + enum cc_req_dma_buf_type assoc_dma_type = areq_ctx->assoc_buff_type; unsigned int idx = *seq_size; struct device *dev = drvdata_to_dev(ctx->drvdata); switch (assoc_dma_type) { - case SSI_DMA_BUF_DLLI: + case CC_DMA_BUF_DLLI: dev_dbg(dev, "ASSOC buffer type DLLI\n"); hw_desc_init(&desc[idx]); set_din_type(&desc[idx], DMA_DLLI, sg_dma_address(areq->src), - areq->assoclen, NS_BIT); set_flow_mode(&desc[idx], - flow_mode); - if ((ctx->auth_mode == DRV_HASH_XCBC_MAC) && - (areq_ctx->cryptlen > 0)) + areq->assoclen, NS_BIT); + set_flow_mode(&desc[idx], flow_mode); + if (ctx->auth_mode == DRV_HASH_XCBC_MAC && + areq_ctx->cryptlen > 0) set_din_not_last_indication(&desc[idx]); break; - case SSI_DMA_BUF_MLLI: + case CC_DMA_BUF_MLLI: dev_dbg(dev, "ASSOC buffer type MLLI\n"); hw_desc_init(&desc[idx]); set_din_type(&desc[idx], DMA_MLLI, areq_ctx->assoc.sram_addr, areq_ctx->assoc.mlli_nents, NS_BIT); set_flow_mode(&desc[idx], flow_mode); - if ((ctx->auth_mode == DRV_HASH_XCBC_MAC) && - (areq_ctx->cryptlen > 0)) + if (ctx->auth_mode == DRV_HASH_XCBC_MAC && + areq_ctx->cryptlen > 0) set_din_not_last_indication(&desc[idx]); break; - case SSI_DMA_BUF_NULL: + case CC_DMA_BUF_NULL: default: dev_err(dev, "Invalid ASSOC buffer type\n"); } @@ -765,23 +747,20 @@ ssi_aead_create_assoc_desc( *seq_size = (++idx); } -static inline void -ssi_aead_process_authenc_data_desc( - struct aead_request *areq, - unsigned int flow_mode, - struct cc_hw_desc desc[], - unsigned int *seq_size, - int direct) +static void cc_proc_authen_desc(struct aead_request *areq, + unsigned int flow_mode, + struct cc_hw_desc desc[], + unsigned int *seq_size, int direct) { struct aead_req_ctx *areq_ctx = aead_request_ctx(areq); - enum ssi_req_dma_buf_type data_dma_type = areq_ctx->data_buff_type; + enum cc_req_dma_buf_type data_dma_type = areq_ctx->data_buff_type; unsigned int idx = *seq_size; struct crypto_aead *tfm = crypto_aead_reqtfm(areq); - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); struct device *dev = drvdata_to_dev(ctx->drvdata); switch (data_dma_type) { - case SSI_DMA_BUF_DLLI: + case CC_DMA_BUF_DLLI: { struct scatterlist *cipher = (direct == DRV_CRYPTO_DIRECTION_ENCRYPT) ? @@ -798,16 +777,16 @@ ssi_aead_process_authenc_data_desc( set_flow_mode(&desc[idx], flow_mode); break; } - case SSI_DMA_BUF_MLLI: + case CC_DMA_BUF_MLLI: { /* DOUBLE-PASS flow (as default) * assoc. + iv + data -compact in one table * if assoclen is ZERO only IV perform */ - ssi_sram_addr_t mlli_addr = areq_ctx->assoc.sram_addr; + cc_sram_addr_t mlli_addr = areq_ctx->assoc.sram_addr; u32 mlli_nents = areq_ctx->assoc.mlli_nents; - if (likely(areq_ctx->is_single_pass)) { + if (areq_ctx->is_single_pass) { if (direct == DRV_CRYPTO_DIRECTION_ENCRYPT) { mlli_addr = areq_ctx->dst.sram_addr; mlli_nents = areq_ctx->dst.mlli_nents; @@ -824,7 +803,7 @@ ssi_aead_process_authenc_data_desc( set_flow_mode(&desc[idx], flow_mode); break; } - case SSI_DMA_BUF_NULL: + case CC_DMA_BUF_NULL: default: dev_err(dev, "AUTHENC: Invalid SRC/DST buffer type\n"); } @@ -832,37 +811,36 @@ ssi_aead_process_authenc_data_desc( *seq_size = (++idx); } -static inline void -ssi_aead_process_cipher_data_desc( - struct aead_request *areq, - unsigned int flow_mode, - struct cc_hw_desc desc[], - unsigned int *seq_size) +static void cc_proc_cipher_desc(struct aead_request *areq, + unsigned int flow_mode, + struct cc_hw_desc desc[], + unsigned int *seq_size) { unsigned int idx = *seq_size; struct aead_req_ctx *areq_ctx = aead_request_ctx(areq); - enum ssi_req_dma_buf_type data_dma_type = areq_ctx->data_buff_type; + enum cc_req_dma_buf_type data_dma_type = areq_ctx->data_buff_type; struct crypto_aead *tfm = crypto_aead_reqtfm(areq); - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); struct device *dev = drvdata_to_dev(ctx->drvdata); if (areq_ctx->cryptlen == 0) return; /*null processing*/ switch (data_dma_type) { - case SSI_DMA_BUF_DLLI: + case CC_DMA_BUF_DLLI: dev_dbg(dev, "CIPHER: SRC/DST buffer type DLLI\n"); hw_desc_init(&desc[idx]); set_din_type(&desc[idx], DMA_DLLI, (sg_dma_address(areq_ctx->src_sgl) + - areq_ctx->src_offset), areq_ctx->cryptlen, NS_BIT); + areq_ctx->src_offset), areq_ctx->cryptlen, + NS_BIT); set_dout_dlli(&desc[idx], (sg_dma_address(areq_ctx->dst_sgl) + areq_ctx->dst_offset), areq_ctx->cryptlen, NS_BIT, 0); set_flow_mode(&desc[idx], flow_mode); break; - case SSI_DMA_BUF_MLLI: + case CC_DMA_BUF_MLLI: dev_dbg(dev, "CIPHER: SRC/DST buffer type MLLI\n"); hw_desc_init(&desc[idx]); set_din_type(&desc[idx], DMA_MLLI, areq_ctx->src.sram_addr, @@ -871,7 +849,7 @@ ssi_aead_process_cipher_data_desc( areq_ctx->dst.mlli_nents, NS_BIT, 0); set_flow_mode(&desc[idx], flow_mode); break; - case SSI_DMA_BUF_NULL: + case CC_DMA_BUF_NULL: default: dev_err(dev, "CIPHER: Invalid SRC/DST buffer type\n"); } @@ -879,13 +857,12 @@ ssi_aead_process_cipher_data_desc( *seq_size = (++idx); } -static inline void ssi_aead_process_digest_result_desc( - struct aead_request *req, - struct cc_hw_desc desc[], - unsigned int *seq_size) +static void cc_proc_digest_desc(struct aead_request *req, + struct cc_hw_desc desc[], + unsigned int *seq_size) { struct crypto_aead *tfm = crypto_aead_reqtfm(req); - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); struct aead_req_ctx *req_ctx = aead_request_ctx(req); unsigned int idx = *seq_size; unsigned int hash_mode = (ctx->auth_mode == DRV_HASH_SHA1) ? @@ -930,13 +907,12 @@ static inline void ssi_aead_process_digest_result_desc( *seq_size = (++idx); } -static inline void ssi_aead_setup_cipher_desc( - struct aead_request *req, - struct cc_hw_desc desc[], - unsigned int *seq_size) +static void cc_set_cipher_desc(struct aead_request *req, + struct cc_hw_desc desc[], + unsigned int *seq_size) { struct crypto_aead *tfm = crypto_aead_reqtfm(req); - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); struct aead_req_ctx *req_ctx = aead_request_ctx(req); unsigned int hw_iv_size = req_ctx->hw_iv_size; unsigned int idx = *seq_size; @@ -976,11 +952,8 @@ static inline void ssi_aead_setup_cipher_desc( *seq_size = idx; } -static inline void ssi_aead_process_cipher( - struct aead_request *req, - struct cc_hw_desc desc[], - unsigned int *seq_size, - unsigned int data_flow_mode) +static void cc_proc_cipher(struct aead_request *req, struct cc_hw_desc desc[], + unsigned int *seq_size, unsigned int data_flow_mode) { struct aead_req_ctx *req_ctx = aead_request_ctx(req); int direct = req_ctx->gen_ctx.op_type; @@ -989,8 +962,8 @@ static inline void ssi_aead_process_cipher( if (req_ctx->cryptlen == 0) return; /*null processing*/ - ssi_aead_setup_cipher_desc(req, desc, &idx); - ssi_aead_process_cipher_data_desc(req, data_flow_mode, desc, &idx); + cc_set_cipher_desc(req, desc, &idx); + cc_proc_cipher_desc(req, data_flow_mode, desc, &idx); if (direct == DRV_CRYPTO_DIRECTION_ENCRYPT) { /* We must wait for DMA to write all cipher */ hw_desc_init(&desc[idx]); @@ -1002,13 +975,11 @@ static inline void ssi_aead_process_cipher( *seq_size = idx; } -static inline void ssi_aead_hmac_setup_digest_desc( - struct aead_request *req, - struct cc_hw_desc desc[], - unsigned int *seq_size) +static void cc_set_hmac_desc(struct aead_request *req, struct cc_hw_desc desc[], + unsigned int *seq_size) { struct crypto_aead *tfm = crypto_aead_reqtfm(req); - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); unsigned int hash_mode = (ctx->auth_mode == DRV_HASH_SHA1) ? DRV_HASH_HW_SHA1 : DRV_HASH_HW_SHA256; unsigned int digest_size = (ctx->auth_mode == DRV_HASH_SHA1) ? @@ -1028,10 +999,8 @@ static inline void ssi_aead_hmac_setup_digest_desc( /* Load init. digest len (64 bytes) */ hw_desc_init(&desc[idx]); set_cipher_mode(&desc[idx], hash_mode); - set_din_sram(&desc[idx], - ssi_ahash_get_initial_digest_len_sram_addr(ctx->drvdata, - hash_mode), - HASH_LEN_SIZE); + set_din_sram(&desc[idx], cc_digest_len_addr(ctx->drvdata, hash_mode), + HASH_LEN_SIZE); set_flow_mode(&desc[idx], S_DIN_to_HASH); set_setup_mode(&desc[idx], SETUP_LOAD_KEY0); idx++; @@ -1039,13 +1008,11 @@ static inline void ssi_aead_hmac_setup_digest_desc( *seq_size = idx; } -static inline void ssi_aead_xcbc_setup_digest_desc( - struct aead_request *req, - struct cc_hw_desc desc[], - unsigned int *seq_size) +static void cc_set_xcbc_desc(struct aead_request *req, struct cc_hw_desc desc[], + unsigned int *seq_size) { struct crypto_aead *tfm = crypto_aead_reqtfm(req); - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); unsigned int idx = *seq_size; /* Loading MAC state */ @@ -1101,28 +1068,26 @@ static inline void ssi_aead_xcbc_setup_digest_desc( *seq_size = idx; } -static inline void ssi_aead_process_digest_header_desc( - struct aead_request *req, - struct cc_hw_desc desc[], - unsigned int *seq_size) +static void cc_proc_header_desc(struct aead_request *req, + struct cc_hw_desc desc[], + unsigned int *seq_size) { unsigned int idx = *seq_size; /* Hash associated data */ if (req->assoclen > 0) - ssi_aead_create_assoc_desc(req, DIN_HASH, desc, &idx); + cc_set_assoc_desc(req, DIN_HASH, desc, &idx); /* Hash IV */ *seq_size = idx; } -static inline void ssi_aead_process_digest_scheme_desc( - struct aead_request *req, - struct cc_hw_desc desc[], - unsigned int *seq_size) +static void cc_proc_scheme_desc(struct aead_request *req, + struct cc_hw_desc desc[], + unsigned int *seq_size) { struct crypto_aead *tfm = crypto_aead_reqtfm(req); - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); - struct ssi_aead_handle *aead_handle = ctx->drvdata->aead_handle; + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_handle *aead_handle = ctx->drvdata->aead_handle; unsigned int hash_mode = (ctx->auth_mode == DRV_HASH_SHA1) ? DRV_HASH_HW_SHA1 : DRV_HASH_HW_SHA256; unsigned int digest_size = (ctx->auth_mode == DRV_HASH_SHA1) ? @@ -1161,9 +1126,7 @@ static inline void ssi_aead_process_digest_scheme_desc( /* Load init. digest len (64 bytes) */ hw_desc_init(&desc[idx]); set_cipher_mode(&desc[idx], hash_mode); - set_din_sram(&desc[idx], - ssi_ahash_get_initial_digest_len_sram_addr(ctx->drvdata, - hash_mode), + set_din_sram(&desc[idx], cc_digest_len_addr(ctx->drvdata, hash_mode), HASH_LEN_SIZE); set_cipher_config1(&desc[idx], HASH_PADDING_ENABLED); set_flow_mode(&desc[idx], S_DIN_to_HASH); @@ -1180,20 +1143,17 @@ static inline void ssi_aead_process_digest_scheme_desc( *seq_size = idx; } -static inline void ssi_aead_load_mlli_to_sram( - struct aead_request *req, - struct cc_hw_desc desc[], - unsigned int *seq_size) +static void cc_mlli_to_sram(struct aead_request *req, + struct cc_hw_desc desc[], unsigned int *seq_size) { struct aead_req_ctx *req_ctx = aead_request_ctx(req); struct crypto_aead *tfm = crypto_aead_reqtfm(req); - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); struct device *dev = drvdata_to_dev(ctx->drvdata); - if (unlikely( - (req_ctx->assoc_buff_type == SSI_DMA_BUF_MLLI) || - (req_ctx->data_buff_type == SSI_DMA_BUF_MLLI) || - !req_ctx->is_single_pass)) { + if (req_ctx->assoc_buff_type == CC_DMA_BUF_MLLI || + req_ctx->data_buff_type == CC_DMA_BUF_MLLI || + !req_ctx->is_single_pass) { dev_dbg(dev, "Copy-to-sram: mlli_dma=%08x, mlli_size=%u\n", (unsigned int)ctx->drvdata->mlli_sram_addr, req_ctx->mlli_params.mlli_len); @@ -1210,54 +1170,52 @@ static inline void ssi_aead_load_mlli_to_sram( } } -static inline enum cc_flow_mode ssi_aead_get_data_flow_mode( - enum drv_crypto_direction direct, - enum cc_flow_mode setup_flow_mode, - bool is_single_pass) +static enum cc_flow_mode cc_get_data_flow(enum drv_crypto_direction direct, + enum cc_flow_mode setup_flow_mode, + bool is_single_pass) { enum cc_flow_mode data_flow_mode; if (direct == DRV_CRYPTO_DIRECTION_ENCRYPT) { if (setup_flow_mode == S_DIN_to_AES) - data_flow_mode = likely(is_single_pass) ? + data_flow_mode = is_single_pass ? AES_to_HASH_and_DOUT : DIN_AES_DOUT; else - data_flow_mode = likely(is_single_pass) ? + data_flow_mode = is_single_pass ? DES_to_HASH_and_DOUT : DIN_DES_DOUT; } else { /* Decrypt */ if (setup_flow_mode == S_DIN_to_AES) - data_flow_mode = likely(is_single_pass) ? - AES_and_HASH : DIN_AES_DOUT; + data_flow_mode = is_single_pass ? + AES_and_HASH : DIN_AES_DOUT; else - data_flow_mode = likely(is_single_pass) ? - DES_and_HASH : DIN_DES_DOUT; + data_flow_mode = is_single_pass ? + DES_and_HASH : DIN_DES_DOUT; } return data_flow_mode; } -static inline void ssi_aead_hmac_authenc( - struct aead_request *req, - struct cc_hw_desc desc[], - unsigned int *seq_size) +static void cc_hmac_authenc(struct aead_request *req, struct cc_hw_desc desc[], + unsigned int *seq_size) { struct crypto_aead *tfm = crypto_aead_reqtfm(req); - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); struct aead_req_ctx *req_ctx = aead_request_ctx(req); int direct = req_ctx->gen_ctx.op_type; - unsigned int data_flow_mode = ssi_aead_get_data_flow_mode( - direct, ctx->flow_mode, req_ctx->is_single_pass); + unsigned int data_flow_mode = + cc_get_data_flow(direct, ctx->flow_mode, + req_ctx->is_single_pass); if (req_ctx->is_single_pass) { /** * Single-pass flow */ - ssi_aead_hmac_setup_digest_desc(req, desc, seq_size); - ssi_aead_setup_cipher_desc(req, desc, seq_size); - ssi_aead_process_digest_header_desc(req, desc, seq_size); - ssi_aead_process_cipher_data_desc(req, data_flow_mode, desc, seq_size); - ssi_aead_process_digest_scheme_desc(req, desc, seq_size); - ssi_aead_process_digest_result_desc(req, desc, seq_size); + cc_set_hmac_desc(req, desc, seq_size); + cc_set_cipher_desc(req, desc, seq_size); + cc_proc_header_desc(req, desc, seq_size); + cc_proc_cipher_desc(req, data_flow_mode, desc, seq_size); + cc_proc_scheme_desc(req, desc, seq_size); + cc_proc_digest_desc(req, desc, seq_size); return; } @@ -1268,49 +1226,48 @@ static inline void ssi_aead_hmac_authenc( */ if (direct == DRV_CRYPTO_DIRECTION_ENCRYPT) { /* encrypt first.. */ - ssi_aead_process_cipher(req, desc, seq_size, data_flow_mode); + cc_proc_cipher(req, desc, seq_size, data_flow_mode); /* authenc after..*/ - ssi_aead_hmac_setup_digest_desc(req, desc, seq_size); - ssi_aead_process_authenc_data_desc(req, DIN_HASH, desc, seq_size, direct); - ssi_aead_process_digest_scheme_desc(req, desc, seq_size); - ssi_aead_process_digest_result_desc(req, desc, seq_size); + cc_set_hmac_desc(req, desc, seq_size); + cc_proc_authen_desc(req, DIN_HASH, desc, seq_size, direct); + cc_proc_scheme_desc(req, desc, seq_size); + cc_proc_digest_desc(req, desc, seq_size); } else { /*DECRYPT*/ /* authenc first..*/ - ssi_aead_hmac_setup_digest_desc(req, desc, seq_size); - ssi_aead_process_authenc_data_desc(req, DIN_HASH, desc, seq_size, direct); - ssi_aead_process_digest_scheme_desc(req, desc, seq_size); + cc_set_hmac_desc(req, desc, seq_size); + cc_proc_authen_desc(req, DIN_HASH, desc, seq_size, direct); + cc_proc_scheme_desc(req, desc, seq_size); /* decrypt after.. */ - ssi_aead_process_cipher(req, desc, seq_size, data_flow_mode); + cc_proc_cipher(req, desc, seq_size, data_flow_mode); /* read the digest result with setting the completion bit * must be after the cipher operation */ - ssi_aead_process_digest_result_desc(req, desc, seq_size); + cc_proc_digest_desc(req, desc, seq_size); } } -static inline void -ssi_aead_xcbc_authenc( - struct aead_request *req, - struct cc_hw_desc desc[], - unsigned int *seq_size) +static void +cc_xcbc_authenc(struct aead_request *req, struct cc_hw_desc desc[], + unsigned int *seq_size) { struct crypto_aead *tfm = crypto_aead_reqtfm(req); - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); struct aead_req_ctx *req_ctx = aead_request_ctx(req); int direct = req_ctx->gen_ctx.op_type; - unsigned int data_flow_mode = ssi_aead_get_data_flow_mode( - direct, ctx->flow_mode, req_ctx->is_single_pass); + unsigned int data_flow_mode = + cc_get_data_flow(direct, ctx->flow_mode, + req_ctx->is_single_pass); if (req_ctx->is_single_pass) { /** * Single-pass flow */ - ssi_aead_xcbc_setup_digest_desc(req, desc, seq_size); - ssi_aead_setup_cipher_desc(req, desc, seq_size); - ssi_aead_process_digest_header_desc(req, desc, seq_size); - ssi_aead_process_cipher_data_desc(req, data_flow_mode, desc, seq_size); - ssi_aead_process_digest_result_desc(req, desc, seq_size); + cc_set_xcbc_desc(req, desc, seq_size); + cc_set_cipher_desc(req, desc, seq_size); + cc_proc_header_desc(req, desc, seq_size); + cc_proc_cipher_desc(req, data_flow_mode, desc, seq_size); + cc_proc_digest_desc(req, desc, seq_size); return; } @@ -1321,25 +1278,25 @@ ssi_aead_xcbc_authenc( */ if (direct == DRV_CRYPTO_DIRECTION_ENCRYPT) { /* encrypt first.. */ - ssi_aead_process_cipher(req, desc, seq_size, data_flow_mode); + cc_proc_cipher(req, desc, seq_size, data_flow_mode); /* authenc after.. */ - ssi_aead_xcbc_setup_digest_desc(req, desc, seq_size); - ssi_aead_process_authenc_data_desc(req, DIN_HASH, desc, seq_size, direct); - ssi_aead_process_digest_result_desc(req, desc, seq_size); + cc_set_xcbc_desc(req, desc, seq_size); + cc_proc_authen_desc(req, DIN_HASH, desc, seq_size, direct); + cc_proc_digest_desc(req, desc, seq_size); } else { /*DECRYPT*/ /* authenc first.. */ - ssi_aead_xcbc_setup_digest_desc(req, desc, seq_size); - ssi_aead_process_authenc_data_desc(req, DIN_HASH, desc, seq_size, direct); + cc_set_xcbc_desc(req, desc, seq_size); + cc_proc_authen_desc(req, DIN_HASH, desc, seq_size, direct); /* decrypt after..*/ - ssi_aead_process_cipher(req, desc, seq_size, data_flow_mode); + cc_proc_cipher(req, desc, seq_size, data_flow_mode); /* read the digest result with setting the completion bit * must be after the cipher operation */ - ssi_aead_process_digest_result_desc(req, desc, seq_size); + cc_proc_digest_desc(req, desc, seq_size); } } -static int validate_data_size(struct ssi_aead_ctx *ctx, +static int validate_data_size(struct cc_aead_ctx *ctx, enum drv_crypto_direction direct, struct aead_request *req) { @@ -1349,16 +1306,16 @@ static int validate_data_size(struct ssi_aead_ctx *ctx, unsigned int cipherlen = (direct == DRV_CRYPTO_DIRECTION_DECRYPT) ? (req->cryptlen - ctx->authsize) : req->cryptlen; - if (unlikely((direct == DRV_CRYPTO_DIRECTION_DECRYPT) && - (req->cryptlen < ctx->authsize))) + if (direct == DRV_CRYPTO_DIRECTION_DECRYPT && + req->cryptlen < ctx->authsize) goto data_size_err; areq_ctx->is_single_pass = true; /*defaulted to fast flow*/ switch (ctx->flow_mode) { case S_DIN_to_AES: - if (unlikely((ctx->cipher_mode == DRV_CIPHER_CBC) && - !IS_ALIGNED(cipherlen, AES_BLOCK_SIZE))) + if (ctx->cipher_mode == DRV_CIPHER_CBC && + !IS_ALIGNED(cipherlen, AES_BLOCK_SIZE)) goto data_size_err; if (ctx->cipher_mode == DRV_CIPHER_CCM) break; @@ -1371,15 +1328,15 @@ static int validate_data_size(struct ssi_aead_ctx *ctx, if (!IS_ALIGNED(assoclen, sizeof(u32))) areq_ctx->is_single_pass = false; - if ((ctx->cipher_mode == DRV_CIPHER_CTR) && + if (ctx->cipher_mode == DRV_CIPHER_CTR && !IS_ALIGNED(cipherlen, sizeof(u32))) areq_ctx->is_single_pass = false; break; case S_DIN_to_DES: - if (unlikely(!IS_ALIGNED(cipherlen, DES_BLOCK_SIZE))) + if (!IS_ALIGNED(cipherlen, DES_BLOCK_SIZE)) goto data_size_err; - if (unlikely(!IS_ALIGNED(assoclen, DES_BLOCK_SIZE))) + if (!IS_ALIGNED(assoclen, DES_BLOCK_SIZE)) areq_ctx->is_single_pass = false; break; default: @@ -1393,7 +1350,6 @@ data_size_err: return -EINVAL; } -#if SSI_CC_HAS_AES_CCM static unsigned int format_ccm_a0(u8 *pa0_buff, u32 header_size) { unsigned int len = 0; @@ -1438,13 +1394,11 @@ static int set_msg_len(u8 *block, unsigned int msglen, unsigned int csize) return 0; } -static inline int ssi_aead_ccm( - struct aead_request *req, - struct cc_hw_desc desc[], - unsigned int *seq_size) +static int cc_ccm(struct aead_request *req, struct cc_hw_desc desc[], + unsigned int *seq_size) { struct crypto_aead *tfm = crypto_aead_reqtfm(req); - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); struct aead_req_ctx *req_ctx = aead_request_ctx(req); unsigned int idx = *seq_size; unsigned int cipher_flow_mode; @@ -1508,7 +1462,7 @@ static inline int ssi_aead_ccm( /* process assoc data */ if (req->assoclen > 0) { - ssi_aead_create_assoc_desc(req, DIN_HASH, desc, &idx); + cc_set_assoc_desc(req, DIN_HASH, desc, &idx); } else { hw_desc_init(&desc[idx]); set_din_type(&desc[idx], DMA_DLLI, @@ -1519,8 +1473,8 @@ static inline int ssi_aead_ccm( } /* process the cipher */ - if (req_ctx->cryptlen != 0) - ssi_aead_process_cipher_data_desc(req, cipher_flow_mode, desc, &idx); + if (req_ctx->cryptlen) + cc_proc_cipher_desc(req, cipher_flow_mode, desc, &idx); /* Read temporal MAC */ hw_desc_init(&desc[idx]); @@ -1565,12 +1519,14 @@ static inline int ssi_aead_ccm( static int config_ccm_adata(struct aead_request *req) { struct crypto_aead *tfm = crypto_aead_reqtfm(req); - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); struct device *dev = drvdata_to_dev(ctx->drvdata); struct aead_req_ctx *req_ctx = aead_request_ctx(req); //unsigned int size_of_a = 0, rem_a_size = 0; unsigned int lp = req->iv[0]; - /* Note: The code assume that req->iv[0] already contains the value of L' of RFC3610 */ + /* Note: The code assume that req->iv[0] already contains the value + * of L' of RFC3610 + */ unsigned int l = lp + 1; /* This is L' of RFC 3610. */ unsigned int m = ctx->authsize; /* This is M' of RFC 3610. */ u8 *b0 = req_ctx->ccm_config + CCM_B0_OFFSET; @@ -1601,7 +1557,7 @@ static int config_ccm_adata(struct aead_request *req) *b0 |= 64; /* Enable bit 6 if Adata exists. */ rc = set_msg_len(b0 + 16 - l, cryptlen, l); /* Write L'. */ - if (rc != 0) { + if (rc) { dev_err(dev, "message len overflow detected"); return rc; } @@ -1619,33 +1575,35 @@ static int config_ccm_adata(struct aead_request *req) return 0; } -static void ssi_rfc4309_ccm_process(struct aead_request *req) +static void cc_proc_rfc4309_ccm(struct aead_request *req) { struct crypto_aead *tfm = crypto_aead_reqtfm(req); - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); struct aead_req_ctx *areq_ctx = aead_request_ctx(req); /* L' */ memset(areq_ctx->ctr_iv, 0, AES_BLOCK_SIZE); - areq_ctx->ctr_iv[0] = 3; /* For RFC 4309, always use 4 bytes for message length (at most 2^32-1 bytes). */ + /* For RFC 4309, always use 4 bytes for message length + * (at most 2^32-1 bytes). + */ + areq_ctx->ctr_iv[0] = 3; - /* In RFC 4309 there is an 11-bytes nonce+IV part, that we build here. */ - memcpy(areq_ctx->ctr_iv + CCM_BLOCK_NONCE_OFFSET, ctx->ctr_nonce, CCM_BLOCK_NONCE_SIZE); - memcpy(areq_ctx->ctr_iv + CCM_BLOCK_IV_OFFSET, req->iv, CCM_BLOCK_IV_SIZE); + /* In RFC 4309 there is an 11-bytes nonce+IV part, + * that we build here. + */ + memcpy(areq_ctx->ctr_iv + CCM_BLOCK_NONCE_OFFSET, ctx->ctr_nonce, + CCM_BLOCK_NONCE_SIZE); + memcpy(areq_ctx->ctr_iv + CCM_BLOCK_IV_OFFSET, req->iv, + CCM_BLOCK_IV_SIZE); req->iv = areq_ctx->ctr_iv; req->assoclen -= CCM_BLOCK_IV_SIZE; } -#endif /*SSI_CC_HAS_AES_CCM*/ - -#if SSI_CC_HAS_AES_GCM -static inline void ssi_aead_gcm_setup_ghash_desc( - struct aead_request *req, - struct cc_hw_desc desc[], - unsigned int *seq_size) +static void cc_set_ghash_desc(struct aead_request *req, + struct cc_hw_desc desc[], unsigned int *seq_size) { struct crypto_aead *tfm = crypto_aead_reqtfm(req); - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); struct aead_req_ctx *req_ctx = aead_request_ctx(req); unsigned int idx = *seq_size; @@ -1703,7 +1661,9 @@ static inline void ssi_aead_gcm_setup_ghash_desc( set_setup_mode(&desc[idx], SETUP_LOAD_KEY0); idx++; - /* Load GHASH initial STATE (which is 0). (for any hash there is an initial state) */ + /* Load GHASH initial STATE (which is 0). (for any hash there is an + * initial state) + */ hw_desc_init(&desc[idx]); set_din_const(&desc[idx], 0x0, AES_BLOCK_SIZE); set_dout_no_dma(&desc[idx], 0, 0, 1); @@ -1717,13 +1677,11 @@ static inline void ssi_aead_gcm_setup_ghash_desc( *seq_size = idx; } -static inline void ssi_aead_gcm_setup_gctr_desc( - struct aead_request *req, - struct cc_hw_desc desc[], - unsigned int *seq_size) +static void cc_set_gctr_desc(struct aead_request *req, struct cc_hw_desc desc[], + unsigned int *seq_size) { struct crypto_aead *tfm = crypto_aead_reqtfm(req); - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); struct aead_req_ctx *req_ctx = aead_request_ctx(req); unsigned int idx = *seq_size; @@ -1738,7 +1696,7 @@ static inline void ssi_aead_gcm_setup_gctr_desc( set_flow_mode(&desc[idx], S_DIN_to_AES); idx++; - if ((req_ctx->cryptlen != 0) && (!req_ctx->plaintext_authenticate_only)) { + if (req_ctx->cryptlen && !req_ctx->plaintext_authenticate_only) { /* load AES/CTR initial CTR value inc by 2*/ hw_desc_init(&desc[idx]); set_cipher_mode(&desc[idx], DRV_CIPHER_GCTR); @@ -1755,13 +1713,12 @@ static inline void ssi_aead_gcm_setup_gctr_desc( *seq_size = idx; } -static inline void ssi_aead_process_gcm_result_desc( - struct aead_request *req, - struct cc_hw_desc desc[], - unsigned int *seq_size) +static void cc_proc_gcm_result(struct aead_request *req, + struct cc_hw_desc desc[], + unsigned int *seq_size) { struct crypto_aead *tfm = crypto_aead_reqtfm(req); - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); struct aead_req_ctx *req_ctx = aead_request_ctx(req); dma_addr_t mac_result; unsigned int idx = *seq_size; @@ -1821,10 +1778,8 @@ static inline void ssi_aead_process_gcm_result_desc( *seq_size = idx; } -static inline int ssi_aead_gcm( - struct aead_request *req, - struct cc_hw_desc desc[], - unsigned int *seq_size) +static int cc_gcm(struct aead_request *req, struct cc_hw_desc desc[], + unsigned int *seq_size) { struct aead_req_ctx *req_ctx = aead_request_ctx(req); unsigned int cipher_flow_mode; @@ -1837,77 +1792,33 @@ static inline int ssi_aead_gcm( //in RFC4543 no data to encrypt. just copy data from src to dest. if (req_ctx->plaintext_authenticate_only) { - ssi_aead_process_cipher_data_desc(req, BYPASS, desc, seq_size); - ssi_aead_gcm_setup_ghash_desc(req, desc, seq_size); + cc_proc_cipher_desc(req, BYPASS, desc, seq_size); + cc_set_ghash_desc(req, desc, seq_size); /* process(ghash) assoc data */ - ssi_aead_create_assoc_desc(req, DIN_HASH, desc, seq_size); - ssi_aead_gcm_setup_gctr_desc(req, desc, seq_size); - ssi_aead_process_gcm_result_desc(req, desc, seq_size); + cc_set_assoc_desc(req, DIN_HASH, desc, seq_size); + cc_set_gctr_desc(req, desc, seq_size); + cc_proc_gcm_result(req, desc, seq_size); return 0; } // for gcm and rfc4106. - ssi_aead_gcm_setup_ghash_desc(req, desc, seq_size); + cc_set_ghash_desc(req, desc, seq_size); /* process(ghash) assoc data */ if (req->assoclen > 0) - ssi_aead_create_assoc_desc(req, DIN_HASH, desc, seq_size); - ssi_aead_gcm_setup_gctr_desc(req, desc, seq_size); + cc_set_assoc_desc(req, DIN_HASH, desc, seq_size); + cc_set_gctr_desc(req, desc, seq_size); /* process(gctr+ghash) */ - if (req_ctx->cryptlen != 0) - ssi_aead_process_cipher_data_desc(req, cipher_flow_mode, desc, seq_size); - ssi_aead_process_gcm_result_desc(req, desc, seq_size); + if (req_ctx->cryptlen) + cc_proc_cipher_desc(req, cipher_flow_mode, desc, seq_size); + cc_proc_gcm_result(req, desc, seq_size); return 0; } -#ifdef CC_DEBUG -static inline void ssi_aead_dump_gcm( - const char *title, - struct aead_request *req) -{ - struct crypto_aead *tfm = crypto_aead_reqtfm(req); - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); - struct aead_req_ctx *req_ctx = aead_request_ctx(req); - - if (ctx->cipher_mode != DRV_CIPHER_GCTR) - return; - - if (title) { - dev_dbg(dev, "----------------------------------------------------------------------------------"); - dev_dbg(dev, "%s\n", title); - } - - dev_dbg(dev, "cipher_mode %d, authsize %d, enc_keylen %d, assoclen %d, cryptlen %d\n", - ctx->cipher_mode, ctx->authsize, ctx->enc_keylen, - req->assoclen, req_ctx->cryptlen); - - if (ctx->enckey) - dump_byte_array("mac key", ctx->enckey, 16); - - dump_byte_array("req->iv", req->iv, AES_BLOCK_SIZE); - - dump_byte_array("gcm_iv_inc1", req_ctx->gcm_iv_inc1, AES_BLOCK_SIZE); - - dump_byte_array("gcm_iv_inc2", req_ctx->gcm_iv_inc2, AES_BLOCK_SIZE); - - dump_byte_array("hkey", req_ctx->hkey, AES_BLOCK_SIZE); - - dump_byte_array("mac_buf", req_ctx->mac_buf, AES_BLOCK_SIZE); - - dump_byte_array("gcm_len_block", req_ctx->gcm_len_block.len_a, AES_BLOCK_SIZE); - - if (req->src && req->cryptlen) - dump_byte_array("req->src", sg_virt(req->src), req->cryptlen + req->assoclen); - - if (req->dst) - dump_byte_array("req->dst", sg_virt(req->dst), req->cryptlen + ctx->authsize + req->assoclen); -} -#endif - static int config_gcm_context(struct aead_request *req) { struct crypto_aead *tfm = crypto_aead_reqtfm(req); - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); struct aead_req_ctx *req_ctx = aead_request_ctx(req); struct device *dev = drvdata_to_dev(ctx->drvdata); @@ -1938,10 +1849,14 @@ static int config_gcm_context(struct aead_request *req) memcpy(&req_ctx->gcm_len_block.len_a, &temp64, sizeof(temp64)); temp64 = cpu_to_be64(cryptlen * 8); memcpy(&req_ctx->gcm_len_block.len_c, &temp64, 8); - } else { //rfc4543=> all data(AAD,IV,Plain) are considered additional data that is nothing is encrypted. + } else { + /* rfc4543=> all data(AAD,IV,Plain) are considered additional + * data that is nothing is encrypted. + */ __be64 temp64; - temp64 = cpu_to_be64((req->assoclen + GCM_BLOCK_RFC4_IV_SIZE + cryptlen) * 8); + temp64 = cpu_to_be64((req->assoclen + GCM_BLOCK_RFC4_IV_SIZE + + cryptlen) * 8); memcpy(&req_ctx->gcm_len_block.len_a, &temp64, sizeof(temp64)); temp64 = 0; memcpy(&req_ctx->gcm_len_block.len_c, &temp64, 8); @@ -1950,30 +1865,31 @@ static int config_gcm_context(struct aead_request *req) return 0; } -static void ssi_rfc4_gcm_process(struct aead_request *req) +static void cc_proc_rfc4_gcm(struct aead_request *req) { struct crypto_aead *tfm = crypto_aead_reqtfm(req); - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); struct aead_req_ctx *areq_ctx = aead_request_ctx(req); - memcpy(areq_ctx->ctr_iv + GCM_BLOCK_RFC4_NONCE_OFFSET, ctx->ctr_nonce, GCM_BLOCK_RFC4_NONCE_SIZE); - memcpy(areq_ctx->ctr_iv + GCM_BLOCK_RFC4_IV_OFFSET, req->iv, GCM_BLOCK_RFC4_IV_SIZE); + memcpy(areq_ctx->ctr_iv + GCM_BLOCK_RFC4_NONCE_OFFSET, + ctx->ctr_nonce, GCM_BLOCK_RFC4_NONCE_SIZE); + memcpy(areq_ctx->ctr_iv + GCM_BLOCK_RFC4_IV_OFFSET, req->iv, + GCM_BLOCK_RFC4_IV_SIZE); req->iv = areq_ctx->ctr_iv; req->assoclen -= GCM_BLOCK_RFC4_IV_SIZE; } -#endif /*SSI_CC_HAS_AES_GCM*/ - -static int ssi_aead_process(struct aead_request *req, enum drv_crypto_direction direct) +static int cc_proc_aead(struct aead_request *req, + enum drv_crypto_direction direct) { int rc = 0; int seq_len = 0; struct cc_hw_desc desc[MAX_AEAD_PROCESS_SEQ]; struct crypto_aead *tfm = crypto_aead_reqtfm(req); - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); struct aead_req_ctx *areq_ctx = aead_request_ctx(req); struct device *dev = drvdata_to_dev(ctx->drvdata); - struct ssi_crypto_req ssi_req = {}; + struct cc_crypto_req cc_req = {}; dev_dbg(dev, "%s context=%p req=%p iv=%p src=%p src_ofs=%d dst=%p dst_ofs=%d cryptolen=%d\n", ((direct == DRV_CRYPTO_DIRECTION_ENCRYPT) ? "Enc" : "Dec"), @@ -1983,7 +1899,7 @@ static int ssi_aead_process(struct aead_request *req, enum drv_crypto_direction /* STAT_PHASE_0: Init and sanity checks */ /* Check data length according to mode */ - if (unlikely(validate_data_size(ctx, direct, req) != 0)) { + if (validate_data_size(ctx, direct, req)) { dev_err(dev, "Unsupported crypt/assoc len %d/%d.\n", req->cryptlen, req->assoclen); crypto_aead_set_flags(tfm, CRYPTO_TFM_RES_BAD_BLOCK_LEN); @@ -1991,8 +1907,8 @@ static int ssi_aead_process(struct aead_request *req, enum drv_crypto_direction } /* Setup DX request structure */ - ssi_req.user_cb = (void *)ssi_aead_complete; - ssi_req.user_arg = (void *)req; + cc_req.user_cb = (void *)cc_aead_complete; + cc_req.user_arg = (void *)req; /* Setup request context */ areq_ctx->gen_ctx.op_type = direct; @@ -2005,7 +1921,8 @@ static int ssi_aead_process(struct aead_request *req, enum drv_crypto_direction /* Build CTR IV - Copy nonce from last 4 bytes in * CTR key to first 4 bytes in CTR IV */ - memcpy(areq_ctx->ctr_iv, ctx->ctr_nonce, CTR_RFC3686_NONCE_SIZE); + memcpy(areq_ctx->ctr_iv, ctx->ctr_nonce, + CTR_RFC3686_NONCE_SIZE); if (!areq_ctx->backup_giv) /*User none-generated IV*/ memcpy(areq_ctx->ctr_iv + CTR_RFC3686_NONCE_SIZE, req->iv, CTR_RFC3686_IV_SIZE); @@ -2020,17 +1937,17 @@ static int ssi_aead_process(struct aead_request *req, enum drv_crypto_direction (ctx->cipher_mode == DRV_CIPHER_GCTR)) { areq_ctx->hw_iv_size = AES_BLOCK_SIZE; if (areq_ctx->ctr_iv != req->iv) { - memcpy(areq_ctx->ctr_iv, req->iv, crypto_aead_ivsize(tfm)); + memcpy(areq_ctx->ctr_iv, req->iv, + crypto_aead_ivsize(tfm)); req->iv = areq_ctx->ctr_iv; } } else { areq_ctx->hw_iv_size = crypto_aead_ivsize(tfm); } -#if SSI_CC_HAS_AES_CCM if (ctx->cipher_mode == DRV_CIPHER_CCM) { rc = config_ccm_adata(req); - if (unlikely(rc != 0)) { + if (rc) { dev_dbg(dev, "config_ccm_adata() returned with a failure %d!", rc); goto exit; @@ -2038,23 +1955,18 @@ static int ssi_aead_process(struct aead_request *req, enum drv_crypto_direction } else { areq_ctx->ccm_hdr_size = ccm_header_size_null; } -#else - areq_ctx->ccm_hdr_size = ccm_header_size_null; -#endif /*SSI_CC_HAS_AES_CCM*/ -#if SSI_CC_HAS_AES_GCM if (ctx->cipher_mode == DRV_CIPHER_GCTR) { rc = config_gcm_context(req); - if (unlikely(rc != 0)) { + if (rc) { dev_dbg(dev, "config_gcm_context() returned with a failure %d!", rc); goto exit; } } -#endif /*SSI_CC_HAS_AES_GCM*/ - rc = ssi_buffer_mgr_map_aead_request(ctx->drvdata, req); - if (unlikely(rc != 0)) { + rc = cc_map_aead_request(ctx->drvdata, req); + if (rc) { dev_err(dev, "map_request() failed\n"); goto exit; } @@ -2063,74 +1975,77 @@ static int ssi_aead_process(struct aead_request *req, enum drv_crypto_direction if (areq_ctx->backup_giv) { /* set the DMA mapped IV address*/ if (ctx->cipher_mode == DRV_CIPHER_CTR) { - ssi_req.ivgen_dma_addr[0] = areq_ctx->gen_ctx.iv_dma_addr + CTR_RFC3686_NONCE_SIZE; - ssi_req.ivgen_dma_addr_len = 1; + cc_req.ivgen_dma_addr[0] = + areq_ctx->gen_ctx.iv_dma_addr + + CTR_RFC3686_NONCE_SIZE; + cc_req.ivgen_dma_addr_len = 1; } else if (ctx->cipher_mode == DRV_CIPHER_CCM) { - /* In ccm, the IV needs to exist both inside B0 and inside the counter. - * It is also copied to iv_dma_addr for other reasons (like returning - * it to the user). + /* In ccm, the IV needs to exist both inside B0 and + * inside the counter.It is also copied to iv_dma_addr + * for other reasons (like returning it to the user). * So, using 3 (identical) IV outputs. */ - ssi_req.ivgen_dma_addr[0] = areq_ctx->gen_ctx.iv_dma_addr + CCM_BLOCK_IV_OFFSET; - ssi_req.ivgen_dma_addr[1] = sg_dma_address(&areq_ctx->ccm_adata_sg) + CCM_B0_OFFSET + CCM_BLOCK_IV_OFFSET; - ssi_req.ivgen_dma_addr[2] = sg_dma_address(&areq_ctx->ccm_adata_sg) + CCM_CTR_COUNT_0_OFFSET + CCM_BLOCK_IV_OFFSET; - ssi_req.ivgen_dma_addr_len = 3; + cc_req.ivgen_dma_addr[0] = + areq_ctx->gen_ctx.iv_dma_addr + + CCM_BLOCK_IV_OFFSET; + cc_req.ivgen_dma_addr[1] = + sg_dma_address(&areq_ctx->ccm_adata_sg) + + CCM_B0_OFFSET + CCM_BLOCK_IV_OFFSET; + cc_req.ivgen_dma_addr[2] = + sg_dma_address(&areq_ctx->ccm_adata_sg) + + CCM_CTR_COUNT_0_OFFSET + CCM_BLOCK_IV_OFFSET; + cc_req.ivgen_dma_addr_len = 3; } else { - ssi_req.ivgen_dma_addr[0] = areq_ctx->gen_ctx.iv_dma_addr; - ssi_req.ivgen_dma_addr_len = 1; + cc_req.ivgen_dma_addr[0] = + areq_ctx->gen_ctx.iv_dma_addr; + cc_req.ivgen_dma_addr_len = 1; } /* set the IV size (8/16 B long)*/ - ssi_req.ivgen_size = crypto_aead_ivsize(tfm); + cc_req.ivgen_size = crypto_aead_ivsize(tfm); } /* STAT_PHASE_2: Create sequence */ /* Load MLLI tables to SRAM if necessary */ - ssi_aead_load_mlli_to_sram(req, desc, &seq_len); + cc_mlli_to_sram(req, desc, &seq_len); /*TODO: move seq len by reference */ switch (ctx->auth_mode) { case DRV_HASH_SHA1: case DRV_HASH_SHA256: - ssi_aead_hmac_authenc(req, desc, &seq_len); + cc_hmac_authenc(req, desc, &seq_len); break; case DRV_HASH_XCBC_MAC: - ssi_aead_xcbc_authenc(req, desc, &seq_len); + cc_xcbc_authenc(req, desc, &seq_len); break; -#if (SSI_CC_HAS_AES_CCM || SSI_CC_HAS_AES_GCM) case DRV_HASH_NULL: -#if SSI_CC_HAS_AES_CCM if (ctx->cipher_mode == DRV_CIPHER_CCM) - ssi_aead_ccm(req, desc, &seq_len); -#endif /*SSI_CC_HAS_AES_CCM*/ -#if SSI_CC_HAS_AES_GCM + cc_ccm(req, desc, &seq_len); if (ctx->cipher_mode == DRV_CIPHER_GCTR) - ssi_aead_gcm(req, desc, &seq_len); -#endif /*SSI_CC_HAS_AES_GCM*/ - break; -#endif + cc_gcm(req, desc, &seq_len); + break; default: dev_err(dev, "Unsupported authenc (%d)\n", ctx->auth_mode); - ssi_buffer_mgr_unmap_aead_request(dev, req); + cc_unmap_aead_request(dev, req); rc = -ENOTSUPP; goto exit; } /* STAT_PHASE_3: Lock HW and push sequence */ - rc = send_request(ctx->drvdata, &ssi_req, desc, seq_len, 1); + rc = cc_send_request(ctx->drvdata, &cc_req, desc, seq_len, &req->base); - if (unlikely(rc != -EINPROGRESS)) { + if (rc != -EINPROGRESS && rc != -EBUSY) { dev_err(dev, "send_request() failed (rc=%d)\n", rc); - ssi_buffer_mgr_unmap_aead_request(dev, req); + cc_unmap_aead_request(dev, req); } exit: return rc; } -static int ssi_aead_encrypt(struct aead_request *req) +static int cc_aead_encrypt(struct aead_request *req) { struct aead_req_ctx *areq_ctx = aead_request_ctx(req); int rc; @@ -2142,21 +2057,20 @@ static int ssi_aead_encrypt(struct aead_request *req) areq_ctx->plaintext_authenticate_only = false; - rc = ssi_aead_process(req, DRV_CRYPTO_DIRECTION_ENCRYPT); - if (rc != -EINPROGRESS) + rc = cc_proc_aead(req, DRV_CRYPTO_DIRECTION_ENCRYPT); + if (rc != -EINPROGRESS && rc != -EBUSY) req->iv = areq_ctx->backup_iv; return rc; } -#if SSI_CC_HAS_AES_CCM -static int ssi_rfc4309_ccm_encrypt(struct aead_request *req) +static int cc_rfc4309_ccm_encrypt(struct aead_request *req) { - /* Very similar to ssi_aead_encrypt() above. */ + /* Very similar to cc_aead_encrypt() above. */ struct aead_req_ctx *areq_ctx = aead_request_ctx(req); struct crypto_aead *tfm = crypto_aead_reqtfm(req); - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); struct device *dev = drvdata_to_dev(ctx->drvdata); int rc = -EINVAL; @@ -2170,17 +2084,16 @@ static int ssi_rfc4309_ccm_encrypt(struct aead_request *req) areq_ctx->backup_giv = NULL; areq_ctx->is_gcm4543 = true; - ssi_rfc4309_ccm_process(req); + cc_proc_rfc4309_ccm(req); - rc = ssi_aead_process(req, DRV_CRYPTO_DIRECTION_ENCRYPT); - if (rc != -EINPROGRESS) + rc = cc_proc_aead(req, DRV_CRYPTO_DIRECTION_ENCRYPT); + if (rc != -EINPROGRESS && rc != -EBUSY) req->iv = areq_ctx->backup_iv; out: return rc; } -#endif /* SSI_CC_HAS_AES_CCM */ -static int ssi_aead_decrypt(struct aead_request *req) +static int cc_aead_decrypt(struct aead_request *req) { struct aead_req_ctx *areq_ctx = aead_request_ctx(req); int rc; @@ -2192,18 +2105,17 @@ static int ssi_aead_decrypt(struct aead_request *req) areq_ctx->plaintext_authenticate_only = false; - rc = ssi_aead_process(req, DRV_CRYPTO_DIRECTION_DECRYPT); - if (rc != -EINPROGRESS) + rc = cc_proc_aead(req, DRV_CRYPTO_DIRECTION_DECRYPT); + if (rc != -EINPROGRESS && rc != -EBUSY) req->iv = areq_ctx->backup_iv; return rc; } -#if SSI_CC_HAS_AES_CCM -static int ssi_rfc4309_ccm_decrypt(struct aead_request *req) +static int cc_rfc4309_ccm_decrypt(struct aead_request *req) { struct crypto_aead *tfm = crypto_aead_reqtfm(req); - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); struct device *dev = drvdata_to_dev(ctx->drvdata); struct aead_req_ctx *areq_ctx = aead_request_ctx(req); int rc = -EINVAL; @@ -2218,22 +2130,20 @@ static int ssi_rfc4309_ccm_decrypt(struct aead_request *req) areq_ctx->backup_giv = NULL; areq_ctx->is_gcm4543 = true; - ssi_rfc4309_ccm_process(req); + cc_proc_rfc4309_ccm(req); - rc = ssi_aead_process(req, DRV_CRYPTO_DIRECTION_DECRYPT); - if (rc != -EINPROGRESS) + rc = cc_proc_aead(req, DRV_CRYPTO_DIRECTION_DECRYPT); + if (rc != -EINPROGRESS && rc != -EBUSY) req->iv = areq_ctx->backup_iv; out: return rc; } -#endif /* SSI_CC_HAS_AES_CCM */ - -#if SSI_CC_HAS_AES_GCM -static int ssi_rfc4106_gcm_setkey(struct crypto_aead *tfm, const u8 *key, unsigned int keylen) +static int cc_rfc4106_gcm_setkey(struct crypto_aead *tfm, const u8 *key, + unsigned int keylen) { - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); struct device *dev = drvdata_to_dev(ctx->drvdata); dev_dbg(dev, "%s() keylen %d, key %p\n", __func__, keylen, key); @@ -2244,12 +2154,13 @@ static int ssi_rfc4106_gcm_setkey(struct crypto_aead *tfm, const u8 *key, unsign keylen -= 4; memcpy(ctx->ctr_nonce, key + keylen, 4); - return ssi_aead_setkey(tfm, key, keylen); + return cc_aead_setkey(tfm, key, keylen); } -static int ssi_rfc4543_gcm_setkey(struct crypto_aead *tfm, const u8 *key, unsigned int keylen) +static int cc_rfc4543_gcm_setkey(struct crypto_aead *tfm, const u8 *key, + unsigned int keylen) { - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); struct device *dev = drvdata_to_dev(ctx->drvdata); dev_dbg(dev, "%s() keylen %d, key %p\n", __func__, keylen, key); @@ -2260,11 +2171,11 @@ static int ssi_rfc4543_gcm_setkey(struct crypto_aead *tfm, const u8 *key, unsign keylen -= 4; memcpy(ctx->ctr_nonce, key + keylen, 4); - return ssi_aead_setkey(tfm, key, keylen); + return cc_aead_setkey(tfm, key, keylen); } -static int ssi_gcm_setauthsize(struct crypto_aead *authenc, - unsigned int authsize) +static int cc_gcm_setauthsize(struct crypto_aead *authenc, + unsigned int authsize) { switch (authsize) { case 4: @@ -2279,13 +2190,13 @@ static int ssi_gcm_setauthsize(struct crypto_aead *authenc, return -EINVAL; } - return ssi_aead_setauthsize(authenc, authsize); + return cc_aead_setauthsize(authenc, authsize); } -static int ssi_rfc4106_gcm_setauthsize(struct crypto_aead *authenc, - unsigned int authsize) +static int cc_rfc4106_gcm_setauthsize(struct crypto_aead *authenc, + unsigned int authsize) { - struct ssi_aead_ctx *ctx = crypto_aead_ctx(authenc); + struct cc_aead_ctx *ctx = crypto_aead_ctx(authenc); struct device *dev = drvdata_to_dev(ctx->drvdata); dev_dbg(dev, "authsize %d\n", authsize); @@ -2299,13 +2210,13 @@ static int ssi_rfc4106_gcm_setauthsize(struct crypto_aead *authenc, return -EINVAL; } - return ssi_aead_setauthsize(authenc, authsize); + return cc_aead_setauthsize(authenc, authsize); } -static int ssi_rfc4543_gcm_setauthsize(struct crypto_aead *authenc, - unsigned int authsize) +static int cc_rfc4543_gcm_setauthsize(struct crypto_aead *authenc, + unsigned int authsize) { - struct ssi_aead_ctx *ctx = crypto_aead_ctx(authenc); + struct cc_aead_ctx *ctx = crypto_aead_ctx(authenc); struct device *dev = drvdata_to_dev(ctx->drvdata); dev_dbg(dev, "authsize %d\n", authsize); @@ -2313,15 +2224,15 @@ static int ssi_rfc4543_gcm_setauthsize(struct crypto_aead *authenc, if (authsize != 16) return -EINVAL; - return ssi_aead_setauthsize(authenc, authsize); + return cc_aead_setauthsize(authenc, authsize); } -static int ssi_rfc4106_gcm_encrypt(struct aead_request *req) +static int cc_rfc4106_gcm_encrypt(struct aead_request *req) { - /* Very similar to ssi_aead_encrypt() above. */ + /* Very similar to cc_aead_encrypt() above. */ struct crypto_aead *tfm = crypto_aead_reqtfm(req); - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); struct device *dev = drvdata_to_dev(ctx->drvdata); struct aead_req_ctx *areq_ctx = aead_request_ctx(req); int rc = -EINVAL; @@ -2337,19 +2248,19 @@ static int ssi_rfc4106_gcm_encrypt(struct aead_request *req) areq_ctx->plaintext_authenticate_only = false; - ssi_rfc4_gcm_process(req); + cc_proc_rfc4_gcm(req); areq_ctx->is_gcm4543 = true; - rc = ssi_aead_process(req, DRV_CRYPTO_DIRECTION_ENCRYPT); - if (rc != -EINPROGRESS) + rc = cc_proc_aead(req, DRV_CRYPTO_DIRECTION_ENCRYPT); + if (rc != -EINPROGRESS && rc != -EBUSY) req->iv = areq_ctx->backup_iv; out: return rc; } -static int ssi_rfc4543_gcm_encrypt(struct aead_request *req) +static int cc_rfc4543_gcm_encrypt(struct aead_request *req) { - /* Very similar to ssi_aead_encrypt() above. */ + /* Very similar to cc_aead_encrypt() above. */ struct aead_req_ctx *areq_ctx = aead_request_ctx(req); int rc; @@ -2361,22 +2272,22 @@ static int ssi_rfc4543_gcm_encrypt(struct aead_request *req) areq_ctx->backup_iv = req->iv; areq_ctx->backup_giv = NULL; - ssi_rfc4_gcm_process(req); + cc_proc_rfc4_gcm(req); areq_ctx->is_gcm4543 = true; - rc = ssi_aead_process(req, DRV_CRYPTO_DIRECTION_ENCRYPT); - if (rc != -EINPROGRESS) + rc = cc_proc_aead(req, DRV_CRYPTO_DIRECTION_ENCRYPT); + if (rc != -EINPROGRESS && rc != -EBUSY) req->iv = areq_ctx->backup_iv; return rc; } -static int ssi_rfc4106_gcm_decrypt(struct aead_request *req) +static int cc_rfc4106_gcm_decrypt(struct aead_request *req) { - /* Very similar to ssi_aead_decrypt() above. */ + /* Very similar to cc_aead_decrypt() above. */ struct crypto_aead *tfm = crypto_aead_reqtfm(req); - struct ssi_aead_ctx *ctx = crypto_aead_ctx(tfm); + struct cc_aead_ctx *ctx = crypto_aead_ctx(tfm); struct device *dev = drvdata_to_dev(ctx->drvdata); struct aead_req_ctx *areq_ctx = aead_request_ctx(req); int rc = -EINVAL; @@ -2392,19 +2303,19 @@ static int ssi_rfc4106_gcm_decrypt(struct aead_request *req) areq_ctx->plaintext_authenticate_only = false; - ssi_rfc4_gcm_process(req); + cc_proc_rfc4_gcm(req); areq_ctx->is_gcm4543 = true; - rc = ssi_aead_process(req, DRV_CRYPTO_DIRECTION_DECRYPT); - if (rc != -EINPROGRESS) + rc = cc_proc_aead(req, DRV_CRYPTO_DIRECTION_DECRYPT); + if (rc != -EINPROGRESS && rc != -EBUSY) req->iv = areq_ctx->backup_iv; out: return rc; } -static int ssi_rfc4543_gcm_decrypt(struct aead_request *req) +static int cc_rfc4543_gcm_decrypt(struct aead_request *req) { - /* Very similar to ssi_aead_decrypt() above. */ + /* Very similar to cc_aead_decrypt() above. */ struct aead_req_ctx *areq_ctx = aead_request_ctx(req); int rc; @@ -2416,31 +2327,30 @@ static int ssi_rfc4543_gcm_decrypt(struct aead_request *req) areq_ctx->backup_iv = req->iv; areq_ctx->backup_giv = NULL; - ssi_rfc4_gcm_process(req); + cc_proc_rfc4_gcm(req); areq_ctx->is_gcm4543 = true; - rc = ssi_aead_process(req, DRV_CRYPTO_DIRECTION_DECRYPT); - if (rc != -EINPROGRESS) + rc = cc_proc_aead(req, DRV_CRYPTO_DIRECTION_DECRYPT); + if (rc != -EINPROGRESS && rc != -EBUSY) req->iv = areq_ctx->backup_iv; return rc; } -#endif /* SSI_CC_HAS_AES_GCM */ /* DX Block aead alg */ -static struct ssi_alg_template aead_algs[] = { +static struct cc_alg_template aead_algs[] = { { .name = "authenc(hmac(sha1),cbc(aes))", .driver_name = "authenc-hmac-sha1-cbc-aes-dx", .blocksize = AES_BLOCK_SIZE, .type = CRYPTO_ALG_TYPE_AEAD, .template_aead = { - .setkey = ssi_aead_setkey, - .setauthsize = ssi_aead_setauthsize, - .encrypt = ssi_aead_encrypt, - .decrypt = ssi_aead_decrypt, - .init = ssi_aead_init, - .exit = ssi_aead_exit, + .setkey = cc_aead_setkey, + .setauthsize = cc_aead_setauthsize, + .encrypt = cc_aead_encrypt, + .decrypt = cc_aead_decrypt, + .init = cc_aead_init, + .exit = cc_aead_exit, .ivsize = AES_BLOCK_SIZE, .maxauthsize = SHA1_DIGEST_SIZE, }, @@ -2454,12 +2364,12 @@ static struct ssi_alg_template aead_algs[] = { .blocksize = DES3_EDE_BLOCK_SIZE, .type = CRYPTO_ALG_TYPE_AEAD, .template_aead = { - .setkey = ssi_aead_setkey, - .setauthsize = ssi_aead_setauthsize, - .encrypt = ssi_aead_encrypt, - .decrypt = ssi_aead_decrypt, - .init = ssi_aead_init, - .exit = ssi_aead_exit, + .setkey = cc_aead_setkey, + .setauthsize = cc_aead_setauthsize, + .encrypt = cc_aead_encrypt, + .decrypt = cc_aead_decrypt, + .init = cc_aead_init, + .exit = cc_aead_exit, .ivsize = DES3_EDE_BLOCK_SIZE, .maxauthsize = SHA1_DIGEST_SIZE, }, @@ -2473,12 +2383,12 @@ static struct ssi_alg_template aead_algs[] = { .blocksize = AES_BLOCK_SIZE, .type = CRYPTO_ALG_TYPE_AEAD, .template_aead = { - .setkey = ssi_aead_setkey, - .setauthsize = ssi_aead_setauthsize, - .encrypt = ssi_aead_encrypt, - .decrypt = ssi_aead_decrypt, - .init = ssi_aead_init, - .exit = ssi_aead_exit, + .setkey = cc_aead_setkey, + .setauthsize = cc_aead_setauthsize, + .encrypt = cc_aead_encrypt, + .decrypt = cc_aead_decrypt, + .init = cc_aead_init, + .exit = cc_aead_exit, .ivsize = AES_BLOCK_SIZE, .maxauthsize = SHA256_DIGEST_SIZE, }, @@ -2492,12 +2402,12 @@ static struct ssi_alg_template aead_algs[] = { .blocksize = DES3_EDE_BLOCK_SIZE, .type = CRYPTO_ALG_TYPE_AEAD, .template_aead = { - .setkey = ssi_aead_setkey, - .setauthsize = ssi_aead_setauthsize, - .encrypt = ssi_aead_encrypt, - .decrypt = ssi_aead_decrypt, - .init = ssi_aead_init, - .exit = ssi_aead_exit, + .setkey = cc_aead_setkey, + .setauthsize = cc_aead_setauthsize, + .encrypt = cc_aead_encrypt, + .decrypt = cc_aead_decrypt, + .init = cc_aead_init, + .exit = cc_aead_exit, .ivsize = DES3_EDE_BLOCK_SIZE, .maxauthsize = SHA256_DIGEST_SIZE, }, @@ -2511,12 +2421,12 @@ static struct ssi_alg_template aead_algs[] = { .blocksize = AES_BLOCK_SIZE, .type = CRYPTO_ALG_TYPE_AEAD, .template_aead = { - .setkey = ssi_aead_setkey, - .setauthsize = ssi_aead_setauthsize, - .encrypt = ssi_aead_encrypt, - .decrypt = ssi_aead_decrypt, - .init = ssi_aead_init, - .exit = ssi_aead_exit, + .setkey = cc_aead_setkey, + .setauthsize = cc_aead_setauthsize, + .encrypt = cc_aead_encrypt, + .decrypt = cc_aead_decrypt, + .init = cc_aead_init, + .exit = cc_aead_exit, .ivsize = AES_BLOCK_SIZE, .maxauthsize = AES_BLOCK_SIZE, }, @@ -2530,12 +2440,12 @@ static struct ssi_alg_template aead_algs[] = { .blocksize = 1, .type = CRYPTO_ALG_TYPE_AEAD, .template_aead = { - .setkey = ssi_aead_setkey, - .setauthsize = ssi_aead_setauthsize, - .encrypt = ssi_aead_encrypt, - .decrypt = ssi_aead_decrypt, - .init = ssi_aead_init, - .exit = ssi_aead_exit, + .setkey = cc_aead_setkey, + .setauthsize = cc_aead_setauthsize, + .encrypt = cc_aead_encrypt, + .decrypt = cc_aead_decrypt, + .init = cc_aead_init, + .exit = cc_aead_exit, .ivsize = CTR_RFC3686_IV_SIZE, .maxauthsize = SHA1_DIGEST_SIZE, }, @@ -2549,12 +2459,12 @@ static struct ssi_alg_template aead_algs[] = { .blocksize = 1, .type = CRYPTO_ALG_TYPE_AEAD, .template_aead = { - .setkey = ssi_aead_setkey, - .setauthsize = ssi_aead_setauthsize, - .encrypt = ssi_aead_encrypt, - .decrypt = ssi_aead_decrypt, - .init = ssi_aead_init, - .exit = ssi_aead_exit, + .setkey = cc_aead_setkey, + .setauthsize = cc_aead_setauthsize, + .encrypt = cc_aead_encrypt, + .decrypt = cc_aead_decrypt, + .init = cc_aead_init, + .exit = cc_aead_exit, .ivsize = CTR_RFC3686_IV_SIZE, .maxauthsize = SHA256_DIGEST_SIZE, }, @@ -2568,12 +2478,12 @@ static struct ssi_alg_template aead_algs[] = { .blocksize = 1, .type = CRYPTO_ALG_TYPE_AEAD, .template_aead = { - .setkey = ssi_aead_setkey, - .setauthsize = ssi_aead_setauthsize, - .encrypt = ssi_aead_encrypt, - .decrypt = ssi_aead_decrypt, - .init = ssi_aead_init, - .exit = ssi_aead_exit, + .setkey = cc_aead_setkey, + .setauthsize = cc_aead_setauthsize, + .encrypt = cc_aead_encrypt, + .decrypt = cc_aead_decrypt, + .init = cc_aead_init, + .exit = cc_aead_exit, .ivsize = CTR_RFC3686_IV_SIZE, .maxauthsize = AES_BLOCK_SIZE, }, @@ -2581,19 +2491,18 @@ static struct ssi_alg_template aead_algs[] = { .flow_mode = S_DIN_to_AES, .auth_mode = DRV_HASH_XCBC_MAC, }, -#if SSI_CC_HAS_AES_CCM { .name = "ccm(aes)", .driver_name = "ccm-aes-dx", .blocksize = 1, .type = CRYPTO_ALG_TYPE_AEAD, .template_aead = { - .setkey = ssi_aead_setkey, - .setauthsize = ssi_ccm_setauthsize, - .encrypt = ssi_aead_encrypt, - .decrypt = ssi_aead_decrypt, - .init = ssi_aead_init, - .exit = ssi_aead_exit, + .setkey = cc_aead_setkey, + .setauthsize = cc_ccm_setauthsize, + .encrypt = cc_aead_encrypt, + .decrypt = cc_aead_decrypt, + .init = cc_aead_init, + .exit = cc_aead_exit, .ivsize = AES_BLOCK_SIZE, .maxauthsize = AES_BLOCK_SIZE, }, @@ -2607,12 +2516,12 @@ static struct ssi_alg_template aead_algs[] = { .blocksize = 1, .type = CRYPTO_ALG_TYPE_AEAD, .template_aead = { - .setkey = ssi_rfc4309_ccm_setkey, - .setauthsize = ssi_rfc4309_ccm_setauthsize, - .encrypt = ssi_rfc4309_ccm_encrypt, - .decrypt = ssi_rfc4309_ccm_decrypt, - .init = ssi_aead_init, - .exit = ssi_aead_exit, + .setkey = cc_rfc4309_ccm_setkey, + .setauthsize = cc_rfc4309_ccm_setauthsize, + .encrypt = cc_rfc4309_ccm_encrypt, + .decrypt = cc_rfc4309_ccm_decrypt, + .init = cc_aead_init, + .exit = cc_aead_exit, .ivsize = CCM_BLOCK_IV_SIZE, .maxauthsize = AES_BLOCK_SIZE, }, @@ -2620,20 +2529,18 @@ static struct ssi_alg_template aead_algs[] = { .flow_mode = S_DIN_to_AES, .auth_mode = DRV_HASH_NULL, }, -#endif /*SSI_CC_HAS_AES_CCM*/ -#if SSI_CC_HAS_AES_GCM { .name = "gcm(aes)", .driver_name = "gcm-aes-dx", .blocksize = 1, .type = CRYPTO_ALG_TYPE_AEAD, .template_aead = { - .setkey = ssi_aead_setkey, - .setauthsize = ssi_gcm_setauthsize, - .encrypt = ssi_aead_encrypt, - .decrypt = ssi_aead_decrypt, - .init = ssi_aead_init, - .exit = ssi_aead_exit, + .setkey = cc_aead_setkey, + .setauthsize = cc_gcm_setauthsize, + .encrypt = cc_aead_encrypt, + .decrypt = cc_aead_decrypt, + .init = cc_aead_init, + .exit = cc_aead_exit, .ivsize = 12, .maxauthsize = AES_BLOCK_SIZE, }, @@ -2647,12 +2554,12 @@ static struct ssi_alg_template aead_algs[] = { .blocksize = 1, .type = CRYPTO_ALG_TYPE_AEAD, .template_aead = { - .setkey = ssi_rfc4106_gcm_setkey, - .setauthsize = ssi_rfc4106_gcm_setauthsize, - .encrypt = ssi_rfc4106_gcm_encrypt, - .decrypt = ssi_rfc4106_gcm_decrypt, - .init = ssi_aead_init, - .exit = ssi_aead_exit, + .setkey = cc_rfc4106_gcm_setkey, + .setauthsize = cc_rfc4106_gcm_setauthsize, + .encrypt = cc_rfc4106_gcm_encrypt, + .decrypt = cc_rfc4106_gcm_decrypt, + .init = cc_aead_init, + .exit = cc_aead_exit, .ivsize = GCM_BLOCK_RFC4_IV_SIZE, .maxauthsize = AES_BLOCK_SIZE, }, @@ -2666,12 +2573,12 @@ static struct ssi_alg_template aead_algs[] = { .blocksize = 1, .type = CRYPTO_ALG_TYPE_AEAD, .template_aead = { - .setkey = ssi_rfc4543_gcm_setkey, - .setauthsize = ssi_rfc4543_gcm_setauthsize, - .encrypt = ssi_rfc4543_gcm_encrypt, - .decrypt = ssi_rfc4543_gcm_decrypt, - .init = ssi_aead_init, - .exit = ssi_aead_exit, + .setkey = cc_rfc4543_gcm_setkey, + .setauthsize = cc_rfc4543_gcm_setauthsize, + .encrypt = cc_rfc4543_gcm_encrypt, + .decrypt = cc_rfc4543_gcm_decrypt, + .init = cc_aead_init, + .exit = cc_aead_exit, .ivsize = GCM_BLOCK_RFC4_IV_SIZE, .maxauthsize = AES_BLOCK_SIZE, }, @@ -2679,52 +2586,51 @@ static struct ssi_alg_template aead_algs[] = { .flow_mode = S_DIN_to_AES, .auth_mode = DRV_HASH_NULL, }, -#endif /*SSI_CC_HAS_AES_GCM*/ }; -static struct ssi_crypto_alg *ssi_aead_create_alg( - struct ssi_alg_template *template, - struct device *dev) +static struct cc_crypto_alg *cc_create_aead_alg(struct cc_alg_template *tmpl, + struct device *dev) { - struct ssi_crypto_alg *t_alg; + struct cc_crypto_alg *t_alg; struct aead_alg *alg; t_alg = kzalloc(sizeof(*t_alg), GFP_KERNEL); if (!t_alg) return ERR_PTR(-ENOMEM); - alg = &template->template_aead; + alg = &tmpl->template_aead; - snprintf(alg->base.cra_name, CRYPTO_MAX_ALG_NAME, "%s", template->name); + snprintf(alg->base.cra_name, CRYPTO_MAX_ALG_NAME, "%s", tmpl->name); snprintf(alg->base.cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", - template->driver_name); + tmpl->driver_name); alg->base.cra_module = THIS_MODULE; - alg->base.cra_priority = SSI_CRA_PRIO; + alg->base.cra_priority = CC_CRA_PRIO; - alg->base.cra_ctxsize = sizeof(struct ssi_aead_ctx); + alg->base.cra_ctxsize = sizeof(struct cc_aead_ctx); alg->base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY | - template->type; - alg->init = ssi_aead_init; - alg->exit = ssi_aead_exit; + tmpl->type; + alg->init = cc_aead_init; + alg->exit = cc_aead_exit; t_alg->aead_alg = *alg; - t_alg->cipher_mode = template->cipher_mode; - t_alg->flow_mode = template->flow_mode; - t_alg->auth_mode = template->auth_mode; + t_alg->cipher_mode = tmpl->cipher_mode; + t_alg->flow_mode = tmpl->flow_mode; + t_alg->auth_mode = tmpl->auth_mode; return t_alg; } -int ssi_aead_free(struct ssi_drvdata *drvdata) +int cc_aead_free(struct cc_drvdata *drvdata) { - struct ssi_crypto_alg *t_alg, *n; - struct ssi_aead_handle *aead_handle = - (struct ssi_aead_handle *)drvdata->aead_handle; + struct cc_crypto_alg *t_alg, *n; + struct cc_aead_handle *aead_handle = + (struct cc_aead_handle *)drvdata->aead_handle; if (aead_handle) { /* Remove registered algs */ - list_for_each_entry_safe(t_alg, n, &aead_handle->aead_list, entry) { + list_for_each_entry_safe(t_alg, n, &aead_handle->aead_list, + entry) { crypto_unregister_aead(&t_alg->aead_alg); list_del(&t_alg->entry); kfree(t_alg); @@ -2736,10 +2642,10 @@ int ssi_aead_free(struct ssi_drvdata *drvdata) return 0; } -int ssi_aead_alloc(struct ssi_drvdata *drvdata) +int cc_aead_alloc(struct cc_drvdata *drvdata) { - struct ssi_aead_handle *aead_handle; - struct ssi_crypto_alg *t_alg; + struct cc_aead_handle *aead_handle; + struct cc_crypto_alg *t_alg; int rc = -ENOMEM; int alg; struct device *dev = drvdata_to_dev(drvdata); @@ -2753,8 +2659,9 @@ int ssi_aead_alloc(struct ssi_drvdata *drvdata) INIT_LIST_HEAD(&aead_handle->aead_list); drvdata->aead_handle = aead_handle; - aead_handle->sram_workspace_addr = ssi_sram_mgr_alloc( - drvdata, MAX_HMAC_DIGEST_SIZE); + aead_handle->sram_workspace_addr = cc_sram_alloc(drvdata, + MAX_HMAC_DIGEST_SIZE); + if (aead_handle->sram_workspace_addr == NULL_SRAM_ADDR) { dev_err(dev, "SRAM pool exhausted\n"); rc = -ENOMEM; @@ -2763,7 +2670,7 @@ int ssi_aead_alloc(struct ssi_drvdata *drvdata) /* Linux crypto */ for (alg = 0; alg < ARRAY_SIZE(aead_algs); alg++) { - t_alg = ssi_aead_create_alg(&aead_algs[alg], dev); + t_alg = cc_create_aead_alg(&aead_algs[alg], dev); if (IS_ERR(t_alg)) { rc = PTR_ERR(t_alg); dev_err(dev, "%s alg allocation failed\n", @@ -2772,7 +2679,7 @@ int ssi_aead_alloc(struct ssi_drvdata *drvdata) } t_alg->drvdata = drvdata; rc = crypto_register_aead(&t_alg->aead_alg); - if (unlikely(rc != 0)) { + if (rc) { dev_err(dev, "%s alg registration failed\n", t_alg->aead_alg.base.cra_driver_name); goto fail2; @@ -2788,7 +2695,7 @@ int ssi_aead_alloc(struct ssi_drvdata *drvdata) fail2: kfree(t_alg); fail1: - ssi_aead_free(drvdata); + cc_aead_free(drvdata); fail0: return rc; } diff --git a/drivers/staging/ccree/ssi_aead.h b/drivers/staging/ccree/cc_aead.h index e85bcd917e7b..5edf3b351fa4 100644 --- a/drivers/staging/ccree/ssi_aead.h +++ b/drivers/staging/ccree/cc_aead.h @@ -1,25 +1,12 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ -/* \file ssi_aead.h +/* \file cc_aead.h * ARM CryptoCell AEAD Crypto API */ -#ifndef __SSI_AEAD_H__ -#define __SSI_AEAD_H__ +#ifndef __CC_AEAD_H__ +#define __CC_AEAD_H__ #include <linux/kernel.h> #include <crypto/algapi.h> @@ -28,7 +15,7 @@ /* mac_cmp - HW writes 8 B but all bytes hold the same value */ #define ICV_CMP_SIZE 8 #define CCM_CONFIG_BUF_SIZE (AES_BLOCK_SIZE * 3) -#define MAX_MAC_SIZE MAX(SHA256_DIGEST_SIZE, AES_BLOCK_SIZE) +#define MAX_MAC_SIZE SHA256_DIGEST_SIZE /* defines for AES GCM configuration buffer */ #define GCM_BLOCK_LEN_SIZE 8 @@ -74,32 +61,37 @@ struct aead_req_ctx { } gcm_len_block; u8 ccm_config[CCM_CONFIG_BUF_SIZE] ____cacheline_aligned; - unsigned int hw_iv_size ____cacheline_aligned; /*HW actual size input*/ - u8 backup_mac[MAX_MAC_SIZE]; /*used to prevent cache coherence problem*/ + /* HW actual size input */ + unsigned int hw_iv_size ____cacheline_aligned; + /* used to prevent cache coherence problem */ + u8 backup_mac[MAX_MAC_SIZE]; u8 *backup_iv; /*store iv for generated IV flow*/ u8 *backup_giv; /*store iv for rfc3686(ctr) flow*/ dma_addr_t mac_buf_dma_addr; /* internal ICV DMA buffer */ - dma_addr_t ccm_iv0_dma_addr; /* buffer for internal ccm configurations */ + /* buffer for internal ccm configurations */ + dma_addr_t ccm_iv0_dma_addr; dma_addr_t icv_dma_addr; /* Phys. address of ICV */ //used in gcm - dma_addr_t gcm_iv_inc1_dma_addr; /* buffer for internal gcm configurations */ - dma_addr_t gcm_iv_inc2_dma_addr; /* buffer for internal gcm configurations */ + /* buffer for internal gcm configurations */ + dma_addr_t gcm_iv_inc1_dma_addr; + /* buffer for internal gcm configurations */ + dma_addr_t gcm_iv_inc2_dma_addr; dma_addr_t hkey_dma_addr; /* Phys. address of hkey */ dma_addr_t gcm_block_len_dma_addr; /* Phys. address of gcm block len */ bool is_gcm4543; u8 *icv_virt_addr; /* Virt. address of ICV */ struct async_gen_req_ctx gen_ctx; - struct ssi_mlli assoc; - struct ssi_mlli src; - struct ssi_mlli dst; + struct cc_mlli assoc; + struct cc_mlli src; + struct cc_mlli dst; struct scatterlist *src_sgl; struct scatterlist *dst_sgl; unsigned int src_offset; unsigned int dst_offset; - enum ssi_req_dma_buf_type assoc_buff_type; - enum ssi_req_dma_buf_type data_buff_type; + enum cc_req_dma_buf_type assoc_buff_type; + enum cc_req_dma_buf_type data_buff_type; struct mlli_params mlli_params; unsigned int cryptlen; struct scatterlist ccm_adata_sg; @@ -111,7 +103,7 @@ struct aead_req_ctx { bool plaintext_authenticate_only; //for gcm_rfc4543 }; -int ssi_aead_alloc(struct ssi_drvdata *drvdata); -int ssi_aead_free(struct ssi_drvdata *drvdata); +int cc_aead_alloc(struct cc_drvdata *drvdata); +int cc_aead_free(struct cc_drvdata *drvdata); -#endif /*__SSI_AEAD_H__*/ +#endif /*__CC_AEAD_H__*/ diff --git a/drivers/staging/ccree/ssi_buffer_mgr.c b/drivers/staging/ccree/cc_buffer_mgr.c index 1f8a225530a8..14b2eabbf70a 100644 --- a/drivers/staging/ccree/ssi_buffer_mgr.c +++ b/drivers/staging/ccree/cc_buffer_mgr.c @@ -1,42 +1,17 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ -#include <linux/crypto.h> -#include <linux/version.h> -#include <crypto/algapi.h> #include <crypto/internal/aead.h> -#include <crypto/hash.h> #include <crypto/authenc.h> #include <crypto/scatterwalk.h> #include <linux/dmapool.h> #include <linux/dma-mapping.h> -#include <linux/crypto.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include "ssi_buffer_mgr.h" +#include "cc_buffer_mgr.h" #include "cc_lli_defs.h" -#include "ssi_cipher.h" -#include "ssi_hash.h" -#include "ssi_aead.h" - -#define GET_DMA_BUFFER_TYPE(buff_type) ( \ - ((buff_type) == SSI_DMA_BUF_NULL) ? "BUF_NULL" : \ - ((buff_type) == SSI_DMA_BUF_DLLI) ? "BUF_DLLI" : \ - ((buff_type) == SSI_DMA_BUF_MLLI) ? "BUF_MLLI" : "BUF_INVALID") +#include "cc_cipher.h" +#include "cc_hash.h" +#include "cc_aead.h" enum dma_buffer_type { DMA_NULL_TYPE = -1, @@ -64,25 +39,62 @@ struct buffer_array { u32 *mlli_nents[MAX_NUM_OF_BUFFERS_IN_MLLI]; }; +static inline char *cc_dma_buf_type(enum cc_req_dma_buf_type type) +{ + switch (type) { + case CC_DMA_BUF_NULL: + return "BUF_NULL"; + case CC_DMA_BUF_DLLI: + return "BUF_DLLI"; + case CC_DMA_BUF_MLLI: + return "BUF_MLLI"; + default: + return "BUF_INVALID"; + } +} + /** - * ssi_buffer_mgr_get_sgl_nents() - Get scatterlist number of entries. + * cc_copy_mac() - Copy MAC to temporary location + * + * @dev: device object + * @req: aead request object + * @dir: [IN] copy from/to sgl + */ +static void cc_copy_mac(struct device *dev, struct aead_request *req, + enum cc_sg_cpy_direct dir) +{ + struct aead_req_ctx *areq_ctx = aead_request_ctx(req); + struct crypto_aead *tfm = crypto_aead_reqtfm(req); + u32 skip = req->assoclen + req->cryptlen; + + if (areq_ctx->is_gcm4543) + skip += crypto_aead_ivsize(tfm); + + cc_copy_sg_portion(dev, areq_ctx->backup_mac, req->src, + (skip - areq_ctx->req_authsize), skip, dir); +} + +/** + * cc_get_sgl_nents() - Get scatterlist number of entries. * * @sg_list: SG list * @nbytes: [IN] Total SGL data bytes. * @lbytes: [OUT] Returns the amount of bytes at the last entry */ -static unsigned int ssi_buffer_mgr_get_sgl_nents( - struct device *dev, struct scatterlist *sg_list, - unsigned int nbytes, u32 *lbytes, bool *is_chained) +static unsigned int cc_get_sgl_nents(struct device *dev, + struct scatterlist *sg_list, + unsigned int nbytes, u32 *lbytes, + bool *is_chained) { unsigned int nents = 0; - while (nbytes != 0) { - if (sg_list->length != 0) { + while (nbytes && sg_list) { + if (sg_list->length) { nents++; /* get the number of bytes in the last entry */ *lbytes = nbytes; - nbytes -= (sg_list->length > nbytes) ? nbytes : sg_list->length; + nbytes -= (sg_list->length > nbytes) ? + nbytes : sg_list->length; sg_list = sg_next(sg_list); } else { sg_list = (struct scatterlist *)sg_page(sg_list); @@ -95,11 +107,11 @@ static unsigned int ssi_buffer_mgr_get_sgl_nents( } /** - * ssi_buffer_mgr_zero_sgl() - Zero scatter scatter list data. + * cc_zero_sgl() - Zero scatter scatter list data. * * @sgl: */ -void ssi_buffer_mgr_zero_sgl(struct scatterlist *sgl, u32 data_len) +void cc_zero_sgl(struct scatterlist *sgl, u32 data_len) { struct scatterlist *current_sg = sgl; int sg_index = 0; @@ -116,7 +128,7 @@ void ssi_buffer_mgr_zero_sgl(struct scatterlist *sgl, u32 data_len) } /** - * ssi_buffer_mgr_copy_scatterlist_portion() - Copy scatter list data, + * cc_copy_sg_portion() - Copy scatter list data, * from to_skip to end, to dest and vice versa * * @dest: @@ -125,21 +137,19 @@ void ssi_buffer_mgr_zero_sgl(struct scatterlist *sgl, u32 data_len) * @end: * @direct: */ -void ssi_buffer_mgr_copy_scatterlist_portion( - struct device *dev, u8 *dest, - struct scatterlist *sg, u32 to_skip, - u32 end, enum ssi_sg_cpy_direct direct) +void cc_copy_sg_portion(struct device *dev, u8 *dest, struct scatterlist *sg, + u32 to_skip, u32 end, enum cc_sg_cpy_direct direct) { u32 nents, lbytes; - nents = ssi_buffer_mgr_get_sgl_nents(dev, sg, end, &lbytes, NULL); + nents = cc_get_sgl_nents(dev, sg, end, &lbytes, NULL); sg_copy_buffer(sg, nents, (void *)dest, (end - to_skip + 1), to_skip, - (direct == SSI_SG_TO_BUF)); + (direct == CC_SG_TO_BUF)); } -static inline int ssi_buffer_mgr_render_buff_to_mlli( - struct device *dev, dma_addr_t buff_dma, u32 buff_size, - u32 *curr_nents, u32 **mlli_entry_pp) +static int cc_render_buff_to_mlli(struct device *dev, dma_addr_t buff_dma, + u32 buff_size, u32 *curr_nents, + u32 **mlli_entry_pp) { u32 *mlli_entry_p = *mlli_entry_pp; u32 new_nents; @@ -173,26 +183,25 @@ static inline int ssi_buffer_mgr_render_buff_to_mlli( return 0; } -static inline int ssi_buffer_mgr_render_scatterlist_to_mlli( - struct device *dev, struct scatterlist *sgl, - u32 sgl_data_len, u32 sgl_offset, u32 *curr_nents, - u32 **mlli_entry_pp) +static int cc_render_sg_to_mlli(struct device *dev, struct scatterlist *sgl, + u32 sgl_data_len, u32 sgl_offset, + u32 *curr_nents, u32 **mlli_entry_pp) { struct scatterlist *curr_sgl = sgl; u32 *mlli_entry_p = *mlli_entry_pp; s32 rc = 0; - for ( ; (curr_sgl) && (sgl_data_len != 0); + for ( ; (curr_sgl && sgl_data_len); curr_sgl = sg_next(curr_sgl)) { u32 entry_data_len = (sgl_data_len > sg_dma_len(curr_sgl) - sgl_offset) ? sg_dma_len(curr_sgl) - sgl_offset : sgl_data_len; sgl_data_len -= entry_data_len; - rc = ssi_buffer_mgr_render_buff_to_mlli( - dev, sg_dma_address(curr_sgl) + sgl_offset, - entry_data_len, curr_nents, &mlli_entry_p); - if (rc != 0) + rc = cc_render_buff_to_mlli(dev, sg_dma_address(curr_sgl) + + sgl_offset, entry_data_len, + curr_nents, &mlli_entry_p); + if (rc) return rc; sgl_offset = 0; @@ -201,10 +210,8 @@ static inline int ssi_buffer_mgr_render_scatterlist_to_mlli( return 0; } -static int ssi_buffer_mgr_generate_mlli( - struct device *dev, - struct buffer_array *sg_data, - struct mlli_params *mlli_params) +static int cc_generate_mlli(struct device *dev, struct buffer_array *sg_data, + struct mlli_params *mlli_params, gfp_t flags) { u32 *mlli_p; u32 total_nents = 0, prev_total_nents = 0; @@ -213,10 +220,10 @@ static int ssi_buffer_mgr_generate_mlli( dev_dbg(dev, "NUM of SG's = %d\n", sg_data->num_of_buffers); /* Allocate memory from the pointed pool */ - mlli_params->mlli_virt_addr = dma_pool_alloc( - mlli_params->curr_pool, GFP_KERNEL, - &mlli_params->mlli_dma_addr); - if (unlikely(!mlli_params->mlli_virt_addr)) { + mlli_params->mlli_virt_addr = + dma_pool_alloc(mlli_params->curr_pool, flags, + &mlli_params->mlli_dma_addr); + if (!mlli_params->mlli_virt_addr) { dev_err(dev, "dma_pool_alloc() failed\n"); rc = -ENOMEM; goto build_mlli_exit; @@ -225,17 +232,19 @@ static int ssi_buffer_mgr_generate_mlli( mlli_p = (u32 *)mlli_params->mlli_virt_addr; /* go over all SG's and link it to one MLLI table */ for (i = 0; i < sg_data->num_of_buffers; i++) { + union buffer_array_entry *entry = &sg_data->entry[i]; + u32 tot_len = sg_data->total_data_len[i]; + u32 offset = sg_data->offset[i]; + if (sg_data->type[i] == DMA_SGL_TYPE) - rc = ssi_buffer_mgr_render_scatterlist_to_mlli( - dev, sg_data->entry[i].sgl, - sg_data->total_data_len[i], sg_data->offset[i], - &total_nents, &mlli_p); + rc = cc_render_sg_to_mlli(dev, entry->sgl, tot_len, + offset, &total_nents, + &mlli_p); else /*DMA_BUFF_TYPE*/ - rc = ssi_buffer_mgr_render_buff_to_mlli( - dev, sg_data->entry[i].buffer_dma, - sg_data->total_data_len[i], &total_nents, - &mlli_p); - if (rc != 0) + rc = cc_render_buff_to_mlli(dev, entry->buffer_dma, + tot_len, &total_nents, + &mlli_p); + if (rc) return rc; /* set last bit in the current table */ @@ -260,10 +269,10 @@ build_mlli_exit: return rc; } -static inline void ssi_buffer_mgr_add_buffer_entry( - struct device *dev, struct buffer_array *sgl_data, - dma_addr_t buffer_dma, unsigned int buffer_len, - bool is_last_entry, u32 *mlli_nents) +static void cc_add_buffer_entry(struct device *dev, + struct buffer_array *sgl_data, + dma_addr_t buffer_dma, unsigned int buffer_len, + bool is_last_entry, u32 *mlli_nents) { unsigned int index = sgl_data->num_of_buffers; @@ -281,15 +290,10 @@ static inline void ssi_buffer_mgr_add_buffer_entry( sgl_data->num_of_buffers++; } -static inline void ssi_buffer_mgr_add_scatterlist_entry( - struct device *dev, - struct buffer_array *sgl_data, - unsigned int nents, - struct scatterlist *sgl, - unsigned int data_len, - unsigned int data_offset, - bool is_last_table, - u32 *mlli_nents) +static void cc_add_sg_entry(struct device *dev, struct buffer_array *sgl_data, + unsigned int nents, struct scatterlist *sgl, + unsigned int data_len, unsigned int data_offset, + bool is_last_table, u32 *mlli_nents) { unsigned int index = sgl_data->num_of_buffers; @@ -307,9 +311,8 @@ static inline void ssi_buffer_mgr_add_scatterlist_entry( sgl_data->num_of_buffers++; } -static int -ssi_buffer_mgr_dma_map_sg(struct device *dev, struct scatterlist *sg, u32 nents, - enum dma_data_direction direction) +static int cc_dma_map_sg(struct device *dev, struct scatterlist *sg, u32 nents, + enum dma_data_direction direction) { u32 i, j; struct scatterlist *l_sg = sg; @@ -317,7 +320,7 @@ ssi_buffer_mgr_dma_map_sg(struct device *dev, struct scatterlist *sg, u32 nents, for (i = 0; i < nents; i++) { if (!l_sg) break; - if (unlikely(dma_map_sg(dev, l_sg, 1, direction) != 1)) { + if (dma_map_sg(dev, l_sg, 1, direction) != 1) { dev_err(dev, "dma_map_page() sg buffer failed\n"); goto err; } @@ -336,17 +339,15 @@ err: return 0; } -static int ssi_buffer_mgr_map_scatterlist( - struct device *dev, struct scatterlist *sg, - unsigned int nbytes, int direction, - u32 *nents, u32 max_sg_nents, - u32 *lbytes, u32 *mapped_nents) +static int cc_map_sg(struct device *dev, struct scatterlist *sg, + unsigned int nbytes, int direction, u32 *nents, + u32 max_sg_nents, u32 *lbytes, u32 *mapped_nents) { bool is_chained = false; if (sg_is_last(sg)) { /* One entry only case -set to DLLI */ - if (unlikely(dma_map_sg(dev, sg, 1, direction) != 1)) { + if (dma_map_sg(dev, sg, 1, direction) != 1) { dev_err(dev, "dma_map_sg() single buffer failed\n"); return -ENOMEM; } @@ -357,8 +358,8 @@ static int ssi_buffer_mgr_map_scatterlist( *nents = 1; *mapped_nents = 1; } else { /*sg_is_last*/ - *nents = ssi_buffer_mgr_get_sgl_nents(dev, sg, nbytes, lbytes, - &is_chained); + *nents = cc_get_sgl_nents(dev, sg, nbytes, lbytes, + &is_chained); if (*nents > max_sg_nents) { *nents = 0; dev_err(dev, "Too many fragments. current %d max %d\n", @@ -370,7 +371,7 @@ static int ssi_buffer_mgr_map_scatterlist( * be changed from the original sgl nents */ *mapped_nents = dma_map_sg(dev, sg, *nents, direction); - if (unlikely(*mapped_nents == 0)) { + if (*mapped_nents == 0) { *nents = 0; dev_err(dev, "dma_map_sg() sg buffer failed\n"); return -ENOMEM; @@ -379,11 +380,9 @@ static int ssi_buffer_mgr_map_scatterlist( /*In this case the driver maps entry by entry so it * must have the same nents before and after map */ - *mapped_nents = ssi_buffer_mgr_dma_map_sg(dev, - sg, - *nents, - direction); - if (unlikely(*mapped_nents != *nents)) { + *mapped_nents = cc_dma_map_sg(dev, sg, *nents, + direction); + if (*mapped_nents != *nents) { *nents = *mapped_nents; dev_err(dev, "dma_map_sg() sg buffer failed\n"); return -ENOMEM; @@ -394,18 +393,16 @@ static int ssi_buffer_mgr_map_scatterlist( return 0; } -static inline int -ssi_aead_handle_config_buf(struct device *dev, - struct aead_req_ctx *areq_ctx, - u8 *config_data, - struct buffer_array *sg_data, - unsigned int assoclen) +static int +cc_set_aead_conf_buf(struct device *dev, struct aead_req_ctx *areq_ctx, + u8 *config_data, struct buffer_array *sg_data, + unsigned int assoclen) { dev_dbg(dev, " handle additional data config set to DLLI\n"); /* create sg for the current buffer */ - sg_init_one(&areq_ctx->ccm_adata_sg, config_data, AES_BLOCK_SIZE + areq_ctx->ccm_hdr_size); - if (unlikely(dma_map_sg(dev, &areq_ctx->ccm_adata_sg, 1, - DMA_TO_DEVICE) != 1)) { + sg_init_one(&areq_ctx->ccm_adata_sg, config_data, + AES_BLOCK_SIZE + areq_ctx->ccm_hdr_size); + if (dma_map_sg(dev, &areq_ctx->ccm_adata_sg, 1, DMA_TO_DEVICE) != 1) { dev_err(dev, "dma_map_sg() config buffer failed\n"); return -ENOMEM; } @@ -416,25 +413,21 @@ ssi_aead_handle_config_buf(struct device *dev, areq_ctx->ccm_adata_sg.offset, areq_ctx->ccm_adata_sg.length); /* prepare for case of MLLI */ if (assoclen > 0) { - ssi_buffer_mgr_add_scatterlist_entry(dev, sg_data, 1, - &areq_ctx->ccm_adata_sg, - (AES_BLOCK_SIZE + areq_ctx->ccm_hdr_size), - 0, false, NULL); + cc_add_sg_entry(dev, sg_data, 1, &areq_ctx->ccm_adata_sg, + (AES_BLOCK_SIZE + areq_ctx->ccm_hdr_size), + 0, false, NULL); } return 0; } -static inline int ssi_ahash_handle_curr_buf(struct device *dev, - struct ahash_req_ctx *areq_ctx, - u8 *curr_buff, - u32 curr_buff_cnt, - struct buffer_array *sg_data) +static int cc_set_hash_buf(struct device *dev, struct ahash_req_ctx *areq_ctx, + u8 *curr_buff, u32 curr_buff_cnt, + struct buffer_array *sg_data) { dev_dbg(dev, " handle curr buff %x set to DLLI\n", curr_buff_cnt); /* create sg for the current buffer */ sg_init_one(areq_ctx->buff_sg, curr_buff, curr_buff_cnt); - if (unlikely(dma_map_sg(dev, areq_ctx->buff_sg, 1, - DMA_TO_DEVICE) != 1)) { + if (dma_map_sg(dev, areq_ctx->buff_sg, 1, DMA_TO_DEVICE) != 1) { dev_err(dev, "dma_map_sg() src buffer failed\n"); return -ENOMEM; } @@ -442,25 +435,22 @@ static inline int ssi_ahash_handle_curr_buf(struct device *dev, &sg_dma_address(areq_ctx->buff_sg), sg_page(areq_ctx->buff_sg), sg_virt(areq_ctx->buff_sg), areq_ctx->buff_sg->offset, areq_ctx->buff_sg->length); - areq_ctx->data_dma_buf_type = SSI_DMA_BUF_DLLI; + areq_ctx->data_dma_buf_type = CC_DMA_BUF_DLLI; areq_ctx->curr_sg = areq_ctx->buff_sg; areq_ctx->in_nents = 0; /* prepare for case of MLLI */ - ssi_buffer_mgr_add_scatterlist_entry(dev, sg_data, 1, areq_ctx->buff_sg, - curr_buff_cnt, 0, false, NULL); + cc_add_sg_entry(dev, sg_data, 1, areq_ctx->buff_sg, curr_buff_cnt, 0, + false, NULL); return 0; } -void ssi_buffer_mgr_unmap_blkcipher_request( - struct device *dev, - void *ctx, - unsigned int ivsize, - struct scatterlist *src, - struct scatterlist *dst) +void cc_unmap_blkcipher_request(struct device *dev, void *ctx, + unsigned int ivsize, struct scatterlist *src, + struct scatterlist *dst) { struct blkcipher_req_ctx *req_ctx = (struct blkcipher_req_ctx *)ctx; - if (likely(req_ctx->gen_ctx.iv_dma_addr != 0)) { + if (req_ctx->gen_ctx.iv_dma_addr) { dev_dbg(dev, "Unmapped iv: iv_dma_addr=%pad iv_size=%u\n", &req_ctx->gen_ctx.iv_dma_addr, ivsize); dma_unmap_single(dev, req_ctx->gen_ctx.iv_dma_addr, @@ -469,7 +459,8 @@ void ssi_buffer_mgr_unmap_blkcipher_request( DMA_TO_DEVICE); } /* Release pool */ - if (req_ctx->dma_buf_type == SSI_DMA_BUF_MLLI) { + if (req_ctx->dma_buf_type == CC_DMA_BUF_MLLI && + req_ctx->mlli_params.mlli_virt_addr) { dma_pool_free(req_ctx->mlli_params.curr_pool, req_ctx->mlli_params.mlli_virt_addr, req_ctx->mlli_params.mlli_dma_addr); @@ -484,14 +475,10 @@ void ssi_buffer_mgr_unmap_blkcipher_request( } } -int ssi_buffer_mgr_map_blkcipher_request( - struct ssi_drvdata *drvdata, - void *ctx, - unsigned int ivsize, - unsigned int nbytes, - void *info, - struct scatterlist *src, - struct scatterlist *dst) +int cc_map_blkcipher_request(struct cc_drvdata *drvdata, void *ctx, + unsigned int ivsize, unsigned int nbytes, + void *info, struct scatterlist *src, + struct scatterlist *dst, gfp_t flags) { struct blkcipher_req_ctx *req_ctx = (struct blkcipher_req_ctx *)ctx; struct mlli_params *mlli_params = &req_ctx->mlli_params; @@ -502,20 +489,19 @@ int ssi_buffer_mgr_map_blkcipher_request( int rc = 0; u32 mapped_nents = 0; - req_ctx->dma_buf_type = SSI_DMA_BUF_DLLI; + req_ctx->dma_buf_type = CC_DMA_BUF_DLLI; mlli_params->curr_pool = NULL; sg_data.num_of_buffers = 0; /* Map IV buffer */ - if (likely(ivsize != 0)) { + if (ivsize) { dump_byte_array("iv", (u8 *)info, ivsize); req_ctx->gen_ctx.iv_dma_addr = dma_map_single(dev, (void *)info, ivsize, req_ctx->is_giv ? DMA_BIDIRECTIONAL : DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(dev, - req_ctx->gen_ctx.iv_dma_addr))) { + if (dma_mapping_error(dev, req_ctx->gen_ctx.iv_dma_addr)) { dev_err(dev, "Mapping iv %u B at va=%pK for DMA failed\n", ivsize, info); return -ENOMEM; @@ -527,121 +513,107 @@ int ssi_buffer_mgr_map_blkcipher_request( } /* Map the src SGL */ - rc = ssi_buffer_mgr_map_scatterlist(dev, src, - nbytes, DMA_BIDIRECTIONAL, - &req_ctx->in_nents, - LLI_MAX_NUM_OF_DATA_ENTRIES, &dummy, - &mapped_nents); - if (unlikely(rc != 0)) { + rc = cc_map_sg(dev, src, nbytes, DMA_BIDIRECTIONAL, &req_ctx->in_nents, + LLI_MAX_NUM_OF_DATA_ENTRIES, &dummy, &mapped_nents); + if (rc) { rc = -ENOMEM; goto ablkcipher_exit; } if (mapped_nents > 1) - req_ctx->dma_buf_type = SSI_DMA_BUF_MLLI; + req_ctx->dma_buf_type = CC_DMA_BUF_MLLI; - if (unlikely(src == dst)) { + if (src == dst) { /* Handle inplace operation */ - if (unlikely(req_ctx->dma_buf_type == SSI_DMA_BUF_MLLI)) { + if (req_ctx->dma_buf_type == CC_DMA_BUF_MLLI) { req_ctx->out_nents = 0; - ssi_buffer_mgr_add_scatterlist_entry(dev, &sg_data, - req_ctx->in_nents, - src, nbytes, 0, - true, - &req_ctx->in_mlli_nents); + cc_add_sg_entry(dev, &sg_data, req_ctx->in_nents, src, + nbytes, 0, true, + &req_ctx->in_mlli_nents); } } else { /* Map the dst sg */ - if (unlikely(ssi_buffer_mgr_map_scatterlist( - dev, dst, nbytes, - DMA_BIDIRECTIONAL, &req_ctx->out_nents, - LLI_MAX_NUM_OF_DATA_ENTRIES, &dummy, - &mapped_nents))){ + if (cc_map_sg(dev, dst, nbytes, DMA_BIDIRECTIONAL, + &req_ctx->out_nents, LLI_MAX_NUM_OF_DATA_ENTRIES, + &dummy, &mapped_nents)) { rc = -ENOMEM; goto ablkcipher_exit; } if (mapped_nents > 1) - req_ctx->dma_buf_type = SSI_DMA_BUF_MLLI; - - if (unlikely((req_ctx->dma_buf_type == SSI_DMA_BUF_MLLI))) { - ssi_buffer_mgr_add_scatterlist_entry(dev, &sg_data, - req_ctx->in_nents, - src, nbytes, 0, - true, - &req_ctx->in_mlli_nents); - ssi_buffer_mgr_add_scatterlist_entry(dev, &sg_data, - req_ctx->out_nents, - dst, nbytes, 0, - true, - &req_ctx->out_mlli_nents); + req_ctx->dma_buf_type = CC_DMA_BUF_MLLI; + + if (req_ctx->dma_buf_type == CC_DMA_BUF_MLLI) { + cc_add_sg_entry(dev, &sg_data, req_ctx->in_nents, src, + nbytes, 0, true, + &req_ctx->in_mlli_nents); + cc_add_sg_entry(dev, &sg_data, req_ctx->out_nents, dst, + nbytes, 0, true, + &req_ctx->out_mlli_nents); } } - if (unlikely(req_ctx->dma_buf_type == SSI_DMA_BUF_MLLI)) { + if (req_ctx->dma_buf_type == CC_DMA_BUF_MLLI) { mlli_params->curr_pool = buff_mgr->mlli_buffs_pool; - rc = ssi_buffer_mgr_generate_mlli(dev, &sg_data, mlli_params); - if (unlikely(rc != 0)) + rc = cc_generate_mlli(dev, &sg_data, mlli_params, flags); + if (rc) goto ablkcipher_exit; } dev_dbg(dev, "areq_ctx->dma_buf_type = %s\n", - GET_DMA_BUFFER_TYPE(req_ctx->dma_buf_type)); + cc_dma_buf_type(req_ctx->dma_buf_type)); return 0; ablkcipher_exit: - ssi_buffer_mgr_unmap_blkcipher_request(dev, req_ctx, ivsize, src, dst); + cc_unmap_blkcipher_request(dev, req_ctx, ivsize, src, dst); return rc; } -void ssi_buffer_mgr_unmap_aead_request( - struct device *dev, struct aead_request *req) +void cc_unmap_aead_request(struct device *dev, struct aead_request *req) { struct aead_req_ctx *areq_ctx = aead_request_ctx(req); unsigned int hw_iv_size = areq_ctx->hw_iv_size; struct crypto_aead *tfm = crypto_aead_reqtfm(req); - struct ssi_drvdata *drvdata = dev_get_drvdata(dev); + struct cc_drvdata *drvdata = dev_get_drvdata(dev); u32 dummy; bool chained; u32 size_to_unmap = 0; - if (areq_ctx->mac_buf_dma_addr != 0) { + if (areq_ctx->mac_buf_dma_addr) { dma_unmap_single(dev, areq_ctx->mac_buf_dma_addr, MAX_MAC_SIZE, DMA_BIDIRECTIONAL); } -#if SSI_CC_HAS_AES_GCM if (areq_ctx->cipher_mode == DRV_CIPHER_GCTR) { - if (areq_ctx->hkey_dma_addr != 0) { + if (areq_ctx->hkey_dma_addr) { dma_unmap_single(dev, areq_ctx->hkey_dma_addr, AES_BLOCK_SIZE, DMA_BIDIRECTIONAL); } - if (areq_ctx->gcm_block_len_dma_addr != 0) { + if (areq_ctx->gcm_block_len_dma_addr) { dma_unmap_single(dev, areq_ctx->gcm_block_len_dma_addr, AES_BLOCK_SIZE, DMA_TO_DEVICE); } - if (areq_ctx->gcm_iv_inc1_dma_addr != 0) { + if (areq_ctx->gcm_iv_inc1_dma_addr) { dma_unmap_single(dev, areq_ctx->gcm_iv_inc1_dma_addr, AES_BLOCK_SIZE, DMA_TO_DEVICE); } - if (areq_ctx->gcm_iv_inc2_dma_addr != 0) { + if (areq_ctx->gcm_iv_inc2_dma_addr) { dma_unmap_single(dev, areq_ctx->gcm_iv_inc2_dma_addr, AES_BLOCK_SIZE, DMA_TO_DEVICE); } } -#endif if (areq_ctx->ccm_hdr_size != ccm_header_size_null) { - if (areq_ctx->ccm_iv0_dma_addr != 0) { + if (areq_ctx->ccm_iv0_dma_addr) { dma_unmap_single(dev, areq_ctx->ccm_iv0_dma_addr, AES_BLOCK_SIZE, DMA_TO_DEVICE); } dma_unmap_sg(dev, &areq_ctx->ccm_adata_sg, 1, DMA_TO_DEVICE); } - if (areq_ctx->gen_ctx.iv_dma_addr != 0) { + if (areq_ctx->gen_ctx.iv_dma_addr) { dma_unmap_single(dev, areq_ctx->gen_ctx.iv_dma_addr, hw_iv_size, DMA_BIDIRECTIONAL); } @@ -668,46 +640,37 @@ void ssi_buffer_mgr_unmap_aead_request( size_to_unmap += crypto_aead_ivsize(tfm); dma_unmap_sg(dev, req->src, - ssi_buffer_mgr_get_sgl_nents(dev, req->src, size_to_unmap, - &dummy, &chained), + cc_get_sgl_nents(dev, req->src, size_to_unmap, + &dummy, &chained), DMA_BIDIRECTIONAL); - if (unlikely(req->src != req->dst)) { + if (req->src != req->dst) { dev_dbg(dev, "Unmapping dst sgl: req->dst=%pK\n", sg_virt(req->dst)); dma_unmap_sg(dev, req->dst, - ssi_buffer_mgr_get_sgl_nents(dev, req->dst, - size_to_unmap, - &dummy, &chained), + cc_get_sgl_nents(dev, req->dst, size_to_unmap, + &dummy, &chained), DMA_BIDIRECTIONAL); } if (drvdata->coherent && - (areq_ctx->gen_ctx.op_type == DRV_CRYPTO_DIRECTION_DECRYPT) && - likely(req->src == req->dst)) { - u32 size_to_skip = req->assoclen; - - if (areq_ctx->is_gcm4543) - size_to_skip += crypto_aead_ivsize(tfm); - - /* copy mac to a temporary location to deal with possible - * data memory overriding that caused by cache coherence problem. + areq_ctx->gen_ctx.op_type == DRV_CRYPTO_DIRECTION_DECRYPT && + req->src == req->dst) { + /* copy back mac from temporary location to deal with possible + * data memory overriding that caused by cache coherence + * problem. */ - ssi_buffer_mgr_copy_scatterlist_portion( - dev, areq_ctx->backup_mac, req->src, - size_to_skip + req->cryptlen - areq_ctx->req_authsize, - size_to_skip + req->cryptlen, SSI_SG_FROM_BUF); + cc_copy_mac(dev, req, CC_SG_FROM_BUF); } } -static inline int ssi_buffer_mgr_get_aead_icv_nents( - struct device *dev, - struct scatterlist *sgl, - unsigned int sgl_nents, - unsigned int authsize, - u32 last_entry_data_size, - bool *is_icv_fragmented) +static int cc_get_aead_icv_nents(struct device *dev, struct scatterlist *sgl, + unsigned int sgl_nents, unsigned int authsize, + u32 last_entry_data_size, + bool *is_icv_fragmented) { unsigned int icv_max_size = 0; - unsigned int icv_required_size = authsize > last_entry_data_size ? (authsize - last_entry_data_size) : authsize; + unsigned int icv_required_size = authsize > last_entry_data_size ? + (authsize - last_entry_data_size) : + authsize; unsigned int nents; unsigned int i; @@ -726,10 +689,12 @@ static inline int ssi_buffer_mgr_get_aead_icv_nents( icv_max_size = sgl->length; if (last_entry_data_size > authsize) { - nents = 0; /* ICV attached to data in last entry (not fragmented!) */ + /* ICV attached to data in last entry (not fragmented!) */ + nents = 0; *is_icv_fragmented = false; } else if (last_entry_data_size == authsize) { - nents = 1; /* ICV placed in whole last entry (not fragmented!) */ + /* ICV placed in whole last entry (not fragmented!) */ + nents = 1; *is_icv_fragmented = false; } else if (icv_max_size > icv_required_size) { nents = 1; @@ -748,25 +713,25 @@ static inline int ssi_buffer_mgr_get_aead_icv_nents( return nents; } -static inline int ssi_buffer_mgr_aead_chain_iv( - struct ssi_drvdata *drvdata, - struct aead_request *req, - struct buffer_array *sg_data, - bool is_last, bool do_chain) +static int cc_aead_chain_iv(struct cc_drvdata *drvdata, + struct aead_request *req, + struct buffer_array *sg_data, + bool is_last, bool do_chain) { struct aead_req_ctx *areq_ctx = aead_request_ctx(req); unsigned int hw_iv_size = areq_ctx->hw_iv_size; struct device *dev = drvdata_to_dev(drvdata); int rc = 0; - if (unlikely(!req->iv)) { + if (!req->iv) { areq_ctx->gen_ctx.iv_dma_addr = 0; goto chain_iv_exit; } - areq_ctx->gen_ctx.iv_dma_addr = dma_map_single(dev, req->iv, hw_iv_size, + areq_ctx->gen_ctx.iv_dma_addr = dma_map_single(dev, req->iv, + hw_iv_size, DMA_BIDIRECTIONAL); - if (unlikely(dma_mapping_error(dev, areq_ctx->gen_ctx.iv_dma_addr))) { + if (dma_mapping_error(dev, areq_ctx->gen_ctx.iv_dma_addr)) { dev_err(dev, "Mapping iv %u B at va=%pK for DMA failed\n", hw_iv_size, req->iv); rc = -ENOMEM; @@ -775,28 +740,27 @@ static inline int ssi_buffer_mgr_aead_chain_iv( dev_dbg(dev, "Mapped iv %u B at va=%pK to dma=%pad\n", hw_iv_size, req->iv, &areq_ctx->gen_ctx.iv_dma_addr); - if (do_chain && areq_ctx->plaintext_authenticate_only) { // TODO: what about CTR?? ask Ron + // TODO: what about CTR?? ask Ron + if (do_chain && areq_ctx->plaintext_authenticate_only) { struct crypto_aead *tfm = crypto_aead_reqtfm(req); unsigned int iv_size_to_authenc = crypto_aead_ivsize(tfm); unsigned int iv_ofs = GCM_BLOCK_RFC4_IV_OFFSET; /* Chain to given list */ - ssi_buffer_mgr_add_buffer_entry( - dev, sg_data, - areq_ctx->gen_ctx.iv_dma_addr + iv_ofs, - iv_size_to_authenc, is_last, - &areq_ctx->assoc.mlli_nents); - areq_ctx->assoc_buff_type = SSI_DMA_BUF_MLLI; + cc_add_buffer_entry(dev, sg_data, + (areq_ctx->gen_ctx.iv_dma_addr + iv_ofs), + iv_size_to_authenc, is_last, + &areq_ctx->assoc.mlli_nents); + areq_ctx->assoc_buff_type = CC_DMA_BUF_MLLI; } chain_iv_exit: return rc; } -static inline int ssi_buffer_mgr_aead_chain_assoc( - struct ssi_drvdata *drvdata, - struct aead_request *req, - struct buffer_array *sg_data, - bool is_last, bool do_chain) +static int cc_aead_chain_assoc(struct cc_drvdata *drvdata, + struct aead_request *req, + struct buffer_array *sg_data, + bool is_last, bool do_chain) { struct aead_req_ctx *areq_ctx = aead_request_ctx(req); int rc = 0; @@ -815,12 +779,12 @@ static inline int ssi_buffer_mgr_aead_chain_assoc( goto chain_assoc_exit; } - if (unlikely(req->assoclen == 0)) { - areq_ctx->assoc_buff_type = SSI_DMA_BUF_NULL; + if (req->assoclen == 0) { + areq_ctx->assoc_buff_type = CC_DMA_BUF_NULL; areq_ctx->assoc.nents = 0; areq_ctx->assoc.mlli_nents = 0; dev_dbg(dev, "Chain assoc of length 0: buff_type=%s nents=%u\n", - GET_DMA_BUFFER_TYPE(areq_ctx->assoc_buff_type), + cc_dma_buf_type(areq_ctx->assoc_buff_type), areq_ctx->assoc.nents); goto chain_assoc_exit; } @@ -828,12 +792,15 @@ static inline int ssi_buffer_mgr_aead_chain_assoc( //iterate over the sgl to see how many entries are for associated data //it is assumed that if we reach here , the sgl is already mapped sg_index = current_sg->length; - if (sg_index > size_of_assoc) { //the first entry in the scatter list contains all the associated data + //the first entry in the scatter list contains all the associated data + if (sg_index > size_of_assoc) { mapped_nents++; } else { while (sg_index <= size_of_assoc) { current_sg = sg_next(current_sg); - //if have reached the end of the sgl, then this is unexpected + /* if have reached the end of the sgl, then this is + * unexpected + */ if (!current_sg) { dev_err(dev, "reached end of sg list. unexpected\n"); return -EINVAL; @@ -842,7 +809,7 @@ static inline int ssi_buffer_mgr_aead_chain_assoc( mapped_nents++; } } - if (unlikely(mapped_nents > LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES)) { + if (mapped_nents > LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES) { dev_err(dev, "Too many fragments. current %d max %d\n", mapped_nents, LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES); return -ENOMEM; @@ -853,8 +820,7 @@ static inline int ssi_buffer_mgr_aead_chain_assoc( * ccm header configurations */ if (areq_ctx->ccm_hdr_size != ccm_header_size_null) { - if (unlikely((mapped_nents + 1) > - LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES)) { + if ((mapped_nents + 1) > LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES) { dev_err(dev, "CCM case.Too many fragments. Current %d max %d\n", (areq_ctx->assoc.nents + 1), LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES); @@ -863,227 +829,175 @@ static inline int ssi_buffer_mgr_aead_chain_assoc( } } - if (likely(mapped_nents == 1) && - (areq_ctx->ccm_hdr_size == ccm_header_size_null)) - areq_ctx->assoc_buff_type = SSI_DMA_BUF_DLLI; + if (mapped_nents == 1 && areq_ctx->ccm_hdr_size == ccm_header_size_null) + areq_ctx->assoc_buff_type = CC_DMA_BUF_DLLI; else - areq_ctx->assoc_buff_type = SSI_DMA_BUF_MLLI; + areq_ctx->assoc_buff_type = CC_DMA_BUF_MLLI; - if (unlikely((do_chain) || - (areq_ctx->assoc_buff_type == SSI_DMA_BUF_MLLI))) { + if (do_chain || areq_ctx->assoc_buff_type == CC_DMA_BUF_MLLI) { dev_dbg(dev, "Chain assoc: buff_type=%s nents=%u\n", - GET_DMA_BUFFER_TYPE(areq_ctx->assoc_buff_type), + cc_dma_buf_type(areq_ctx->assoc_buff_type), areq_ctx->assoc.nents); - ssi_buffer_mgr_add_scatterlist_entry( - dev, sg_data, areq_ctx->assoc.nents, - req->src, req->assoclen, 0, is_last, - &areq_ctx->assoc.mlli_nents); - areq_ctx->assoc_buff_type = SSI_DMA_BUF_MLLI; + cc_add_sg_entry(dev, sg_data, areq_ctx->assoc.nents, req->src, + req->assoclen, 0, is_last, + &areq_ctx->assoc.mlli_nents); + areq_ctx->assoc_buff_type = CC_DMA_BUF_MLLI; } chain_assoc_exit: return rc; } -static inline void ssi_buffer_mgr_prepare_aead_data_dlli( - struct aead_request *req, - u32 *src_last_bytes, u32 *dst_last_bytes) +static void cc_prepare_aead_data_dlli(struct aead_request *req, + u32 *src_last_bytes, u32 *dst_last_bytes) { struct aead_req_ctx *areq_ctx = aead_request_ctx(req); enum drv_crypto_direction direct = areq_ctx->gen_ctx.op_type; unsigned int authsize = areq_ctx->req_authsize; areq_ctx->is_icv_fragmented = false; - if (likely(req->src == req->dst)) { + if (req->src == req->dst) { /*INPLACE*/ - areq_ctx->icv_dma_addr = sg_dma_address( - areq_ctx->src_sgl) + + areq_ctx->icv_dma_addr = sg_dma_address(areq_ctx->src_sgl) + (*src_last_bytes - authsize); - areq_ctx->icv_virt_addr = sg_virt( - areq_ctx->src_sgl) + + areq_ctx->icv_virt_addr = sg_virt(areq_ctx->src_sgl) + (*src_last_bytes - authsize); } else if (direct == DRV_CRYPTO_DIRECTION_DECRYPT) { /*NON-INPLACE and DECRYPT*/ - areq_ctx->icv_dma_addr = sg_dma_address( - areq_ctx->src_sgl) + + areq_ctx->icv_dma_addr = sg_dma_address(areq_ctx->src_sgl) + (*src_last_bytes - authsize); - areq_ctx->icv_virt_addr = sg_virt( - areq_ctx->src_sgl) + + areq_ctx->icv_virt_addr = sg_virt(areq_ctx->src_sgl) + (*src_last_bytes - authsize); } else { /*NON-INPLACE and ENCRYPT*/ - areq_ctx->icv_dma_addr = sg_dma_address( - areq_ctx->dst_sgl) + + areq_ctx->icv_dma_addr = sg_dma_address(areq_ctx->dst_sgl) + (*dst_last_bytes - authsize); - areq_ctx->icv_virt_addr = sg_virt( - areq_ctx->dst_sgl) + + areq_ctx->icv_virt_addr = sg_virt(areq_ctx->dst_sgl) + (*dst_last_bytes - authsize); } } -static inline int ssi_buffer_mgr_prepare_aead_data_mlli( - struct ssi_drvdata *drvdata, - struct aead_request *req, - struct buffer_array *sg_data, - u32 *src_last_bytes, u32 *dst_last_bytes, - bool is_last_table) +static int cc_prepare_aead_data_mlli(struct cc_drvdata *drvdata, + struct aead_request *req, + struct buffer_array *sg_data, + u32 *src_last_bytes, u32 *dst_last_bytes, + bool is_last_table) { struct aead_req_ctx *areq_ctx = aead_request_ctx(req); enum drv_crypto_direction direct = areq_ctx->gen_ctx.op_type; unsigned int authsize = areq_ctx->req_authsize; int rc = 0, icv_nents; - struct crypto_aead *tfm = crypto_aead_reqtfm(req); struct device *dev = drvdata_to_dev(drvdata); + struct scatterlist *sg; - if (likely(req->src == req->dst)) { + if (req->src == req->dst) { /*INPLACE*/ - ssi_buffer_mgr_add_scatterlist_entry(dev, sg_data, - areq_ctx->src.nents, - areq_ctx->src_sgl, - areq_ctx->cryptlen, - areq_ctx->src_offset, - is_last_table, - &areq_ctx->src.mlli_nents); - - icv_nents = ssi_buffer_mgr_get_aead_icv_nents(dev, - areq_ctx->src_sgl, - areq_ctx->src.nents, - authsize, - *src_last_bytes, - &areq_ctx->is_icv_fragmented); - if (unlikely(icv_nents < 0)) { + cc_add_sg_entry(dev, sg_data, areq_ctx->src.nents, + areq_ctx->src_sgl, areq_ctx->cryptlen, + areq_ctx->src_offset, is_last_table, + &areq_ctx->src.mlli_nents); + + icv_nents = cc_get_aead_icv_nents(dev, areq_ctx->src_sgl, + areq_ctx->src.nents, + authsize, *src_last_bytes, + &areq_ctx->is_icv_fragmented); + if (icv_nents < 0) { rc = -ENOTSUPP; goto prepare_data_mlli_exit; } - if (unlikely(areq_ctx->is_icv_fragmented)) { + if (areq_ctx->is_icv_fragmented) { /* Backup happens only when ICV is fragmented, ICV - * verification is made by CPU compare in order to simplify - * MAC verification upon request completion + * verification is made by CPU compare in order to + * simplify MAC verification upon request completion */ if (direct == DRV_CRYPTO_DIRECTION_DECRYPT) { - if (!drvdata->coherent) { /* In coherent platforms (e.g. ACP) * already copying ICV for any * INPLACE-DECRYPT operation, hence * we must neglect this code. */ - u32 skip = req->assoclen; - - if (areq_ctx->is_gcm4543) - skip += crypto_aead_ivsize(tfm); - - ssi_buffer_mgr_copy_scatterlist_portion( - dev, areq_ctx->backup_mac, - req->src, - (skip + req->cryptlen - - areq_ctx->req_authsize), - skip + req->cryptlen, - SSI_SG_TO_BUF); - } + if (!drvdata->coherent) + cc_copy_mac(dev, req, CC_SG_TO_BUF); + areq_ctx->icv_virt_addr = areq_ctx->backup_mac; } else { areq_ctx->icv_virt_addr = areq_ctx->mac_buf; - areq_ctx->icv_dma_addr = areq_ctx->mac_buf_dma_addr; + areq_ctx->icv_dma_addr = + areq_ctx->mac_buf_dma_addr; } } else { /* Contig. ICV */ + sg = &areq_ctx->src_sgl[areq_ctx->src.nents - 1]; /*Should hanlde if the sg is not contig.*/ - areq_ctx->icv_dma_addr = sg_dma_address( - &areq_ctx->src_sgl[areq_ctx->src.nents - 1]) + + areq_ctx->icv_dma_addr = sg_dma_address(sg) + (*src_last_bytes - authsize); - areq_ctx->icv_virt_addr = sg_virt( - &areq_ctx->src_sgl[areq_ctx->src.nents - 1]) + + areq_ctx->icv_virt_addr = sg_virt(sg) + (*src_last_bytes - authsize); } } else if (direct == DRV_CRYPTO_DIRECTION_DECRYPT) { /*NON-INPLACE and DECRYPT*/ - ssi_buffer_mgr_add_scatterlist_entry(dev, sg_data, - areq_ctx->src.nents, - areq_ctx->src_sgl, - areq_ctx->cryptlen, - areq_ctx->src_offset, - is_last_table, - &areq_ctx->src.mlli_nents); - ssi_buffer_mgr_add_scatterlist_entry(dev, sg_data, - areq_ctx->dst.nents, - areq_ctx->dst_sgl, - areq_ctx->cryptlen, - areq_ctx->dst_offset, - is_last_table, - &areq_ctx->dst.mlli_nents); - - icv_nents = ssi_buffer_mgr_get_aead_icv_nents(dev, - areq_ctx->src_sgl, - areq_ctx->src.nents, - authsize, - *src_last_bytes, - &areq_ctx->is_icv_fragmented); - if (unlikely(icv_nents < 0)) { + cc_add_sg_entry(dev, sg_data, areq_ctx->src.nents, + areq_ctx->src_sgl, areq_ctx->cryptlen, + areq_ctx->src_offset, is_last_table, + &areq_ctx->src.mlli_nents); + cc_add_sg_entry(dev, sg_data, areq_ctx->dst.nents, + areq_ctx->dst_sgl, areq_ctx->cryptlen, + areq_ctx->dst_offset, is_last_table, + &areq_ctx->dst.mlli_nents); + + icv_nents = cc_get_aead_icv_nents(dev, areq_ctx->src_sgl, + areq_ctx->src.nents, + authsize, *src_last_bytes, + &areq_ctx->is_icv_fragmented); + if (icv_nents < 0) { rc = -ENOTSUPP; goto prepare_data_mlli_exit; } - if (unlikely(areq_ctx->is_icv_fragmented)) { - /* Backup happens only when ICV is fragmented, ICV - * verification is made by CPU compare in order to simplify - * MAC verification upon request completion - */ - u32 size_to_skip = req->assoclen; - - if (areq_ctx->is_gcm4543) - size_to_skip += crypto_aead_ivsize(tfm); - - ssi_buffer_mgr_copy_scatterlist_portion( - dev, areq_ctx->backup_mac, req->src, - size_to_skip + req->cryptlen - areq_ctx->req_authsize, - size_to_skip + req->cryptlen, SSI_SG_TO_BUF); + /* Backup happens only when ICV is fragmented, ICV + * verification is made by CPU compare in order to simplify + * MAC verification upon request completion + */ + if (areq_ctx->is_icv_fragmented) { + cc_copy_mac(dev, req, CC_SG_TO_BUF); areq_ctx->icv_virt_addr = areq_ctx->backup_mac; + } else { /* Contig. ICV */ + sg = &areq_ctx->src_sgl[areq_ctx->src.nents - 1]; /*Should hanlde if the sg is not contig.*/ - areq_ctx->icv_dma_addr = sg_dma_address( - &areq_ctx->src_sgl[areq_ctx->src.nents - 1]) + + areq_ctx->icv_dma_addr = sg_dma_address(sg) + (*src_last_bytes - authsize); - areq_ctx->icv_virt_addr = sg_virt( - &areq_ctx->src_sgl[areq_ctx->src.nents - 1]) + + areq_ctx->icv_virt_addr = sg_virt(sg) + (*src_last_bytes - authsize); } } else { /*NON-INPLACE and ENCRYPT*/ - ssi_buffer_mgr_add_scatterlist_entry(dev, sg_data, - areq_ctx->dst.nents, - areq_ctx->dst_sgl, - areq_ctx->cryptlen, - areq_ctx->dst_offset, - is_last_table, - &areq_ctx->dst.mlli_nents); - ssi_buffer_mgr_add_scatterlist_entry(dev, sg_data, - areq_ctx->src.nents, - areq_ctx->src_sgl, - areq_ctx->cryptlen, - areq_ctx->src_offset, - is_last_table, - &areq_ctx->src.mlli_nents); - - icv_nents = ssi_buffer_mgr_get_aead_icv_nents(dev, - areq_ctx->dst_sgl, - areq_ctx->dst.nents, - authsize, - *dst_last_bytes, - &areq_ctx->is_icv_fragmented); - if (unlikely(icv_nents < 0)) { + cc_add_sg_entry(dev, sg_data, areq_ctx->dst.nents, + areq_ctx->dst_sgl, areq_ctx->cryptlen, + areq_ctx->dst_offset, is_last_table, + &areq_ctx->dst.mlli_nents); + cc_add_sg_entry(dev, sg_data, areq_ctx->src.nents, + areq_ctx->src_sgl, areq_ctx->cryptlen, + areq_ctx->src_offset, is_last_table, + &areq_ctx->src.mlli_nents); + + icv_nents = cc_get_aead_icv_nents(dev, areq_ctx->dst_sgl, + areq_ctx->dst.nents, + authsize, *dst_last_bytes, + &areq_ctx->is_icv_fragmented); + if (icv_nents < 0) { rc = -ENOTSUPP; goto prepare_data_mlli_exit; } - if (likely(!areq_ctx->is_icv_fragmented)) { + if (!areq_ctx->is_icv_fragmented) { + sg = &areq_ctx->dst_sgl[areq_ctx->dst.nents - 1]; /* Contig. ICV */ - areq_ctx->icv_dma_addr = sg_dma_address( - &areq_ctx->dst_sgl[areq_ctx->dst.nents - 1]) + + areq_ctx->icv_dma_addr = sg_dma_address(sg) + (*dst_last_bytes - authsize); - areq_ctx->icv_virt_addr = sg_virt( - &areq_ctx->dst_sgl[areq_ctx->dst.nents - 1]) + + areq_ctx->icv_virt_addr = sg_virt(sg) + (*dst_last_bytes - authsize); } else { areq_ctx->icv_dma_addr = areq_ctx->mac_buf_dma_addr; @@ -1095,11 +1009,10 @@ prepare_data_mlli_exit: return rc; } -static inline int ssi_buffer_mgr_aead_chain_data( - struct ssi_drvdata *drvdata, - struct aead_request *req, - struct buffer_array *sg_data, - bool is_last_table, bool do_chain) +static int cc_aead_chain_data(struct cc_drvdata *drvdata, + struct aead_request *req, + struct buffer_array *sg_data, + bool is_last_table, bool do_chain) { struct aead_req_ctx *areq_ctx = aead_request_ctx(req); struct device *dev = drvdata_to_dev(drvdata); @@ -1109,7 +1022,8 @@ static inline int ssi_buffer_mgr_aead_chain_data( int rc = 0; u32 src_mapped_nents = 0, dst_mapped_nents = 0; u32 offset = 0; - unsigned int size_for_map = req->assoclen + req->cryptlen; /*non-inplace mode*/ + /* non-inplace mode */ + unsigned int size_for_map = req->assoclen + req->cryptlen; struct crypto_aead *tfm = crypto_aead_reqtfm(req); u32 sg_index = 0; bool chained = false; @@ -1130,11 +1044,10 @@ static inline int ssi_buffer_mgr_aead_chain_data( if (is_gcm4543) size_for_map += crypto_aead_ivsize(tfm); - size_for_map += (direct == DRV_CRYPTO_DIRECTION_ENCRYPT) ? authsize : 0; - src_mapped_nents = ssi_buffer_mgr_get_sgl_nents(dev, req->src, - size_for_map, - &src_last_bytes, - &chained); + size_for_map += (direct == DRV_CRYPTO_DIRECTION_ENCRYPT) ? + authsize : 0; + src_mapped_nents = cc_get_sgl_nents(dev, req->src, size_for_map, + &src_last_bytes, &chained); sg_index = areq_ctx->src_sgl->length; //check where the data starts while (sg_index <= size_to_skip) { @@ -1148,7 +1061,7 @@ static inline int ssi_buffer_mgr_aead_chain_data( sg_index += areq_ctx->src_sgl->length; src_mapped_nents--; } - if (unlikely(src_mapped_nents > LLI_MAX_NUM_OF_DATA_ENTRIES)) { + if (src_mapped_nents > LLI_MAX_NUM_OF_DATA_ENTRIES) { dev_err(dev, "Too many fragments. current %d max %d\n", src_mapped_nents, LLI_MAX_NUM_OF_DATA_ENTRIES); return -ENOMEM; @@ -1160,26 +1073,23 @@ static inline int ssi_buffer_mgr_aead_chain_data( if (req->src != req->dst) { size_for_map = req->assoclen + req->cryptlen; - size_for_map += (direct == DRV_CRYPTO_DIRECTION_ENCRYPT) ? authsize : 0; + size_for_map += (direct == DRV_CRYPTO_DIRECTION_ENCRYPT) ? + authsize : 0; if (is_gcm4543) size_for_map += crypto_aead_ivsize(tfm); - rc = ssi_buffer_mgr_map_scatterlist(dev, req->dst, size_for_map, - DMA_BIDIRECTIONAL, - &areq_ctx->dst.nents, - LLI_MAX_NUM_OF_DATA_ENTRIES, - &dst_last_bytes, - &dst_mapped_nents); - if (unlikely(rc != 0)) { + rc = cc_map_sg(dev, req->dst, size_for_map, DMA_BIDIRECTIONAL, + &areq_ctx->dst.nents, + LLI_MAX_NUM_OF_DATA_ENTRIES, &dst_last_bytes, + &dst_mapped_nents); + if (rc) { rc = -ENOMEM; goto chain_data_exit; } } - dst_mapped_nents = ssi_buffer_mgr_get_sgl_nents(dev, req->dst, - size_for_map, - &dst_last_bytes, - &chained); + dst_mapped_nents = cc_get_sgl_nents(dev, req->dst, size_for_map, + &dst_last_bytes, &chained); sg_index = areq_ctx->dst_sgl->length; offset = size_to_skip; @@ -1195,45 +1105,43 @@ static inline int ssi_buffer_mgr_aead_chain_data( sg_index += areq_ctx->dst_sgl->length; dst_mapped_nents--; } - if (unlikely(dst_mapped_nents > LLI_MAX_NUM_OF_DATA_ENTRIES)) { + if (dst_mapped_nents > LLI_MAX_NUM_OF_DATA_ENTRIES) { dev_err(dev, "Too many fragments. current %d max %d\n", dst_mapped_nents, LLI_MAX_NUM_OF_DATA_ENTRIES); return -ENOMEM; } areq_ctx->dst.nents = dst_mapped_nents; areq_ctx->dst_offset = offset; - if ((src_mapped_nents > 1) || - (dst_mapped_nents > 1) || + if (src_mapped_nents > 1 || + dst_mapped_nents > 1 || do_chain) { - areq_ctx->data_buff_type = SSI_DMA_BUF_MLLI; - rc = ssi_buffer_mgr_prepare_aead_data_mlli(drvdata, req, - sg_data, - &src_last_bytes, - &dst_last_bytes, - is_last_table); + areq_ctx->data_buff_type = CC_DMA_BUF_MLLI; + rc = cc_prepare_aead_data_mlli(drvdata, req, sg_data, + &src_last_bytes, + &dst_last_bytes, is_last_table); } else { - areq_ctx->data_buff_type = SSI_DMA_BUF_DLLI; - ssi_buffer_mgr_prepare_aead_data_dlli( - req, &src_last_bytes, &dst_last_bytes); + areq_ctx->data_buff_type = CC_DMA_BUF_DLLI; + cc_prepare_aead_data_dlli(req, &src_last_bytes, + &dst_last_bytes); } chain_data_exit: return rc; } -static void ssi_buffer_mgr_update_aead_mlli_nents(struct ssi_drvdata *drvdata, - struct aead_request *req) +static void cc_update_aead_mlli_nents(struct cc_drvdata *drvdata, + struct aead_request *req) { struct aead_req_ctx *areq_ctx = aead_request_ctx(req); u32 curr_mlli_size = 0; - if (areq_ctx->assoc_buff_type == SSI_DMA_BUF_MLLI) { + if (areq_ctx->assoc_buff_type == CC_DMA_BUF_MLLI) { areq_ctx->assoc.sram_addr = drvdata->mlli_sram_addr; curr_mlli_size = areq_ctx->assoc.mlli_nents * LLI_ENTRY_BYTE_SIZE; } - if (areq_ctx->data_buff_type == SSI_DMA_BUF_MLLI) { + if (areq_ctx->data_buff_type == CC_DMA_BUF_MLLI) { /*Inplace case dst nents equal to src nents*/ if (req->src == req->dst) { areq_ctx->dst.mlli_nents = areq_ctx->src.mlli_nents; @@ -1272,8 +1180,7 @@ static void ssi_buffer_mgr_update_aead_mlli_nents(struct ssi_drvdata *drvdata, } } -int ssi_buffer_mgr_map_aead_request( - struct ssi_drvdata *drvdata, struct aead_request *req) +int cc_map_aead_request(struct cc_drvdata *drvdata, struct aead_request *req) { struct aead_req_ctx *areq_ctx = aead_request_ctx(req); struct mlli_params *mlli_params = &areq_ctx->mlli_params; @@ -1284,30 +1191,22 @@ int ssi_buffer_mgr_map_aead_request( int rc = 0; struct crypto_aead *tfm = crypto_aead_reqtfm(req); bool is_gcm4543 = areq_ctx->is_gcm4543; - + dma_addr_t dma_addr; u32 mapped_nents = 0; u32 dummy = 0; /*used for the assoc data fragments */ u32 size_to_map = 0; + gfp_t flags = cc_gfp_flags(&req->base); mlli_params->curr_pool = NULL; sg_data.num_of_buffers = 0; + /* copy mac to a temporary location to deal with possible + * data memory overriding that caused by cache coherence problem. + */ if (drvdata->coherent && - (areq_ctx->gen_ctx.op_type == DRV_CRYPTO_DIRECTION_DECRYPT) && - likely(req->src == req->dst)) { - u32 size_to_skip = req->assoclen; - - if (is_gcm4543) - size_to_skip += crypto_aead_ivsize(tfm); - - /* copy mac to a temporary location to deal with possible - * data memory overriding that caused by cache coherence problem. - */ - ssi_buffer_mgr_copy_scatterlist_portion( - dev, areq_ctx->backup_mac, req->src, - size_to_skip + req->cryptlen - areq_ctx->req_authsize, - size_to_skip + req->cryptlen, SSI_SG_TO_BUF); - } + areq_ctx->gen_ctx.op_type == DRV_CRYPTO_DIRECTION_DECRYPT && + req->src == req->dst) + cc_copy_mac(dev, req, CC_SG_TO_BUF); /* cacluate the size for cipher remove ICV in decrypt*/ areq_ctx->cryptlen = (areq_ctx->gen_ctx.op_type == @@ -1315,90 +1214,83 @@ int ssi_buffer_mgr_map_aead_request( req->cryptlen : (req->cryptlen - authsize); - areq_ctx->mac_buf_dma_addr = dma_map_single(dev, areq_ctx->mac_buf, - MAX_MAC_SIZE, - DMA_BIDIRECTIONAL); - if (unlikely(dma_mapping_error(dev, areq_ctx->mac_buf_dma_addr))) { + dma_addr = dma_map_single(dev, areq_ctx->mac_buf, MAX_MAC_SIZE, + DMA_BIDIRECTIONAL); + if (dma_mapping_error(dev, dma_addr)) { dev_err(dev, "Mapping mac_buf %u B at va=%pK for DMA failed\n", MAX_MAC_SIZE, areq_ctx->mac_buf); rc = -ENOMEM; goto aead_map_failure; } + areq_ctx->mac_buf_dma_addr = dma_addr; if (areq_ctx->ccm_hdr_size != ccm_header_size_null) { - areq_ctx->ccm_iv0_dma_addr = dma_map_single(dev, - (areq_ctx->ccm_config + CCM_CTR_COUNT_0_OFFSET), - AES_BLOCK_SIZE, - DMA_TO_DEVICE); + void *addr = areq_ctx->ccm_config + CCM_CTR_COUNT_0_OFFSET; - if (unlikely(dma_mapping_error(dev, areq_ctx->ccm_iv0_dma_addr))) { + dma_addr = dma_map_single(dev, addr, AES_BLOCK_SIZE, + DMA_TO_DEVICE); + + if (dma_mapping_error(dev, dma_addr)) { dev_err(dev, "Mapping mac_buf %u B at va=%pK for DMA failed\n", - AES_BLOCK_SIZE, - (areq_ctx->ccm_config + - CCM_CTR_COUNT_0_OFFSET)); + AES_BLOCK_SIZE, addr); areq_ctx->ccm_iv0_dma_addr = 0; rc = -ENOMEM; goto aead_map_failure; } - if (ssi_aead_handle_config_buf(dev, areq_ctx, - areq_ctx->ccm_config, &sg_data, - req->assoclen) != 0) { + areq_ctx->ccm_iv0_dma_addr = dma_addr; + + if (cc_set_aead_conf_buf(dev, areq_ctx, areq_ctx->ccm_config, + &sg_data, req->assoclen)) { rc = -ENOMEM; goto aead_map_failure; } } -#if SSI_CC_HAS_AES_GCM if (areq_ctx->cipher_mode == DRV_CIPHER_GCTR) { - areq_ctx->hkey_dma_addr = dma_map_single(dev, - areq_ctx->hkey, - AES_BLOCK_SIZE, - DMA_BIDIRECTIONAL); - if (unlikely(dma_mapping_error(dev, areq_ctx->hkey_dma_addr))) { + dma_addr = dma_map_single(dev, areq_ctx->hkey, AES_BLOCK_SIZE, + DMA_BIDIRECTIONAL); + if (dma_mapping_error(dev, dma_addr)) { dev_err(dev, "Mapping hkey %u B at va=%pK for DMA failed\n", AES_BLOCK_SIZE, areq_ctx->hkey); rc = -ENOMEM; goto aead_map_failure; } + areq_ctx->hkey_dma_addr = dma_addr; - areq_ctx->gcm_block_len_dma_addr = dma_map_single(dev, - &areq_ctx->gcm_len_block, - AES_BLOCK_SIZE, - DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(dev, areq_ctx->gcm_block_len_dma_addr))) { + dma_addr = dma_map_single(dev, &areq_ctx->gcm_len_block, + AES_BLOCK_SIZE, DMA_TO_DEVICE); + if (dma_mapping_error(dev, dma_addr)) { dev_err(dev, "Mapping gcm_len_block %u B at va=%pK for DMA failed\n", AES_BLOCK_SIZE, &areq_ctx->gcm_len_block); rc = -ENOMEM; goto aead_map_failure; } + areq_ctx->gcm_block_len_dma_addr = dma_addr; - areq_ctx->gcm_iv_inc1_dma_addr = dma_map_single(dev, - areq_ctx->gcm_iv_inc1, - AES_BLOCK_SIZE, - DMA_TO_DEVICE); + dma_addr = dma_map_single(dev, areq_ctx->gcm_iv_inc1, + AES_BLOCK_SIZE, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(dev, areq_ctx->gcm_iv_inc1_dma_addr))) { + if (dma_mapping_error(dev, dma_addr)) { dev_err(dev, "Mapping gcm_iv_inc1 %u B at va=%pK for DMA failed\n", AES_BLOCK_SIZE, (areq_ctx->gcm_iv_inc1)); areq_ctx->gcm_iv_inc1_dma_addr = 0; rc = -ENOMEM; goto aead_map_failure; } + areq_ctx->gcm_iv_inc1_dma_addr = dma_addr; - areq_ctx->gcm_iv_inc2_dma_addr = dma_map_single(dev, - areq_ctx->gcm_iv_inc2, - AES_BLOCK_SIZE, - DMA_TO_DEVICE); + dma_addr = dma_map_single(dev, areq_ctx->gcm_iv_inc2, + AES_BLOCK_SIZE, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(dev, areq_ctx->gcm_iv_inc2_dma_addr))) { + if (dma_mapping_error(dev, dma_addr)) { dev_err(dev, "Mapping gcm_iv_inc2 %u B at va=%pK for DMA failed\n", AES_BLOCK_SIZE, (areq_ctx->gcm_iv_inc2)); areq_ctx->gcm_iv_inc2_dma_addr = 0; rc = -ENOMEM; goto aead_map_failure; } + areq_ctx->gcm_iv_inc2_dma_addr = dma_addr; } -#endif /*SSI_CC_HAS_AES_GCM*/ size_to_map = req->cryptlen + req->assoclen; if (areq_ctx->gen_ctx.op_type == DRV_CRYPTO_DIRECTION_ENCRYPT) @@ -1406,29 +1298,31 @@ int ssi_buffer_mgr_map_aead_request( if (is_gcm4543) size_to_map += crypto_aead_ivsize(tfm); - rc = ssi_buffer_mgr_map_scatterlist(dev, req->src, - size_to_map, DMA_BIDIRECTIONAL, &areq_ctx->src.nents, - LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES + LLI_MAX_NUM_OF_DATA_ENTRIES, &dummy, &mapped_nents); - if (unlikely(rc != 0)) { + rc = cc_map_sg(dev, req->src, size_to_map, DMA_BIDIRECTIONAL, + &areq_ctx->src.nents, + (LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES + + LLI_MAX_NUM_OF_DATA_ENTRIES), + &dummy, &mapped_nents); + if (rc) { rc = -ENOMEM; goto aead_map_failure; } - if (likely(areq_ctx->is_single_pass)) { + if (areq_ctx->is_single_pass) { /* * Create MLLI table for: * (1) Assoc. data * (2) Src/Dst SGLs * Note: IV is contg. buffer (not an SGL) */ - rc = ssi_buffer_mgr_aead_chain_assoc(drvdata, req, &sg_data, true, false); - if (unlikely(rc != 0)) + rc = cc_aead_chain_assoc(drvdata, req, &sg_data, true, false); + if (rc) goto aead_map_failure; - rc = ssi_buffer_mgr_aead_chain_iv(drvdata, req, &sg_data, true, false); - if (unlikely(rc != 0)) + rc = cc_aead_chain_iv(drvdata, req, &sg_data, true, false); + if (rc) goto aead_map_failure; - rc = ssi_buffer_mgr_aead_chain_data(drvdata, req, &sg_data, true, false); - if (unlikely(rc != 0)) + rc = cc_aead_chain_data(drvdata, req, &sg_data, true, false); + if (rc) goto aead_map_failure; } else { /* DOUBLE-PASS flow */ /* @@ -1451,27 +1345,28 @@ int ssi_buffer_mgr_map_aead_request( * (3) MLLI for src * (4) MLLI for dst */ - rc = ssi_buffer_mgr_aead_chain_assoc(drvdata, req, &sg_data, false, true); - if (unlikely(rc != 0)) + rc = cc_aead_chain_assoc(drvdata, req, &sg_data, false, true); + if (rc) goto aead_map_failure; - rc = ssi_buffer_mgr_aead_chain_iv(drvdata, req, &sg_data, false, true); - if (unlikely(rc != 0)) + rc = cc_aead_chain_iv(drvdata, req, &sg_data, false, true); + if (rc) goto aead_map_failure; - rc = ssi_buffer_mgr_aead_chain_data(drvdata, req, &sg_data, true, true); - if (unlikely(rc != 0)) + rc = cc_aead_chain_data(drvdata, req, &sg_data, true, true); + if (rc) goto aead_map_failure; } - /* Mlli support -start building the MLLI according to the above results */ - if (unlikely( - (areq_ctx->assoc_buff_type == SSI_DMA_BUF_MLLI) || - (areq_ctx->data_buff_type == SSI_DMA_BUF_MLLI))) { + /* Mlli support -start building the MLLI according to the above + * results + */ + if (areq_ctx->assoc_buff_type == CC_DMA_BUF_MLLI || + areq_ctx->data_buff_type == CC_DMA_BUF_MLLI) { mlli_params->curr_pool = buff_mgr->mlli_buffs_pool; - rc = ssi_buffer_mgr_generate_mlli(dev, &sg_data, mlli_params); - if (unlikely(rc != 0)) + rc = cc_generate_mlli(dev, &sg_data, mlli_params, flags); + if (rc) goto aead_map_failure; - ssi_buffer_mgr_update_aead_mlli_nents(drvdata, req); + cc_update_aead_mlli_nents(drvdata, req); dev_dbg(dev, "assoc params mn %d\n", areq_ctx->assoc.mlli_nents); dev_dbg(dev, "src params mn %d\n", areq_ctx->src.mlli_nents); @@ -1480,19 +1375,18 @@ int ssi_buffer_mgr_map_aead_request( return 0; aead_map_failure: - ssi_buffer_mgr_unmap_aead_request(dev, req); + cc_unmap_aead_request(dev, req); return rc; } -int ssi_buffer_mgr_map_hash_request_final( - struct ssi_drvdata *drvdata, void *ctx, struct scatterlist *src, unsigned int nbytes, bool do_update) +int cc_map_hash_request_final(struct cc_drvdata *drvdata, void *ctx, + struct scatterlist *src, unsigned int nbytes, + bool do_update, gfp_t flags) { struct ahash_req_ctx *areq_ctx = (struct ahash_req_ctx *)ctx; struct device *dev = drvdata_to_dev(drvdata); - u8 *curr_buff = areq_ctx->buff_index ? areq_ctx->buff1 : - areq_ctx->buff0; - u32 *curr_buff_cnt = areq_ctx->buff_index ? &areq_ctx->buff1_cnt : - &areq_ctx->buff0_cnt; + u8 *curr_buff = cc_hash_buf(areq_ctx); + u32 *curr_buff_cnt = cc_hash_buf_cnt(areq_ctx); struct mlli_params *mlli_params = &areq_ctx->mlli_params; struct buffer_array sg_data; struct buff_mgr_handle *buff_mgr = drvdata->buff_mgr_handle; @@ -1502,88 +1396,78 @@ int ssi_buffer_mgr_map_hash_request_final( dev_dbg(dev, "final params : curr_buff=%pK curr_buff_cnt=0x%X nbytes = 0x%X src=%pK curr_index=%u\n", curr_buff, *curr_buff_cnt, nbytes, src, areq_ctx->buff_index); /* Init the type of the dma buffer */ - areq_ctx->data_dma_buf_type = SSI_DMA_BUF_NULL; + areq_ctx->data_dma_buf_type = CC_DMA_BUF_NULL; mlli_params->curr_pool = NULL; sg_data.num_of_buffers = 0; areq_ctx->in_nents = 0; - if (unlikely(nbytes == 0 && *curr_buff_cnt == 0)) { + if (nbytes == 0 && *curr_buff_cnt == 0) { /* nothing to do */ return 0; } /*TODO: copy data in case that buffer is enough for operation */ /* map the previous buffer */ - if (*curr_buff_cnt != 0) { - if (ssi_ahash_handle_curr_buf(dev, areq_ctx, curr_buff, - *curr_buff_cnt, &sg_data) != 0) { + if (*curr_buff_cnt) { + if (cc_set_hash_buf(dev, areq_ctx, curr_buff, *curr_buff_cnt, + &sg_data)) { return -ENOMEM; } } - if (src && (nbytes > 0) && do_update) { - if (unlikely(ssi_buffer_mgr_map_scatterlist(dev, src, nbytes, - DMA_TO_DEVICE, - &areq_ctx->in_nents, - LLI_MAX_NUM_OF_DATA_ENTRIES, - &dummy, - &mapped_nents))){ + if (src && nbytes > 0 && do_update) { + if (cc_map_sg(dev, src, nbytes, DMA_TO_DEVICE, + &areq_ctx->in_nents, LLI_MAX_NUM_OF_DATA_ENTRIES, + &dummy, &mapped_nents)) { goto unmap_curr_buff; } - if (src && (mapped_nents == 1) - && (areq_ctx->data_dma_buf_type == SSI_DMA_BUF_NULL)) { + if (src && mapped_nents == 1 && + areq_ctx->data_dma_buf_type == CC_DMA_BUF_NULL) { memcpy(areq_ctx->buff_sg, src, sizeof(struct scatterlist)); areq_ctx->buff_sg->length = nbytes; areq_ctx->curr_sg = areq_ctx->buff_sg; - areq_ctx->data_dma_buf_type = SSI_DMA_BUF_DLLI; + areq_ctx->data_dma_buf_type = CC_DMA_BUF_DLLI; } else { - areq_ctx->data_dma_buf_type = SSI_DMA_BUF_MLLI; + areq_ctx->data_dma_buf_type = CC_DMA_BUF_MLLI; } } /*build mlli */ - if (unlikely(areq_ctx->data_dma_buf_type == SSI_DMA_BUF_MLLI)) { + if (areq_ctx->data_dma_buf_type == CC_DMA_BUF_MLLI) { mlli_params->curr_pool = buff_mgr->mlli_buffs_pool; /* add the src data to the sg_data */ - ssi_buffer_mgr_add_scatterlist_entry(dev, &sg_data, - areq_ctx->in_nents, - src, nbytes, 0, true, - &areq_ctx->mlli_nents); - if (unlikely(ssi_buffer_mgr_generate_mlli(dev, &sg_data, - mlli_params) != 0)) { + cc_add_sg_entry(dev, &sg_data, areq_ctx->in_nents, src, nbytes, + 0, true, &areq_ctx->mlli_nents); + if (cc_generate_mlli(dev, &sg_data, mlli_params, flags)) goto fail_unmap_din; - } } /* change the buffer index for the unmap function */ areq_ctx->buff_index = (areq_ctx->buff_index ^ 1); dev_dbg(dev, "areq_ctx->data_dma_buf_type = %s\n", - GET_DMA_BUFFER_TYPE(areq_ctx->data_dma_buf_type)); + cc_dma_buf_type(areq_ctx->data_dma_buf_type)); return 0; fail_unmap_din: dma_unmap_sg(dev, src, areq_ctx->in_nents, DMA_TO_DEVICE); unmap_curr_buff: - if (*curr_buff_cnt != 0) + if (*curr_buff_cnt) dma_unmap_sg(dev, areq_ctx->buff_sg, 1, DMA_TO_DEVICE); return -ENOMEM; } -int ssi_buffer_mgr_map_hash_request_update( - struct ssi_drvdata *drvdata, void *ctx, struct scatterlist *src, unsigned int nbytes, unsigned int block_size) +int cc_map_hash_request_update(struct cc_drvdata *drvdata, void *ctx, + struct scatterlist *src, unsigned int nbytes, + unsigned int block_size, gfp_t flags) { struct ahash_req_ctx *areq_ctx = (struct ahash_req_ctx *)ctx; struct device *dev = drvdata_to_dev(drvdata); - u8 *curr_buff = areq_ctx->buff_index ? areq_ctx->buff1 : - areq_ctx->buff0; - u32 *curr_buff_cnt = areq_ctx->buff_index ? &areq_ctx->buff1_cnt : - &areq_ctx->buff0_cnt; - u8 *next_buff = areq_ctx->buff_index ? areq_ctx->buff0 : - areq_ctx->buff1; - u32 *next_buff_cnt = areq_ctx->buff_index ? &areq_ctx->buff0_cnt : - &areq_ctx->buff1_cnt; + u8 *curr_buff = cc_hash_buf(areq_ctx); + u32 *curr_buff_cnt = cc_hash_buf_cnt(areq_ctx); + u8 *next_buff = cc_next_buf(areq_ctx); + u32 *next_buff_cnt = cc_next_buf_cnt(areq_ctx); struct mlli_params *mlli_params = &areq_ctx->mlli_params; unsigned int update_data_len; u32 total_in_len = nbytes + *curr_buff_cnt; @@ -1596,18 +1480,17 @@ int ssi_buffer_mgr_map_hash_request_update( dev_dbg(dev, " update params : curr_buff=%pK curr_buff_cnt=0x%X nbytes=0x%X src=%pK curr_index=%u\n", curr_buff, *curr_buff_cnt, nbytes, src, areq_ctx->buff_index); /* Init the type of the dma buffer */ - areq_ctx->data_dma_buf_type = SSI_DMA_BUF_NULL; + areq_ctx->data_dma_buf_type = CC_DMA_BUF_NULL; mlli_params->curr_pool = NULL; areq_ctx->curr_sg = NULL; sg_data.num_of_buffers = 0; areq_ctx->in_nents = 0; - if (unlikely(total_in_len < block_size)) { + if (total_in_len < block_size) { dev_dbg(dev, " less than one block: curr_buff=%pK *curr_buff_cnt=0x%X copy_to=%pK\n", curr_buff, *curr_buff_cnt, &curr_buff[*curr_buff_cnt]); areq_ctx->in_nents = - ssi_buffer_mgr_get_sgl_nents(dev, src, nbytes, &dummy, - NULL); + cc_get_sgl_nents(dev, src, nbytes, &dummy, NULL); sg_copy_to_buffer(src, areq_ctx->in_nents, &curr_buff[*curr_buff_cnt], nbytes); *curr_buff_cnt += nbytes; @@ -1623,20 +1506,20 @@ int ssi_buffer_mgr_map_hash_request_update( *next_buff_cnt, update_data_len); /* Copy the new residue to next buffer */ - if (*next_buff_cnt != 0) { + if (*next_buff_cnt) { dev_dbg(dev, " handle residue: next buff %pK skip data %u residue %u\n", next_buff, (update_data_len - *curr_buff_cnt), *next_buff_cnt); - ssi_buffer_mgr_copy_scatterlist_portion(dev, next_buff, src, - (update_data_len - *curr_buff_cnt), - nbytes, SSI_SG_TO_BUF); + cc_copy_sg_portion(dev, next_buff, src, + (update_data_len - *curr_buff_cnt), + nbytes, CC_SG_TO_BUF); /* change the buffer index for next operation */ swap_index = 1; } - if (*curr_buff_cnt != 0) { - if (ssi_ahash_handle_curr_buf(dev, areq_ctx, curr_buff, - *curr_buff_cnt, &sg_data) != 0) { + if (*curr_buff_cnt) { + if (cc_set_hash_buf(dev, areq_ctx, curr_buff, *curr_buff_cnt, + &sg_data)) { return -ENOMEM; } /* change the buffer index for next operation */ @@ -1644,42 +1527,33 @@ int ssi_buffer_mgr_map_hash_request_update( } if (update_data_len > *curr_buff_cnt) { - if (unlikely(ssi_buffer_mgr_map_scatterlist(dev, src, - (update_data_len - *curr_buff_cnt), - DMA_TO_DEVICE, - &areq_ctx->in_nents, - LLI_MAX_NUM_OF_DATA_ENTRIES, - &dummy, - &mapped_nents))){ + if (cc_map_sg(dev, src, (update_data_len - *curr_buff_cnt), + DMA_TO_DEVICE, &areq_ctx->in_nents, + LLI_MAX_NUM_OF_DATA_ENTRIES, &dummy, + &mapped_nents)) { goto unmap_curr_buff; } - if ((mapped_nents == 1) - && (areq_ctx->data_dma_buf_type == SSI_DMA_BUF_NULL)) { + if (mapped_nents == 1 && + areq_ctx->data_dma_buf_type == CC_DMA_BUF_NULL) { /* only one entry in the SG and no previous data */ memcpy(areq_ctx->buff_sg, src, sizeof(struct scatterlist)); areq_ctx->buff_sg->length = update_data_len; - areq_ctx->data_dma_buf_type = SSI_DMA_BUF_DLLI; + areq_ctx->data_dma_buf_type = CC_DMA_BUF_DLLI; areq_ctx->curr_sg = areq_ctx->buff_sg; } else { - areq_ctx->data_dma_buf_type = SSI_DMA_BUF_MLLI; + areq_ctx->data_dma_buf_type = CC_DMA_BUF_MLLI; } } - if (unlikely(areq_ctx->data_dma_buf_type == SSI_DMA_BUF_MLLI)) { + if (areq_ctx->data_dma_buf_type == CC_DMA_BUF_MLLI) { mlli_params->curr_pool = buff_mgr->mlli_buffs_pool; /* add the src data to the sg_data */ - ssi_buffer_mgr_add_scatterlist_entry(dev, &sg_data, - areq_ctx->in_nents, - src, - (update_data_len - *curr_buff_cnt), - 0, - true, - &areq_ctx->mlli_nents); - if (unlikely(ssi_buffer_mgr_generate_mlli(dev, &sg_data, - mlli_params) != 0)) { + cc_add_sg_entry(dev, &sg_data, areq_ctx->in_nents, src, + (update_data_len - *curr_buff_cnt), 0, true, + &areq_ctx->mlli_nents); + if (cc_generate_mlli(dev, &sg_data, mlli_params, flags)) goto fail_unmap_din; - } } areq_ctx->buff_index = (areq_ctx->buff_index ^ swap_index); @@ -1689,18 +1563,17 @@ fail_unmap_din: dma_unmap_sg(dev, src, areq_ctx->in_nents, DMA_TO_DEVICE); unmap_curr_buff: - if (*curr_buff_cnt != 0) + if (*curr_buff_cnt) dma_unmap_sg(dev, areq_ctx->buff_sg, 1, DMA_TO_DEVICE); return -ENOMEM; } -void ssi_buffer_mgr_unmap_hash_request( - struct device *dev, void *ctx, struct scatterlist *src, bool do_revert) +void cc_unmap_hash_request(struct device *dev, void *ctx, + struct scatterlist *src, bool do_revert) { struct ahash_req_ctx *areq_ctx = (struct ahash_req_ctx *)ctx; - u32 *prev_len = areq_ctx->buff_index ? &areq_ctx->buff0_cnt : - &areq_ctx->buff1_cnt; + u32 *prev_len = cc_next_buf_cnt(areq_ctx); /*In case a pool was set, a table was *allocated and should be released @@ -1714,21 +1587,23 @@ void ssi_buffer_mgr_unmap_hash_request( areq_ctx->mlli_params.mlli_dma_addr); } - if ((src) && likely(areq_ctx->in_nents != 0)) { + if (src && areq_ctx->in_nents) { dev_dbg(dev, "Unmapped sg src: virt=%pK dma=%pad len=0x%X\n", sg_virt(src), &sg_dma_address(src), sg_dma_len(src)); dma_unmap_sg(dev, src, areq_ctx->in_nents, DMA_TO_DEVICE); } - if (*prev_len != 0) { + if (*prev_len) { dev_dbg(dev, "Unmapped buffer: areq_ctx->buff_sg=%pK dma=%pad len 0x%X\n", sg_virt(areq_ctx->buff_sg), &sg_dma_address(areq_ctx->buff_sg), sg_dma_len(areq_ctx->buff_sg)); dma_unmap_sg(dev, areq_ctx->buff_sg, 1, DMA_TO_DEVICE); if (!do_revert) { - /* clean the previous data length for update operation */ + /* clean the previous data length for update + * operation + */ *prev_len = 0; } else { areq_ctx->buff_index ^= 1; @@ -1736,7 +1611,7 @@ void ssi_buffer_mgr_unmap_hash_request( } } -int ssi_buffer_mgr_init(struct ssi_drvdata *drvdata) +int cc_buffer_mgr_init(struct cc_drvdata *drvdata) { struct buff_mgr_handle *buff_mgr_handle; struct device *dev = drvdata_to_dev(drvdata); @@ -1747,23 +1622,23 @@ int ssi_buffer_mgr_init(struct ssi_drvdata *drvdata) drvdata->buff_mgr_handle = buff_mgr_handle; - buff_mgr_handle->mlli_buffs_pool = dma_pool_create( - "dx_single_mlli_tables", dev, + buff_mgr_handle->mlli_buffs_pool = + dma_pool_create("dx_single_mlli_tables", dev, MAX_NUM_OF_TOTAL_MLLI_ENTRIES * LLI_ENTRY_BYTE_SIZE, MLLI_TABLE_MIN_ALIGNMENT, 0); - if (unlikely(!buff_mgr_handle->mlli_buffs_pool)) + if (!buff_mgr_handle->mlli_buffs_pool) goto error; return 0; error: - ssi_buffer_mgr_fini(drvdata); + cc_buffer_mgr_fini(drvdata); return -ENOMEM; } -int ssi_buffer_mgr_fini(struct ssi_drvdata *drvdata) +int cc_buffer_mgr_fini(struct cc_drvdata *drvdata) { struct buff_mgr_handle *buff_mgr_handle = drvdata->buff_mgr_handle; diff --git a/drivers/staging/ccree/cc_buffer_mgr.h b/drivers/staging/ccree/cc_buffer_mgr.h new file mode 100644 index 000000000000..99b752aa1077 --- /dev/null +++ b/drivers/staging/ccree/cc_buffer_mgr.h @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ + +/* \file cc_buffer_mgr.h + * Buffer Manager + */ + +#ifndef __CC_BUFFER_MGR_H__ +#define __CC_BUFFER_MGR_H__ + +#include <crypto/algapi.h> + +#include "cc_driver.h" + +enum cc_req_dma_buf_type { + CC_DMA_BUF_NULL = 0, + CC_DMA_BUF_DLLI, + CC_DMA_BUF_MLLI +}; + +enum cc_sg_cpy_direct { + CC_SG_TO_BUF = 0, + CC_SG_FROM_BUF = 1 +}; + +struct cc_mlli { + cc_sram_addr_t sram_addr; + unsigned int nents; //sg nents + unsigned int mlli_nents; //mlli nents might be different than the above +}; + +struct mlli_params { + struct dma_pool *curr_pool; + u8 *mlli_virt_addr; + dma_addr_t mlli_dma_addr; + u32 mlli_len; +}; + +int cc_buffer_mgr_init(struct cc_drvdata *drvdata); + +int cc_buffer_mgr_fini(struct cc_drvdata *drvdata); + +int cc_map_blkcipher_request(struct cc_drvdata *drvdata, void *ctx, + unsigned int ivsize, unsigned int nbytes, + void *info, struct scatterlist *src, + struct scatterlist *dst, gfp_t flags); + +void cc_unmap_blkcipher_request(struct device *dev, void *ctx, + unsigned int ivsize, + struct scatterlist *src, + struct scatterlist *dst); + +int cc_map_aead_request(struct cc_drvdata *drvdata, struct aead_request *req); + +void cc_unmap_aead_request(struct device *dev, struct aead_request *req); + +int cc_map_hash_request_final(struct cc_drvdata *drvdata, void *ctx, + struct scatterlist *src, unsigned int nbytes, + bool do_update, gfp_t flags); + +int cc_map_hash_request_update(struct cc_drvdata *drvdata, void *ctx, + struct scatterlist *src, unsigned int nbytes, + unsigned int block_size, gfp_t flags); + +void cc_unmap_hash_request(struct device *dev, void *ctx, + struct scatterlist *src, bool do_revert); + +void cc_copy_sg_portion(struct device *dev, u8 *dest, struct scatterlist *sg, + u32 to_skip, u32 end, enum cc_sg_cpy_direct direct); + +void cc_zero_sgl(struct scatterlist *sgl, u32 data_len); + +#endif /*__BUFFER_MGR_H__*/ + diff --git a/drivers/staging/ccree/ssi_cipher.c b/drivers/staging/ccree/cc_cipher.c index ee85cbf7c9ae..d4ac0ff2ffcf 100644 --- a/drivers/staging/ccree/ssi_cipher.c +++ b/drivers/staging/ccree/cc_cipher.c @@ -1,46 +1,27 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ #include <linux/kernel.h> #include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/semaphore.h> #include <crypto/algapi.h> #include <crypto/internal/skcipher.h> -#include <crypto/aes.h> -#include <crypto/ctr.h> #include <crypto/des.h> #include <crypto/xts.h> #include <crypto/scatterwalk.h> -#include "ssi_config.h" -#include "ssi_driver.h" +#include "cc_driver.h" #include "cc_lli_defs.h" -#include "ssi_buffer_mgr.h" -#include "ssi_cipher.h" -#include "ssi_request_mgr.h" -#include "ssi_sysfs.h" +#include "cc_buffer_mgr.h" +#include "cc_cipher.h" +#include "cc_request_mgr.h" #define MAX_ABLKCIPHER_SEQ_LEN 6 #define template_ablkcipher template_u.ablkcipher -#define SSI_MIN_AES_XTS_SIZE 0x10 -#define SSI_MAX_AES_XTS_SIZE 0x2000 -struct ssi_blkcipher_handle { +#define CC_MIN_AES_XTS_SIZE 0x10 +#define CC_MAX_AES_XTS_SIZE 0x2000 +struct cc_cipher_handle { struct list_head blkcipher_alg_list; }; @@ -54,8 +35,8 @@ struct cc_hw_key_info { enum cc_hw_crypto_key key2_slot; }; -struct ssi_ablkcipher_ctx { - struct ssi_drvdata *drvdata; +struct cc_cipher_ctx { + struct cc_drvdata *drvdata; int keylen; int key_round_number; int cipher_mode; @@ -67,61 +48,56 @@ struct ssi_ablkcipher_ctx { struct crypto_shash *shash_tfm; }; -static void ssi_ablkcipher_complete(struct device *dev, void *ssi_req, void __iomem *cc_base); +static void cc_cipher_complete(struct device *dev, void *cc_req, int err); -static int validate_keys_sizes(struct ssi_ablkcipher_ctx *ctx_p, u32 size) +static int validate_keys_sizes(struct cc_cipher_ctx *ctx_p, u32 size) { switch (ctx_p->flow_mode) { case S_DIN_to_AES: switch (size) { case CC_AES_128_BIT_KEY_SIZE: case CC_AES_192_BIT_KEY_SIZE: - if (likely((ctx_p->cipher_mode != DRV_CIPHER_XTS) && - (ctx_p->cipher_mode != DRV_CIPHER_ESSIV) && - (ctx_p->cipher_mode != DRV_CIPHER_BITLOCKER))) + if (ctx_p->cipher_mode != DRV_CIPHER_XTS && + ctx_p->cipher_mode != DRV_CIPHER_ESSIV && + ctx_p->cipher_mode != DRV_CIPHER_BITLOCKER) return 0; break; case CC_AES_256_BIT_KEY_SIZE: return 0; case (CC_AES_192_BIT_KEY_SIZE * 2): case (CC_AES_256_BIT_KEY_SIZE * 2): - if (likely((ctx_p->cipher_mode == DRV_CIPHER_XTS) || - (ctx_p->cipher_mode == DRV_CIPHER_ESSIV) || - (ctx_p->cipher_mode == DRV_CIPHER_BITLOCKER))) + if (ctx_p->cipher_mode == DRV_CIPHER_XTS || + ctx_p->cipher_mode == DRV_CIPHER_ESSIV || + ctx_p->cipher_mode == DRV_CIPHER_BITLOCKER) return 0; break; default: break; } case S_DIN_to_DES: - if (likely(size == DES3_EDE_KEY_SIZE || size == DES_KEY_SIZE)) + if (size == DES3_EDE_KEY_SIZE || size == DES_KEY_SIZE) return 0; break; -#if SSI_CC_HAS_MULTI2 - case S_DIN_to_MULTI2: - if (likely(size == CC_MULTI2_SYSTEM_N_DATA_KEY_SIZE)) - return 0; - break; -#endif default: break; } return -EINVAL; } -static int validate_data_size(struct ssi_ablkcipher_ctx *ctx_p, unsigned int size) +static int validate_data_size(struct cc_cipher_ctx *ctx_p, + unsigned int size) { switch (ctx_p->flow_mode) { case S_DIN_to_AES: switch (ctx_p->cipher_mode) { case DRV_CIPHER_XTS: - if ((size >= SSI_MIN_AES_XTS_SIZE) && - (size <= SSI_MAX_AES_XTS_SIZE) && + if (size >= CC_MIN_AES_XTS_SIZE && + size <= CC_MAX_AES_XTS_SIZE && IS_ALIGNED(size, AES_BLOCK_SIZE)) return 0; break; case DRV_CIPHER_CBC_CTS: - if (likely(size >= AES_BLOCK_SIZE)) + if (size >= AES_BLOCK_SIZE) return 0; break; case DRV_CIPHER_OFB: @@ -131,7 +107,7 @@ static int validate_data_size(struct ssi_ablkcipher_ctx *ctx_p, unsigned int siz case DRV_CIPHER_CBC: case DRV_CIPHER_ESSIV: case DRV_CIPHER_BITLOCKER: - if (likely(IS_ALIGNED(size, AES_BLOCK_SIZE))) + if (IS_ALIGNED(size, AES_BLOCK_SIZE)) return 0; break; default: @@ -139,23 +115,9 @@ static int validate_data_size(struct ssi_ablkcipher_ctx *ctx_p, unsigned int siz } break; case S_DIN_to_DES: - if (likely(IS_ALIGNED(size, DES_BLOCK_SIZE))) - return 0; - break; -#if SSI_CC_HAS_MULTI2 - case S_DIN_to_MULTI2: - switch (ctx_p->cipher_mode) { - case DRV_MULTI2_CBC: - if (likely(IS_ALIGNED(size, CC_MULTI2_BLOCK_SIZE))) - return 0; - break; - case DRV_MULTI2_OFB: + if (IS_ALIGNED(size, DES_BLOCK_SIZE)) return 0; - default: - break; - } break; -#endif /*SSI_CC_HAS_MULTI2*/ default: break; } @@ -164,36 +126,42 @@ static int validate_data_size(struct ssi_ablkcipher_ctx *ctx_p, unsigned int siz static unsigned int get_max_keysize(struct crypto_tfm *tfm) { - struct ssi_crypto_alg *ssi_alg = container_of(tfm->__crt_alg, struct ssi_crypto_alg, crypto_alg); + struct cc_crypto_alg *cc_alg = + container_of(tfm->__crt_alg, struct cc_crypto_alg, crypto_alg); - if ((ssi_alg->crypto_alg.cra_flags & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_ABLKCIPHER) - return ssi_alg->crypto_alg.cra_ablkcipher.max_keysize; + if ((cc_alg->crypto_alg.cra_flags & CRYPTO_ALG_TYPE_MASK) == + CRYPTO_ALG_TYPE_ABLKCIPHER) + return cc_alg->crypto_alg.cra_ablkcipher.max_keysize; - if ((ssi_alg->crypto_alg.cra_flags & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_BLKCIPHER) - return ssi_alg->crypto_alg.cra_blkcipher.max_keysize; + if ((cc_alg->crypto_alg.cra_flags & CRYPTO_ALG_TYPE_MASK) == + CRYPTO_ALG_TYPE_BLKCIPHER) + return cc_alg->crypto_alg.cra_blkcipher.max_keysize; return 0; } -static int ssi_blkcipher_init(struct crypto_tfm *tfm) +static int cc_cipher_init(struct crypto_tfm *tfm) { - struct ssi_ablkcipher_ctx *ctx_p = crypto_tfm_ctx(tfm); + struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm); struct crypto_alg *alg = tfm->__crt_alg; - struct ssi_crypto_alg *ssi_alg = - container_of(alg, struct ssi_crypto_alg, crypto_alg); - struct device *dev = drvdata_to_dev(ssi_alg->drvdata); + struct cc_crypto_alg *cc_alg = + container_of(alg, struct cc_crypto_alg, crypto_alg); + struct device *dev = drvdata_to_dev(cc_alg->drvdata); int rc = 0; unsigned int max_key_buf_size = get_max_keysize(tfm); + struct ablkcipher_tfm *ablktfm = &tfm->crt_ablkcipher; dev_dbg(dev, "Initializing context @%p for %s\n", ctx_p, crypto_tfm_alg_name(tfm)); - ctx_p->cipher_mode = ssi_alg->cipher_mode; - ctx_p->flow_mode = ssi_alg->flow_mode; - ctx_p->drvdata = ssi_alg->drvdata; + ablktfm->reqsize = sizeof(struct blkcipher_req_ctx); + + ctx_p->cipher_mode = cc_alg->cipher_mode; + ctx_p->flow_mode = cc_alg->flow_mode; + ctx_p->drvdata = cc_alg->drvdata; /* Allocate key buffer, cache line aligned */ - ctx_p->user.key = kmalloc(max_key_buf_size, GFP_KERNEL | GFP_DMA); + ctx_p->user.key = kmalloc(max_key_buf_size, GFP_KERNEL); if (!ctx_p->user.key) return -ENOMEM; @@ -224,9 +192,9 @@ static int ssi_blkcipher_init(struct crypto_tfm *tfm) return rc; } -static void ssi_blkcipher_exit(struct crypto_tfm *tfm) +static void cc_cipher_exit(struct crypto_tfm *tfm) { - struct ssi_ablkcipher_ctx *ctx_p = crypto_tfm_ctx(tfm); + struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm); struct device *dev = drvdata_to_dev(ctx_p->drvdata); unsigned int max_key_buf_size = get_max_keysize(tfm); @@ -262,13 +230,15 @@ static const u8 zero_buff[] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; /* The function verifies that tdes keys are not weak.*/ -static int ssi_verify_3des_keys(const u8 *key, unsigned int keylen) +static int cc_verify_3des_keys(const u8 *key, unsigned int keylen) { struct tdes_keys *tdes_key = (struct tdes_keys *)key; /* verify key1 != key2 and key3 != key2*/ - if (unlikely((memcmp((u8 *)tdes_key->key1, (u8 *)tdes_key->key2, sizeof(tdes_key->key1)) == 0) || - (memcmp((u8 *)tdes_key->key3, (u8 *)tdes_key->key2, sizeof(tdes_key->key3)) == 0))) { + if ((memcmp((u8 *)tdes_key->key1, (u8 *)tdes_key->key2, + sizeof(tdes_key->key1)) == 0) || + (memcmp((u8 *)tdes_key->key3, (u8 *)tdes_key->key2, + sizeof(tdes_key->key3)) == 0)) { return -ENOEXEC; } @@ -290,11 +260,11 @@ static enum cc_hw_crypto_key hw_key_to_cc_hw_key(int slot_num) return END_OF_KEYS; } -static int ssi_blkcipher_setkey(struct crypto_tfm *tfm, - const u8 *key, - unsigned int keylen) +static int cc_cipher_setkey(struct crypto_ablkcipher *atfm, const u8 *key, + unsigned int keylen) { - struct ssi_ablkcipher_ctx *ctx_p = crypto_tfm_ctx(tfm); + struct crypto_tfm *tfm = crypto_ablkcipher_tfm(atfm); + struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm); struct device *dev = drvdata_to_dev(ctx_p->drvdata); u32 tmp[DES_EXPKEY_WORDS]; unsigned int max_key_buf_size = get_max_keysize(tfm); @@ -305,44 +275,39 @@ static int ssi_blkcipher_setkey(struct crypto_tfm *tfm, /* STAT_PHASE_0: Init and sanity checks */ -#if SSI_CC_HAS_MULTI2 - /*last byte of key buffer is round number and should not be a part of key size*/ - if (ctx_p->flow_mode == S_DIN_to_MULTI2) - keylen -= 1; -#endif /*SSI_CC_HAS_MULTI2*/ - - if (unlikely(validate_keys_sizes(ctx_p, keylen) != 0)) { + if (validate_keys_sizes(ctx_p, keylen)) { dev_err(dev, "Unsupported key size %d.\n", keylen); crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); return -EINVAL; } - if (ssi_is_hw_key(tfm)) { + if (cc_is_hw_key(tfm)) { /* setting HW key slots */ struct arm_hw_key_info *hki = (struct arm_hw_key_info *)key; - if (unlikely(ctx_p->flow_mode != S_DIN_to_AES)) { + if (ctx_p->flow_mode != S_DIN_to_AES) { dev_err(dev, "HW key not supported for non-AES flows\n"); return -EINVAL; } ctx_p->hw.key1_slot = hw_key_to_cc_hw_key(hki->hw_key1); - if (unlikely(ctx_p->hw.key1_slot == END_OF_KEYS)) { + if (ctx_p->hw.key1_slot == END_OF_KEYS) { dev_err(dev, "Unsupported hw key1 number (%d)\n", hki->hw_key1); return -EINVAL; } - if ((ctx_p->cipher_mode == DRV_CIPHER_XTS) || - (ctx_p->cipher_mode == DRV_CIPHER_ESSIV) || - (ctx_p->cipher_mode == DRV_CIPHER_BITLOCKER)) { - if (unlikely(hki->hw_key1 == hki->hw_key2)) { + if (ctx_p->cipher_mode == DRV_CIPHER_XTS || + ctx_p->cipher_mode == DRV_CIPHER_ESSIV || + ctx_p->cipher_mode == DRV_CIPHER_BITLOCKER) { + if (hki->hw_key1 == hki->hw_key2) { dev_err(dev, "Illegal hw key numbers (%d,%d)\n", hki->hw_key1, hki->hw_key2); return -EINVAL; } - ctx_p->hw.key2_slot = hw_key_to_cc_hw_key(hki->hw_key2); - if (unlikely(ctx_p->hw.key2_slot == END_OF_KEYS)) { + ctx_p->hw.key2_slot = + hw_key_to_cc_hw_key(hki->hw_key2); + if (ctx_p->hw.key2_slot == END_OF_KEYS) { dev_err(dev, "Unsupported hw key2 number (%d)\n", hki->hw_key2); return -EINVAL; @@ -350,28 +315,28 @@ static int ssi_blkcipher_setkey(struct crypto_tfm *tfm, } ctx_p->keylen = keylen; - dev_dbg(dev, "ssi_is_hw_key ret 0"); + dev_dbg(dev, "cc_is_hw_key ret 0"); return 0; } // verify weak keys if (ctx_p->flow_mode == S_DIN_to_DES) { - if (unlikely(!des_ekey(tmp, key)) && + if (!des_ekey(tmp, key) && (crypto_tfm_get_flags(tfm) & CRYPTO_TFM_REQ_WEAK_KEY)) { tfm->crt_flags |= CRYPTO_TFM_RES_WEAK_KEY; dev_dbg(dev, "weak DES key"); return -EINVAL; } } - if ((ctx_p->cipher_mode == DRV_CIPHER_XTS) && - xts_check_key(tfm, key, keylen) != 0) { + if (ctx_p->cipher_mode == DRV_CIPHER_XTS && + xts_check_key(tfm, key, keylen)) { dev_dbg(dev, "weak XTS key"); return -EINVAL; } - if ((ctx_p->flow_mode == S_DIN_to_DES) && - (keylen == DES3_EDE_KEY_SIZE) && - ssi_verify_3des_keys(key, keylen) != 0) { + if (ctx_p->flow_mode == S_DIN_to_DES && + keylen == DES3_EDE_KEY_SIZE && + cc_verify_3des_keys(key, keylen)) { dev_dbg(dev, "weak 3DES key"); return -EINVAL; } @@ -380,34 +345,24 @@ static int ssi_blkcipher_setkey(struct crypto_tfm *tfm, dma_sync_single_for_cpu(dev, ctx_p->user.key_dma_addr, max_key_buf_size, DMA_TO_DEVICE); - if (ctx_p->flow_mode == S_DIN_to_MULTI2) { -#if SSI_CC_HAS_MULTI2 - memcpy(ctx_p->user.key, key, CC_MULTI2_SYSTEM_N_DATA_KEY_SIZE); - ctx_p->key_round_number = key[CC_MULTI2_SYSTEM_N_DATA_KEY_SIZE]; - if (ctx_p->key_round_number < CC_MULTI2_MIN_NUM_ROUNDS || - ctx_p->key_round_number > CC_MULTI2_MAX_NUM_ROUNDS) { - crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); - dev_dbg(dev, "SSI_CC_HAS_MULTI2 einval"); - return -EINVAL; -#endif /*SSI_CC_HAS_MULTI2*/ - } else { - memcpy(ctx_p->user.key, key, keylen); - if (keylen == 24) - memset(ctx_p->user.key + 24, 0, CC_AES_KEY_SIZE_MAX - 24); - - if (ctx_p->cipher_mode == DRV_CIPHER_ESSIV) { - /* sha256 for key2 - use sw implementation */ - int key_len = keylen >> 1; - int err; - SHASH_DESC_ON_STACK(desc, ctx_p->shash_tfm); - - desc->tfm = ctx_p->shash_tfm; - - err = crypto_shash_digest(desc, ctx_p->user.key, key_len, ctx_p->user.key + key_len); - if (err) { - dev_err(dev, "Failed to hash ESSIV key.\n"); - return err; - } + memcpy(ctx_p->user.key, key, keylen); + if (keylen == 24) + memset(ctx_p->user.key + 24, 0, CC_AES_KEY_SIZE_MAX - 24); + + if (ctx_p->cipher_mode == DRV_CIPHER_ESSIV) { + /* sha256 for key2 - use sw implementation */ + int key_len = keylen >> 1; + int err; + + SHASH_DESC_ON_STACK(desc, ctx_p->shash_tfm); + + desc->tfm = ctx_p->shash_tfm; + + err = crypto_shash_digest(desc, ctx_p->user.key, key_len, + ctx_p->user.key + key_len); + if (err) { + dev_err(dev, "Failed to hash ESSIV key.\n"); + return err; } } dma_sync_single_for_device(dev, ctx_p->user.key_dma_addr, @@ -418,16 +373,13 @@ static int ssi_blkcipher_setkey(struct crypto_tfm *tfm, return 0; } -static inline void -ssi_blkcipher_create_setup_desc( - struct crypto_tfm *tfm, - struct blkcipher_req_ctx *req_ctx, - unsigned int ivsize, - unsigned int nbytes, - struct cc_hw_desc desc[], - unsigned int *seq_size) +static void cc_setup_cipher_desc(struct crypto_tfm *tfm, + struct blkcipher_req_ctx *req_ctx, + unsigned int ivsize, unsigned int nbytes, + struct cc_hw_desc desc[], + unsigned int *seq_size) { - struct ssi_ablkcipher_ctx *ctx_p = crypto_tfm_ctx(tfm); + struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm); struct device *dev = drvdata_to_dev(ctx_p->drvdata); int cipher_mode = ctx_p->cipher_mode; int flow_mode = ctx_p->flow_mode; @@ -437,11 +389,14 @@ ssi_blkcipher_create_setup_desc( dma_addr_t iv_dma_addr = req_ctx->gen_ctx.iv_dma_addr; unsigned int du_size = nbytes; - struct ssi_crypto_alg *ssi_alg = container_of(tfm->__crt_alg, struct ssi_crypto_alg, crypto_alg); + struct cc_crypto_alg *cc_alg = + container_of(tfm->__crt_alg, struct cc_crypto_alg, crypto_alg); - if ((ssi_alg->crypto_alg.cra_flags & CRYPTO_ALG_BULK_MASK) == CRYPTO_ALG_BULK_DU_512) + if ((cc_alg->crypto_alg.cra_flags & CRYPTO_ALG_BULK_MASK) == + CRYPTO_ALG_BULK_DU_512) du_size = 512; - if ((ssi_alg->crypto_alg.cra_flags & CRYPTO_ALG_BULK_MASK) == CRYPTO_ALG_BULK_DU_4096) + if ((cc_alg->crypto_alg.cra_flags & CRYPTO_ALG_BULK_MASK) == + CRYPTO_ALG_BULK_DU_4096) du_size = 4096; switch (cipher_mode) { @@ -456,8 +411,8 @@ ssi_blkcipher_create_setup_desc( set_cipher_config0(&desc[*seq_size], direction); set_flow_mode(&desc[*seq_size], flow_mode); set_cipher_mode(&desc[*seq_size], cipher_mode); - if ((cipher_mode == DRV_CIPHER_CTR) || - (cipher_mode == DRV_CIPHER_OFB)) { + if (cipher_mode == DRV_CIPHER_CTR || + cipher_mode == DRV_CIPHER_OFB) { set_setup_mode(&desc[*seq_size], SETUP_LOAD_STATE1); } else { set_setup_mode(&desc[*seq_size], SETUP_LOAD_STATE0); @@ -470,7 +425,7 @@ ssi_blkcipher_create_setup_desc( set_cipher_mode(&desc[*seq_size], cipher_mode); set_cipher_config0(&desc[*seq_size], direction); if (flow_mode == S_DIN_to_AES) { - if (ssi_is_hw_key(tfm)) { + if (cc_is_hw_key(tfm)) { set_hw_crypto_key(&desc[*seq_size], ctx_p->hw.key1_slot); } else { @@ -497,7 +452,7 @@ ssi_blkcipher_create_setup_desc( hw_desc_init(&desc[*seq_size]); set_cipher_mode(&desc[*seq_size], cipher_mode); set_cipher_config0(&desc[*seq_size], direction); - if (ssi_is_hw_key(tfm)) { + if (cc_is_hw_key(tfm)) { set_hw_crypto_key(&desc[*seq_size], ctx_p->hw.key1_slot); } else { @@ -513,7 +468,7 @@ ssi_blkcipher_create_setup_desc( hw_desc_init(&desc[*seq_size]); set_cipher_mode(&desc[*seq_size], cipher_mode); set_cipher_config0(&desc[*seq_size], direction); - if (ssi_is_hw_key(tfm)) { + if (cc_is_hw_key(tfm)) { set_hw_crypto_key(&desc[*seq_size], ctx_p->hw.key2_slot); } else { @@ -543,62 +498,14 @@ ssi_blkcipher_create_setup_desc( } } -#if SSI_CC_HAS_MULTI2 -static inline void ssi_blkcipher_create_multi2_setup_desc( - struct crypto_tfm *tfm, - struct blkcipher_req_ctx *req_ctx, - unsigned int ivsize, - struct cc_hw_desc desc[], - unsigned int *seq_size) -{ - struct ssi_ablkcipher_ctx *ctx_p = crypto_tfm_ctx(tfm); - - int direction = req_ctx->gen_ctx.op_type; - /* Load system key */ - hw_desc_init(&desc[*seq_size]); - set_cipher_mode(&desc[*seq_size], ctx_p->cipher_mode); - set_cipher_config0(&desc[*seq_size], direction); - set_din_type(&desc[*seq_size], DMA_DLLI, ctx_p->user.key_dma_addr, - CC_MULTI2_SYSTEM_KEY_SIZE, NS_BIT); - set_flow_mode(&desc[*seq_size], ctx_p->flow_mode); - set_setup_mode(&desc[*seq_size], SETUP_LOAD_KEY0); - (*seq_size)++; - - /* load data key */ - hw_desc_init(&desc[*seq_size]); - set_din_type(&desc[*seq_size], DMA_DLLI, - (ctx_p->user.key_dma_addr + CC_MULTI2_SYSTEM_KEY_SIZE), - CC_MULTI2_DATA_KEY_SIZE, NS_BIT); - set_multi2_num_rounds(&desc[*seq_size], ctx_p->key_round_number); - set_flow_mode(&desc[*seq_size], ctx_p->flow_mode); - set_cipher_mode(&desc[*seq_size], ctx_p->cipher_mode); - set_cipher_config0(&desc[*seq_size], direction); - set_setup_mode(&desc[*seq_size], SETUP_LOAD_STATE0); - (*seq_size)++; - - /* Set state */ - hw_desc_init(&desc[*seq_size]); - set_din_type(&desc[*seq_size], DMA_DLLI, req_ctx->gen_ctx.iv_dma_addr, - ivsize, NS_BIT); - set_cipher_config0(&desc[*seq_size], direction); - set_flow_mode(&desc[*seq_size], ctx_p->flow_mode); - set_cipher_mode(&desc[*seq_size], ctx_p->cipher_mode); - set_setup_mode(&desc[*seq_size], SETUP_LOAD_STATE1); - (*seq_size)++; -} -#endif /*SSI_CC_HAS_MULTI2*/ - -static inline void -ssi_blkcipher_create_data_desc( - struct crypto_tfm *tfm, - struct blkcipher_req_ctx *req_ctx, - struct scatterlist *dst, struct scatterlist *src, - unsigned int nbytes, - void *areq, - struct cc_hw_desc desc[], - unsigned int *seq_size) +static void cc_setup_cipher_data(struct crypto_tfm *tfm, + struct blkcipher_req_ctx *req_ctx, + struct scatterlist *dst, + struct scatterlist *src, unsigned int nbytes, + void *areq, struct cc_hw_desc desc[], + unsigned int *seq_size) { - struct ssi_ablkcipher_ctx *ctx_p = crypto_tfm_ctx(tfm); + struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm); struct device *dev = drvdata_to_dev(ctx_p->drvdata); unsigned int flow_mode = ctx_p->flow_mode; @@ -609,17 +516,12 @@ ssi_blkcipher_create_data_desc( case S_DIN_to_DES: flow_mode = DIN_DES_DOUT; break; -#if SSI_CC_HAS_MULTI2 - case S_DIN_to_MULTI2: - flow_mode = DIN_MULTI2_DOUT; - break; -#endif /*SSI_CC_HAS_MULTI2*/ default: dev_err(dev, "invalid flow mode, flow_mode = %d\n", flow_mode); return; } /* Process */ - if (likely(req_ctx->dma_buf_type == SSI_DMA_BUF_DLLI)) { + if (req_ctx->dma_buf_type == CC_DMA_BUF_DLLI) { dev_dbg(dev, " data params addr %pad length 0x%X\n", &sg_dma_address(src), nbytes); dev_dbg(dev, " data params addr %pad length 0x%X\n", @@ -682,68 +584,63 @@ ssi_blkcipher_create_data_desc( } } -static int ssi_blkcipher_complete(struct device *dev, - struct ssi_ablkcipher_ctx *ctx_p, - struct blkcipher_req_ctx *req_ctx, - struct scatterlist *dst, - struct scatterlist *src, - unsigned int ivsize, - void *areq, - void __iomem *cc_base) +static void cc_cipher_complete(struct device *dev, void *cc_req, int err) { - int completion_error = 0; + struct ablkcipher_request *areq = (struct ablkcipher_request *)cc_req; + struct scatterlist *dst = areq->dst; + struct scatterlist *src = areq->src; + struct blkcipher_req_ctx *req_ctx = ablkcipher_request_ctx(areq); + struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(areq); + unsigned int ivsize = crypto_ablkcipher_ivsize(tfm); struct ablkcipher_request *req = (struct ablkcipher_request *)areq; - ssi_buffer_mgr_unmap_blkcipher_request(dev, req_ctx, ivsize, src, dst); + cc_unmap_blkcipher_request(dev, req_ctx, ivsize, src, dst); kfree(req_ctx->iv); - if (areq) { - /* - * The crypto API expects us to set the req->info to the last - * ciphertext block. For encrypt, simply copy from the result. - * For decrypt, we must copy from a saved buffer since this - * could be an in-place decryption operation and the src is - * lost by this point. - */ - if (req_ctx->gen_ctx.op_type == DRV_CRYPTO_DIRECTION_DECRYPT) { - memcpy(req->info, req_ctx->backup_info, ivsize); - kfree(req_ctx->backup_info); - } else { - scatterwalk_map_and_copy(req->info, req->dst, - (req->nbytes - ivsize), - ivsize, 0); - } - - ablkcipher_request_complete(areq, completion_error); - return 0; + /* + * The crypto API expects us to set the req->info to the last + * ciphertext block. For encrypt, simply copy from the result. + * For decrypt, we must copy from a saved buffer since this + * could be an in-place decryption operation and the src is + * lost by this point. + */ + if (req_ctx->gen_ctx.op_type == DRV_CRYPTO_DIRECTION_DECRYPT) { + memcpy(req->info, req_ctx->backup_info, ivsize); + kfree(req_ctx->backup_info); + } else if (!err) { + scatterwalk_map_and_copy(req->info, req->dst, + (req->nbytes - ivsize), ivsize, 0); } - return completion_error; + + ablkcipher_request_complete(areq, err); } -static int ssi_blkcipher_process( - struct crypto_tfm *tfm, - struct blkcipher_req_ctx *req_ctx, - struct scatterlist *dst, struct scatterlist *src, - unsigned int nbytes, - void *info, //req info - unsigned int ivsize, - void *areq, - enum drv_crypto_direction direction) +static int cc_cipher_process(struct ablkcipher_request *req, + enum drv_crypto_direction direction) { - struct ssi_ablkcipher_ctx *ctx_p = crypto_tfm_ctx(tfm); + struct crypto_ablkcipher *ablk_tfm = crypto_ablkcipher_reqtfm(req); + struct crypto_tfm *tfm = crypto_ablkcipher_tfm(ablk_tfm); + struct blkcipher_req_ctx *req_ctx = ablkcipher_request_ctx(req); + unsigned int ivsize = crypto_ablkcipher_ivsize(ablk_tfm); + struct scatterlist *dst = req->dst; + struct scatterlist *src = req->src; + unsigned int nbytes = req->nbytes; + void *info = req->info; + struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm); struct device *dev = drvdata_to_dev(ctx_p->drvdata); struct cc_hw_desc desc[MAX_ABLKCIPHER_SEQ_LEN]; - struct ssi_crypto_req ssi_req = {}; + struct cc_crypto_req cc_req = {}; int rc, seq_len = 0, cts_restore_flag = 0; + gfp_t flags = cc_gfp_flags(&req->base); - dev_dbg(dev, "%s areq=%p info=%p nbytes=%d\n", + dev_dbg(dev, "%s req=%p info=%p nbytes=%d\n", ((direction == DRV_CRYPTO_DIRECTION_ENCRYPT) ? - "Encrypt" : "Decrypt"), areq, info, nbytes); + "Encrypt" : "Decrypt"), req, info, nbytes); /* STAT_PHASE_0: Init and sanity checks */ /* TODO: check data length according to mode */ - if (unlikely(validate_data_size(ctx_p, nbytes))) { + if (validate_data_size(ctx_p, nbytes)) { dev_err(dev, "Unsupported data size %d.\n", nbytes); crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_BAD_BLOCK_LEN); rc = -EINVAL; @@ -758,7 +655,7 @@ static int ssi_blkcipher_process( /* The IV we are handed may be allocted from the stack so * we must copy it to a DMAable buffer before use. */ - req_ctx->iv = kmalloc(ivsize, GFP_KERNEL); + req_ctx->iv = kmalloc(ivsize, flags); if (!req_ctx->iv) { rc = -ENOMEM; goto exit_process; @@ -766,17 +663,18 @@ static int ssi_blkcipher_process( memcpy(req_ctx->iv, info, ivsize); /*For CTS in case of data size aligned to 16 use CBC mode*/ - if (((nbytes % AES_BLOCK_SIZE) == 0) && (ctx_p->cipher_mode == DRV_CIPHER_CBC_CTS)) { + if (((nbytes % AES_BLOCK_SIZE) == 0) && + ctx_p->cipher_mode == DRV_CIPHER_CBC_CTS) { ctx_p->cipher_mode = DRV_CIPHER_CBC; cts_restore_flag = 1; } /* Setup DX request structure */ - ssi_req.user_cb = (void *)ssi_ablkcipher_complete; - ssi_req.user_arg = (void *)areq; + cc_req.user_cb = (void *)cc_cipher_complete; + cc_req.user_arg = (void *)req; #ifdef ENABLE_CYCLE_COUNT - ssi_req.op_type = (direction == DRV_CRYPTO_DIRECTION_DECRYPT) ? + cc_req.op_type = (direction == DRV_CRYPTO_DIRECTION_DECRYPT) ? STAT_OP_TYPE_DECODE : STAT_OP_TYPE_ENCODE; #endif @@ -786,10 +684,9 @@ static int ssi_blkcipher_process( /* STAT_PHASE_1: Map buffers */ - rc = ssi_buffer_mgr_map_blkcipher_request(ctx_p->drvdata, req_ctx, - ivsize, nbytes, req_ctx->iv, - src, dst); - if (unlikely(rc != 0)) { + rc = cc_map_blkcipher_request(ctx_p->drvdata, req_ctx, ivsize, nbytes, + req_ctx->iv, src, dst, flags); + if (rc) { dev_err(dev, "map_request() failed\n"); goto exit_process; } @@ -797,50 +694,35 @@ static int ssi_blkcipher_process( /* STAT_PHASE_2: Create sequence */ /* Setup processing */ -#if SSI_CC_HAS_MULTI2 - if (ctx_p->flow_mode == S_DIN_to_MULTI2) - ssi_blkcipher_create_multi2_setup_desc(tfm, req_ctx, ivsize, - desc, &seq_len); - else -#endif /*SSI_CC_HAS_MULTI2*/ - ssi_blkcipher_create_setup_desc(tfm, req_ctx, ivsize, nbytes, - desc, &seq_len); + cc_setup_cipher_desc(tfm, req_ctx, ivsize, nbytes, desc, &seq_len); /* Data processing */ - ssi_blkcipher_create_data_desc(tfm, req_ctx, dst, src, nbytes, areq, - desc, &seq_len); + cc_setup_cipher_data(tfm, req_ctx, dst, src, nbytes, req, desc, + &seq_len); /* do we need to generate IV? */ if (req_ctx->is_giv) { - ssi_req.ivgen_dma_addr[0] = req_ctx->gen_ctx.iv_dma_addr; - ssi_req.ivgen_dma_addr_len = 1; + cc_req.ivgen_dma_addr[0] = req_ctx->gen_ctx.iv_dma_addr; + cc_req.ivgen_dma_addr_len = 1; /* set the IV size (8/16 B long)*/ - ssi_req.ivgen_size = ivsize; + cc_req.ivgen_size = ivsize; } /* STAT_PHASE_3: Lock HW and push sequence */ - rc = send_request(ctx_p->drvdata, &ssi_req, desc, seq_len, (!areq) ? 0 : 1); - if (areq) { - if (unlikely(rc != -EINPROGRESS)) { - /* Failed to send the request or request completed synchronously */ - ssi_buffer_mgr_unmap_blkcipher_request(dev, req_ctx, ivsize, src, dst); - } - - } else { - if (rc != 0) { - ssi_buffer_mgr_unmap_blkcipher_request(dev, req_ctx, ivsize, src, dst); - } else { - rc = ssi_blkcipher_complete(dev, ctx_p, req_ctx, dst, - src, ivsize, NULL, - ctx_p->drvdata->cc_base); - } + rc = cc_send_request(ctx_p->drvdata, &cc_req, desc, seq_len, + &req->base); + if (rc != -EINPROGRESS && rc != -EBUSY) { + /* Failed to send the request or request completed + * synchronously + */ + cc_unmap_blkcipher_request(dev, req_ctx, ivsize, src, dst); } exit_process: - if (cts_restore_flag != 0) + if (cts_restore_flag) ctx_p->cipher_mode = DRV_CIPHER_CBC_CTS; - if (rc != -EINPROGRESS) { + if (rc != -EINPROGRESS && rc != -EBUSY) { kfree(req_ctx->backup_info); kfree(req_ctx->iv); } @@ -848,60 +730,28 @@ exit_process: return rc; } -static void ssi_ablkcipher_complete(struct device *dev, void *ssi_req, void __iomem *cc_base) -{ - struct ablkcipher_request *areq = (struct ablkcipher_request *)ssi_req; - struct blkcipher_req_ctx *req_ctx = ablkcipher_request_ctx(areq); - struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(areq); - struct ssi_ablkcipher_ctx *ctx_p = crypto_ablkcipher_ctx(tfm); - unsigned int ivsize = crypto_ablkcipher_ivsize(tfm); - - ssi_blkcipher_complete(dev, ctx_p, req_ctx, areq->dst, areq->src, - ivsize, areq, cc_base); -} - -/* Async wrap functions */ - -static int ssi_ablkcipher_init(struct crypto_tfm *tfm) -{ - struct ablkcipher_tfm *ablktfm = &tfm->crt_ablkcipher; - - ablktfm->reqsize = sizeof(struct blkcipher_req_ctx); - - return ssi_blkcipher_init(tfm); -} - -static int ssi_ablkcipher_setkey(struct crypto_ablkcipher *tfm, - const u8 *key, - unsigned int keylen) -{ - return ssi_blkcipher_setkey(crypto_ablkcipher_tfm(tfm), key, keylen); -} - -static int ssi_ablkcipher_encrypt(struct ablkcipher_request *req) +static int cc_cipher_encrypt(struct ablkcipher_request *req) { - struct crypto_ablkcipher *ablk_tfm = crypto_ablkcipher_reqtfm(req); - struct crypto_tfm *tfm = crypto_ablkcipher_tfm(ablk_tfm); struct blkcipher_req_ctx *req_ctx = ablkcipher_request_ctx(req); - unsigned int ivsize = crypto_ablkcipher_ivsize(ablk_tfm); req_ctx->is_giv = false; + req_ctx->backup_info = NULL; - return ssi_blkcipher_process(tfm, req_ctx, req->dst, req->src, req->nbytes, req->info, ivsize, (void *)req, DRV_CRYPTO_DIRECTION_ENCRYPT); + return cc_cipher_process(req, DRV_CRYPTO_DIRECTION_ENCRYPT); } -static int ssi_ablkcipher_decrypt(struct ablkcipher_request *req) +static int cc_cipher_decrypt(struct ablkcipher_request *req) { struct crypto_ablkcipher *ablk_tfm = crypto_ablkcipher_reqtfm(req); - struct crypto_tfm *tfm = crypto_ablkcipher_tfm(ablk_tfm); struct blkcipher_req_ctx *req_ctx = ablkcipher_request_ctx(req); unsigned int ivsize = crypto_ablkcipher_ivsize(ablk_tfm); + gfp_t flags = cc_gfp_flags(&req->base); /* * Allocate and save the last IV sized bytes of the source, which will * be lost in case of in-place decryption and might be needed for CTS. */ - req_ctx->backup_info = kmalloc(ivsize, GFP_KERNEL); + req_ctx->backup_info = kmalloc(ivsize, flags); if (!req_ctx->backup_info) return -ENOMEM; @@ -909,22 +759,20 @@ static int ssi_ablkcipher_decrypt(struct ablkcipher_request *req) (req->nbytes - ivsize), ivsize, 0); req_ctx->is_giv = false; - return ssi_blkcipher_process(tfm, req_ctx, req->dst, req->src, req->nbytes, req->info, ivsize, (void *)req, DRV_CRYPTO_DIRECTION_DECRYPT); + return cc_cipher_process(req, DRV_CRYPTO_DIRECTION_DECRYPT); } /* DX Block cipher alg */ -static struct ssi_alg_template blkcipher_algs[] = { -/* Async template */ -#if SSI_CC_HAS_AES_XTS +static struct cc_alg_template blkcipher_algs[] = { { .name = "xts(aes)", .driver_name = "xts-aes-dx", .blocksize = AES_BLOCK_SIZE, .type = CRYPTO_ALG_TYPE_ABLKCIPHER, .template_ablkcipher = { - .setkey = ssi_ablkcipher_setkey, - .encrypt = ssi_ablkcipher_encrypt, - .decrypt = ssi_ablkcipher_decrypt, + .setkey = cc_cipher_setkey, + .encrypt = cc_cipher_encrypt, + .decrypt = cc_cipher_decrypt, .min_keysize = AES_MIN_KEY_SIZE * 2, .max_keysize = AES_MAX_KEY_SIZE * 2, .ivsize = AES_BLOCK_SIZE, @@ -939,9 +787,9 @@ static struct ssi_alg_template blkcipher_algs[] = { .blocksize = AES_BLOCK_SIZE, .type = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_BULK_DU_512, .template_ablkcipher = { - .setkey = ssi_ablkcipher_setkey, - .encrypt = ssi_ablkcipher_encrypt, - .decrypt = ssi_ablkcipher_decrypt, + .setkey = cc_cipher_setkey, + .encrypt = cc_cipher_encrypt, + .decrypt = cc_cipher_decrypt, .min_keysize = AES_MIN_KEY_SIZE * 2, .max_keysize = AES_MAX_KEY_SIZE * 2, .ivsize = AES_BLOCK_SIZE, @@ -955,9 +803,9 @@ static struct ssi_alg_template blkcipher_algs[] = { .blocksize = AES_BLOCK_SIZE, .type = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_BULK_DU_4096, .template_ablkcipher = { - .setkey = ssi_ablkcipher_setkey, - .encrypt = ssi_ablkcipher_encrypt, - .decrypt = ssi_ablkcipher_decrypt, + .setkey = cc_cipher_setkey, + .encrypt = cc_cipher_encrypt, + .decrypt = cc_cipher_decrypt, .min_keysize = AES_MIN_KEY_SIZE * 2, .max_keysize = AES_MAX_KEY_SIZE * 2, .ivsize = AES_BLOCK_SIZE, @@ -965,17 +813,15 @@ static struct ssi_alg_template blkcipher_algs[] = { .cipher_mode = DRV_CIPHER_XTS, .flow_mode = S_DIN_to_AES, }, -#endif /*SSI_CC_HAS_AES_XTS*/ -#if SSI_CC_HAS_AES_ESSIV { .name = "essiv(aes)", .driver_name = "essiv-aes-dx", .blocksize = AES_BLOCK_SIZE, .type = CRYPTO_ALG_TYPE_ABLKCIPHER, .template_ablkcipher = { - .setkey = ssi_ablkcipher_setkey, - .encrypt = ssi_ablkcipher_encrypt, - .decrypt = ssi_ablkcipher_decrypt, + .setkey = cc_cipher_setkey, + .encrypt = cc_cipher_encrypt, + .decrypt = cc_cipher_decrypt, .min_keysize = AES_MIN_KEY_SIZE * 2, .max_keysize = AES_MAX_KEY_SIZE * 2, .ivsize = AES_BLOCK_SIZE, @@ -989,9 +835,9 @@ static struct ssi_alg_template blkcipher_algs[] = { .blocksize = AES_BLOCK_SIZE, .type = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_BULK_DU_512, .template_ablkcipher = { - .setkey = ssi_ablkcipher_setkey, - .encrypt = ssi_ablkcipher_encrypt, - .decrypt = ssi_ablkcipher_decrypt, + .setkey = cc_cipher_setkey, + .encrypt = cc_cipher_encrypt, + .decrypt = cc_cipher_decrypt, .min_keysize = AES_MIN_KEY_SIZE * 2, .max_keysize = AES_MAX_KEY_SIZE * 2, .ivsize = AES_BLOCK_SIZE, @@ -1005,9 +851,9 @@ static struct ssi_alg_template blkcipher_algs[] = { .blocksize = AES_BLOCK_SIZE, .type = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_BULK_DU_4096, .template_ablkcipher = { - .setkey = ssi_ablkcipher_setkey, - .encrypt = ssi_ablkcipher_encrypt, - .decrypt = ssi_ablkcipher_decrypt, + .setkey = cc_cipher_setkey, + .encrypt = cc_cipher_encrypt, + .decrypt = cc_cipher_decrypt, .min_keysize = AES_MIN_KEY_SIZE * 2, .max_keysize = AES_MAX_KEY_SIZE * 2, .ivsize = AES_BLOCK_SIZE, @@ -1015,17 +861,15 @@ static struct ssi_alg_template blkcipher_algs[] = { .cipher_mode = DRV_CIPHER_ESSIV, .flow_mode = S_DIN_to_AES, }, -#endif /*SSI_CC_HAS_AES_ESSIV*/ -#if SSI_CC_HAS_AES_BITLOCKER { .name = "bitlocker(aes)", .driver_name = "bitlocker-aes-dx", .blocksize = AES_BLOCK_SIZE, .type = CRYPTO_ALG_TYPE_ABLKCIPHER, .template_ablkcipher = { - .setkey = ssi_ablkcipher_setkey, - .encrypt = ssi_ablkcipher_encrypt, - .decrypt = ssi_ablkcipher_decrypt, + .setkey = cc_cipher_setkey, + .encrypt = cc_cipher_encrypt, + .decrypt = cc_cipher_decrypt, .min_keysize = AES_MIN_KEY_SIZE * 2, .max_keysize = AES_MAX_KEY_SIZE * 2, .ivsize = AES_BLOCK_SIZE, @@ -1039,9 +883,9 @@ static struct ssi_alg_template blkcipher_algs[] = { .blocksize = AES_BLOCK_SIZE, .type = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_BULK_DU_512, .template_ablkcipher = { - .setkey = ssi_ablkcipher_setkey, - .encrypt = ssi_ablkcipher_encrypt, - .decrypt = ssi_ablkcipher_decrypt, + .setkey = cc_cipher_setkey, + .encrypt = cc_cipher_encrypt, + .decrypt = cc_cipher_decrypt, .min_keysize = AES_MIN_KEY_SIZE * 2, .max_keysize = AES_MAX_KEY_SIZE * 2, .ivsize = AES_BLOCK_SIZE, @@ -1055,9 +899,9 @@ static struct ssi_alg_template blkcipher_algs[] = { .blocksize = AES_BLOCK_SIZE, .type = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_BULK_DU_4096, .template_ablkcipher = { - .setkey = ssi_ablkcipher_setkey, - .encrypt = ssi_ablkcipher_encrypt, - .decrypt = ssi_ablkcipher_decrypt, + .setkey = cc_cipher_setkey, + .encrypt = cc_cipher_encrypt, + .decrypt = cc_cipher_decrypt, .min_keysize = AES_MIN_KEY_SIZE * 2, .max_keysize = AES_MAX_KEY_SIZE * 2, .ivsize = AES_BLOCK_SIZE, @@ -1065,16 +909,15 @@ static struct ssi_alg_template blkcipher_algs[] = { .cipher_mode = DRV_CIPHER_BITLOCKER, .flow_mode = S_DIN_to_AES, }, -#endif /*SSI_CC_HAS_AES_BITLOCKER*/ { .name = "ecb(aes)", .driver_name = "ecb-aes-dx", .blocksize = AES_BLOCK_SIZE, .type = CRYPTO_ALG_TYPE_ABLKCIPHER, .template_ablkcipher = { - .setkey = ssi_ablkcipher_setkey, - .encrypt = ssi_ablkcipher_encrypt, - .decrypt = ssi_ablkcipher_decrypt, + .setkey = cc_cipher_setkey, + .encrypt = cc_cipher_encrypt, + .decrypt = cc_cipher_decrypt, .min_keysize = AES_MIN_KEY_SIZE, .max_keysize = AES_MAX_KEY_SIZE, .ivsize = 0, @@ -1088,9 +931,9 @@ static struct ssi_alg_template blkcipher_algs[] = { .blocksize = AES_BLOCK_SIZE, .type = CRYPTO_ALG_TYPE_ABLKCIPHER, .template_ablkcipher = { - .setkey = ssi_ablkcipher_setkey, - .encrypt = ssi_ablkcipher_encrypt, - .decrypt = ssi_ablkcipher_decrypt, + .setkey = cc_cipher_setkey, + .encrypt = cc_cipher_encrypt, + .decrypt = cc_cipher_decrypt, .min_keysize = AES_MIN_KEY_SIZE, .max_keysize = AES_MAX_KEY_SIZE, .ivsize = AES_BLOCK_SIZE, @@ -1104,9 +947,9 @@ static struct ssi_alg_template blkcipher_algs[] = { .blocksize = AES_BLOCK_SIZE, .type = CRYPTO_ALG_TYPE_ABLKCIPHER, .template_ablkcipher = { - .setkey = ssi_ablkcipher_setkey, - .encrypt = ssi_ablkcipher_encrypt, - .decrypt = ssi_ablkcipher_decrypt, + .setkey = cc_cipher_setkey, + .encrypt = cc_cipher_encrypt, + .decrypt = cc_cipher_decrypt, .min_keysize = AES_MIN_KEY_SIZE, .max_keysize = AES_MAX_KEY_SIZE, .ivsize = AES_BLOCK_SIZE, @@ -1114,16 +957,15 @@ static struct ssi_alg_template blkcipher_algs[] = { .cipher_mode = DRV_CIPHER_OFB, .flow_mode = S_DIN_to_AES, }, -#if SSI_CC_HAS_AES_CTS { .name = "cts1(cbc(aes))", .driver_name = "cts1-cbc-aes-dx", .blocksize = AES_BLOCK_SIZE, .type = CRYPTO_ALG_TYPE_ABLKCIPHER, .template_ablkcipher = { - .setkey = ssi_ablkcipher_setkey, - .encrypt = ssi_ablkcipher_encrypt, - .decrypt = ssi_ablkcipher_decrypt, + .setkey = cc_cipher_setkey, + .encrypt = cc_cipher_encrypt, + .decrypt = cc_cipher_decrypt, .min_keysize = AES_MIN_KEY_SIZE, .max_keysize = AES_MAX_KEY_SIZE, .ivsize = AES_BLOCK_SIZE, @@ -1131,16 +973,15 @@ static struct ssi_alg_template blkcipher_algs[] = { .cipher_mode = DRV_CIPHER_CBC_CTS, .flow_mode = S_DIN_to_AES, }, -#endif { .name = "ctr(aes)", .driver_name = "ctr-aes-dx", .blocksize = 1, .type = CRYPTO_ALG_TYPE_ABLKCIPHER, .template_ablkcipher = { - .setkey = ssi_ablkcipher_setkey, - .encrypt = ssi_ablkcipher_encrypt, - .decrypt = ssi_ablkcipher_decrypt, + .setkey = cc_cipher_setkey, + .encrypt = cc_cipher_encrypt, + .decrypt = cc_cipher_decrypt, .min_keysize = AES_MIN_KEY_SIZE, .max_keysize = AES_MAX_KEY_SIZE, .ivsize = AES_BLOCK_SIZE, @@ -1154,9 +995,9 @@ static struct ssi_alg_template blkcipher_algs[] = { .blocksize = DES3_EDE_BLOCK_SIZE, .type = CRYPTO_ALG_TYPE_ABLKCIPHER, .template_ablkcipher = { - .setkey = ssi_ablkcipher_setkey, - .encrypt = ssi_ablkcipher_encrypt, - .decrypt = ssi_ablkcipher_decrypt, + .setkey = cc_cipher_setkey, + .encrypt = cc_cipher_encrypt, + .decrypt = cc_cipher_decrypt, .min_keysize = DES3_EDE_KEY_SIZE, .max_keysize = DES3_EDE_KEY_SIZE, .ivsize = DES3_EDE_BLOCK_SIZE, @@ -1170,9 +1011,9 @@ static struct ssi_alg_template blkcipher_algs[] = { .blocksize = DES3_EDE_BLOCK_SIZE, .type = CRYPTO_ALG_TYPE_ABLKCIPHER, .template_ablkcipher = { - .setkey = ssi_ablkcipher_setkey, - .encrypt = ssi_ablkcipher_encrypt, - .decrypt = ssi_ablkcipher_decrypt, + .setkey = cc_cipher_setkey, + .encrypt = cc_cipher_encrypt, + .decrypt = cc_cipher_decrypt, .min_keysize = DES3_EDE_KEY_SIZE, .max_keysize = DES3_EDE_KEY_SIZE, .ivsize = 0, @@ -1186,9 +1027,9 @@ static struct ssi_alg_template blkcipher_algs[] = { .blocksize = DES_BLOCK_SIZE, .type = CRYPTO_ALG_TYPE_ABLKCIPHER, .template_ablkcipher = { - .setkey = ssi_ablkcipher_setkey, - .encrypt = ssi_ablkcipher_encrypt, - .decrypt = ssi_ablkcipher_decrypt, + .setkey = cc_cipher_setkey, + .encrypt = cc_cipher_encrypt, + .decrypt = cc_cipher_decrypt, .min_keysize = DES_KEY_SIZE, .max_keysize = DES_KEY_SIZE, .ivsize = DES_BLOCK_SIZE, @@ -1202,9 +1043,9 @@ static struct ssi_alg_template blkcipher_algs[] = { .blocksize = DES_BLOCK_SIZE, .type = CRYPTO_ALG_TYPE_ABLKCIPHER, .template_ablkcipher = { - .setkey = ssi_ablkcipher_setkey, - .encrypt = ssi_ablkcipher_encrypt, - .decrypt = ssi_ablkcipher_decrypt, + .setkey = cc_cipher_setkey, + .encrypt = cc_cipher_encrypt, + .decrypt = cc_cipher_decrypt, .min_keysize = DES_KEY_SIZE, .max_keysize = DES_KEY_SIZE, .ivsize = 0, @@ -1212,47 +1053,13 @@ static struct ssi_alg_template blkcipher_algs[] = { .cipher_mode = DRV_CIPHER_ECB, .flow_mode = S_DIN_to_DES, }, -#if SSI_CC_HAS_MULTI2 - { - .name = "cbc(multi2)", - .driver_name = "cbc-multi2-dx", - .blocksize = CC_MULTI2_BLOCK_SIZE, - .type = CRYPTO_ALG_TYPE_ABLKCIPHER, - .template_ablkcipher = { - .setkey = ssi_ablkcipher_setkey, - .encrypt = ssi_ablkcipher_encrypt, - .decrypt = ssi_ablkcipher_decrypt, - .min_keysize = CC_MULTI2_SYSTEM_N_DATA_KEY_SIZE + 1, - .max_keysize = CC_MULTI2_SYSTEM_N_DATA_KEY_SIZE + 1, - .ivsize = CC_MULTI2_IV_SIZE, - }, - .cipher_mode = DRV_MULTI2_CBC, - .flow_mode = S_DIN_to_MULTI2, - }, - { - .name = "ofb(multi2)", - .driver_name = "ofb-multi2-dx", - .blocksize = 1, - .type = CRYPTO_ALG_TYPE_ABLKCIPHER, - .template_ablkcipher = { - .setkey = ssi_ablkcipher_setkey, - .encrypt = ssi_ablkcipher_encrypt, - .decrypt = ssi_ablkcipher_encrypt, - .min_keysize = CC_MULTI2_SYSTEM_N_DATA_KEY_SIZE + 1, - .max_keysize = CC_MULTI2_SYSTEM_N_DATA_KEY_SIZE + 1, - .ivsize = CC_MULTI2_IV_SIZE, - }, - .cipher_mode = DRV_MULTI2_OFB, - .flow_mode = S_DIN_to_MULTI2, - }, -#endif /*SSI_CC_HAS_MULTI2*/ }; static -struct ssi_crypto_alg *ssi_ablkcipher_create_alg(struct ssi_alg_template - *template, struct device *dev) +struct cc_crypto_alg *cc_cipher_create_alg(struct cc_alg_template *template, + struct device *dev) { - struct ssi_crypto_alg *t_alg; + struct cc_crypto_alg *t_alg; struct crypto_alg *alg; t_alg = kzalloc(sizeof(*t_alg), GFP_KERNEL); @@ -1265,13 +1072,13 @@ struct ssi_crypto_alg *ssi_ablkcipher_create_alg(struct ssi_alg_template snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", template->driver_name); alg->cra_module = THIS_MODULE; - alg->cra_priority = SSI_CRA_PRIO; + alg->cra_priority = CC_CRA_PRIO; alg->cra_blocksize = template->blocksize; alg->cra_alignmask = 0; - alg->cra_ctxsize = sizeof(struct ssi_ablkcipher_ctx); + alg->cra_ctxsize = sizeof(struct cc_cipher_ctx); - alg->cra_init = ssi_ablkcipher_init; - alg->cra_exit = ssi_blkcipher_exit; + alg->cra_init = cc_cipher_init; + alg->cra_exit = cc_cipher_exit; alg->cra_type = &crypto_ablkcipher_type; alg->cra_ablkcipher = template->template_ablkcipher; alg->cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY | @@ -1283,11 +1090,11 @@ struct ssi_crypto_alg *ssi_ablkcipher_create_alg(struct ssi_alg_template return t_alg; } -int ssi_ablkcipher_free(struct ssi_drvdata *drvdata) +int cc_cipher_free(struct cc_drvdata *drvdata) { - struct ssi_crypto_alg *t_alg, *n; - struct ssi_blkcipher_handle *blkcipher_handle = - drvdata->blkcipher_handle; + struct cc_crypto_alg *t_alg, *n; + struct cc_cipher_handle *blkcipher_handle = drvdata->blkcipher_handle; + if (blkcipher_handle) { /* Remove registered algs */ list_for_each_entry_safe(t_alg, n, @@ -1303,10 +1110,10 @@ int ssi_ablkcipher_free(struct ssi_drvdata *drvdata) return 0; } -int ssi_ablkcipher_alloc(struct ssi_drvdata *drvdata) +int cc_cipher_alloc(struct cc_drvdata *drvdata) { - struct ssi_blkcipher_handle *ablkcipher_handle; - struct ssi_crypto_alg *t_alg; + struct cc_cipher_handle *ablkcipher_handle; + struct cc_crypto_alg *t_alg; struct device *dev = drvdata_to_dev(drvdata); int rc = -ENOMEM; int alg; @@ -1323,7 +1130,7 @@ int ssi_ablkcipher_alloc(struct ssi_drvdata *drvdata) ARRAY_SIZE(blkcipher_algs)); for (alg = 0; alg < ARRAY_SIZE(blkcipher_algs); alg++) { dev_dbg(dev, "creating %s\n", blkcipher_algs[alg].driver_name); - t_alg = ssi_ablkcipher_create_alg(&blkcipher_algs[alg], dev); + t_alg = cc_cipher_create_alg(&blkcipher_algs[alg], dev); if (IS_ERR(t_alg)) { rc = PTR_ERR(t_alg); dev_err(dev, "%s alg allocation failed\n", @@ -1337,7 +1144,7 @@ int ssi_ablkcipher_alloc(struct ssi_drvdata *drvdata) rc = crypto_register_alg(&t_alg->crypto_alg); dev_dbg(dev, "%s alg registration rc = %x\n", t_alg->crypto_alg.cra_driver_name, rc); - if (unlikely(rc != 0)) { + if (rc) { dev_err(dev, "%s alg registration failed\n", t_alg->crypto_alg.cra_driver_name); kfree(t_alg); @@ -1352,6 +1159,6 @@ int ssi_ablkcipher_alloc(struct ssi_drvdata *drvdata) return 0; fail0: - ssi_ablkcipher_free(drvdata); + cc_cipher_free(drvdata); return rc; } diff --git a/drivers/staging/ccree/cc_cipher.h b/drivers/staging/ccree/cc_cipher.h new file mode 100644 index 000000000000..4c181c721723 --- /dev/null +++ b/drivers/staging/ccree/cc_cipher.h @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ + +/* \file cc_cipher.h + * ARM CryptoCell Cipher Crypto API + */ + +#ifndef __CC_CIPHER_H__ +#define __CC_CIPHER_H__ + +#include <linux/kernel.h> +#include <crypto/algapi.h> +#include "cc_driver.h" +#include "cc_buffer_mgr.h" + +/* Crypto cipher flags */ +#define CC_CRYPTO_CIPHER_KEY_KFDE0 BIT(0) +#define CC_CRYPTO_CIPHER_KEY_KFDE1 BIT(1) +#define CC_CRYPTO_CIPHER_KEY_KFDE2 BIT(2) +#define CC_CRYPTO_CIPHER_KEY_KFDE3 BIT(3) +#define CC_CRYPTO_CIPHER_DU_SIZE_512B BIT(4) + +#define CC_CRYPTO_CIPHER_KEY_KFDE_MASK (CC_CRYPTO_CIPHER_KEY_KFDE0 | \ + CC_CRYPTO_CIPHER_KEY_KFDE1 | \ + CC_CRYPTO_CIPHER_KEY_KFDE2 | \ + CC_CRYPTO_CIPHER_KEY_KFDE3) + +struct blkcipher_req_ctx { + struct async_gen_req_ctx gen_ctx; + enum cc_req_dma_buf_type dma_buf_type; + u32 in_nents; + u32 in_mlli_nents; + u32 out_nents; + u32 out_mlli_nents; + u8 *backup_info; /*store iv for generated IV flow*/ + u8 *iv; + bool is_giv; + struct mlli_params mlli_params; +}; + +int cc_cipher_alloc(struct cc_drvdata *drvdata); + +int cc_cipher_free(struct cc_drvdata *drvdata); + +#ifndef CRYPTO_ALG_BULK_MASK + +#define CRYPTO_ALG_BULK_DU_512 0x00002000 +#define CRYPTO_ALG_BULK_DU_4096 0x00004000 +#define CRYPTO_ALG_BULK_MASK (CRYPTO_ALG_BULK_DU_512 |\ + CRYPTO_ALG_BULK_DU_4096) +#endif /* CRYPTO_ALG_BULK_MASK */ + +#ifdef CRYPTO_TFM_REQ_HW_KEY + +static inline bool cc_is_hw_key(struct crypto_tfm *tfm) +{ + return (crypto_tfm_get_flags(tfm) & CRYPTO_TFM_REQ_HW_KEY); +} + +#else + +struct arm_hw_key_info { + int hw_key1; + int hw_key2; +}; + +static inline bool cc_is_hw_key(struct crypto_tfm *tfm) +{ + return false; +} + +#endif /* CRYPTO_TFM_REQ_HW_KEY */ + +#endif /*__CC_CIPHER_H__*/ diff --git a/drivers/staging/ccree/cc_crypto_ctx.h b/drivers/staging/ccree/cc_crypto_ctx.h index 591f6fdadc59..eb16842d7db9 100644 --- a/drivers/staging/ccree/cc_crypto_ctx.h +++ b/drivers/staging/ccree/cc_crypto_ctx.h @@ -1,18 +1,5 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ #ifndef _CC_CRYPTO_CTX_H_ #define _CC_CRYPTO_CTX_H_ @@ -21,7 +8,7 @@ /* context size */ #ifndef CC_CTX_SIZE_LOG2 -#if (CC_SUPPORT_SHA > 256) +#if (CC_DEV_SHA_MAX > 256) #define CC_CTX_SIZE_LOG2 8 #else #define CC_CTX_SIZE_LOG2 7 @@ -72,7 +59,7 @@ #define CC_SHA384_BLOCK_SIZE 128 #define CC_SHA512_BLOCK_SIZE 128 -#if (CC_SUPPORT_SHA > 256) +#if (CC_DEV_SHA_MAX > 256) #define CC_DIGEST_SIZE_MAX CC_SHA512_DIGEST_SIZE #define CC_HASH_BLOCK_SIZE_MAX CC_SHA512_BLOCK_SIZE /*1024b*/ #else /* Only up to SHA256 */ @@ -82,15 +69,6 @@ #define CC_HMAC_BLOCK_SIZE_MAX CC_HASH_BLOCK_SIZE_MAX -#define CC_MULTI2_SYSTEM_KEY_SIZE 32 -#define CC_MULTI2_DATA_KEY_SIZE 8 -#define CC_MULTI2_SYSTEM_N_DATA_KEY_SIZE \ - (CC_MULTI2_SYSTEM_KEY_SIZE + CC_MULTI2_DATA_KEY_SIZE) -#define CC_MULTI2_BLOCK_SIZE 8 -#define CC_MULTI2_IV_SIZE 8 -#define CC_MULTI2_MIN_NUM_ROUNDS 8 -#define CC_MULTI2_MAX_NUM_ROUNDS 128 - #define CC_DRV_ALG_MAX_BLOCK_SIZE CC_HASH_BLOCK_SIZE_MAX enum drv_engine_type { @@ -168,14 +146,6 @@ enum drv_hash_hw_mode { DRV_HASH_HW_RESERVE32B = S32_MAX }; -enum drv_multi2_mode { - DRV_MULTI2_NULL = -1, - DRV_MULTI2_ECB = 0, - DRV_MULTI2_CBC = 1, - DRV_MULTI2_OFB = 2, - DRV_MULTI2_RESERVE32B = S32_MAX -}; - /* drv_crypto_key_type[1:0] is mapped to cipher_do[1:0] */ /* drv_crypto_key_type[2] is mapped to cipher_config2 */ enum drv_crypto_key_type { diff --git a/drivers/staging/ccree/cc_debugfs.c b/drivers/staging/ccree/cc_debugfs.c new file mode 100644 index 000000000000..08f8db489cf0 --- /dev/null +++ b/drivers/staging/ccree/cc_debugfs.c @@ -0,0 +1,101 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ + +#include <linux/kernel.h> +#include <linux/debugfs.h> +#include <linux/stringify.h> +#include "cc_driver.h" +#include "cc_crypto_ctx.h" +#include "cc_debugfs.h" + +struct cc_debugfs_ctx { + struct dentry *dir; +}; + +#define CC_DEBUG_REG(_X) { \ + .name = __stringify(_X),\ + .offset = CC_REG(_X) \ + } + +/* + * This is a global var for the dentry of the + * debugfs ccree/ dir. It is not tied down to + * a specific instance of ccree, hence it is + * global. + */ +static struct dentry *cc_debugfs_dir; + +static struct debugfs_reg32 debug_regs[] = { + CC_DEBUG_REG(HOST_SIGNATURE), + CC_DEBUG_REG(HOST_IRR), + CC_DEBUG_REG(HOST_POWER_DOWN_EN), + CC_DEBUG_REG(AXIM_MON_ERR), + CC_DEBUG_REG(DSCRPTR_QUEUE_CONTENT), + CC_DEBUG_REG(HOST_IMR), + CC_DEBUG_REG(AXIM_CFG), + CC_DEBUG_REG(AXIM_CACHE_PARAMS), + CC_DEBUG_REG(HOST_VERSION), + CC_DEBUG_REG(GPR_HOST), + CC_DEBUG_REG(AXIM_MON_COMP), +}; + +int __init cc_debugfs_global_init(void) +{ + cc_debugfs_dir = debugfs_create_dir("ccree", NULL); + + return !cc_debugfs_dir; +} + +void __exit cc_debugfs_global_fini(void) +{ + debugfs_remove(cc_debugfs_dir); +} + +int cc_debugfs_init(struct cc_drvdata *drvdata) +{ + struct device *dev = drvdata_to_dev(drvdata); + struct cc_debugfs_ctx *ctx; + struct debugfs_regset32 *regset; + struct dentry *file; + + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + regset = devm_kzalloc(dev, sizeof(*regset), GFP_KERNEL); + if (!regset) + return -ENOMEM; + + regset->regs = debug_regs; + regset->nregs = ARRAY_SIZE(debug_regs); + regset->base = drvdata->cc_base; + + ctx->dir = debugfs_create_dir(drvdata->plat_dev->name, cc_debugfs_dir); + if (!ctx->dir) + return -ENFILE; + + file = debugfs_create_regset32("regs", 0400, ctx->dir, regset); + if (!file) { + debugfs_remove(ctx->dir); + return -ENFILE; + } + + file = debugfs_create_bool("coherent", 0400, ctx->dir, + &drvdata->coherent); + + if (!file) { + debugfs_remove_recursive(ctx->dir); + return -ENFILE; + } + + drvdata->debugfs = ctx; + + return 0; +} + +void cc_debugfs_fini(struct cc_drvdata *drvdata) +{ + struct cc_debugfs_ctx *ctx = (struct cc_debugfs_ctx *)drvdata->debugfs; + + debugfs_remove_recursive(ctx->dir); +} diff --git a/drivers/staging/ccree/cc_debugfs.h b/drivers/staging/ccree/cc_debugfs.h new file mode 100644 index 000000000000..5b5320eca7d2 --- /dev/null +++ b/drivers/staging/ccree/cc_debugfs.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ + +#ifndef __CC_DEBUGFS_H__ +#define __CC_DEBUGFS_H__ + +#ifdef CONFIG_DEBUG_FS +int cc_debugfs_global_init(void); +void cc_debugfs_global_fini(void); + +int cc_debugfs_init(struct cc_drvdata *drvdata); +void cc_debugfs_fini(struct cc_drvdata *drvdata); + +#else + +static inline int cc_debugfs_global_init(void) +{ + return 0; +} + +static inline void cc_debugfs_global_fini(void) {} + +static inline int cc_debugfs_init(struct cc_drvdata *drvdata) +{ + return 0; +} + +static inline void cc_debugfs_fini(struct cc_drvdata *drvdata) {} + +#endif + +#endif /*__CC_SYSFS_H__*/ diff --git a/drivers/staging/ccree/ssi_driver.c b/drivers/staging/ccree/cc_driver.c index 1a3c481fa92a..3a1cb0c98648 100644 --- a/drivers/staging/ccree/ssi_driver.c +++ b/drivers/staging/ccree/cc_driver.c @@ -1,96 +1,56 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ #include <linux/kernel.h> #include <linux/module.h> #include <linux/crypto.h> -#include <crypto/algapi.h> -#include <crypto/aes.h> -#include <crypto/sha.h> -#include <crypto/aead.h> -#include <crypto/authenc.h> -#include <crypto/scatterwalk.h> -#include <crypto/internal/skcipher.h> - -#include <linux/init.h> #include <linux/moduleparam.h> #include <linux/types.h> -#include <linux/random.h> -#include <linux/ioport.h> #include <linux/interrupt.h> -#include <linux/fcntl.h> -#include <linux/poll.h> -#include <linux/proc_fs.h> -#include <linux/mutex.h> -#include <linux/sysctl.h> -#include <linux/fs.h> -#include <linux/cdev.h> #include <linux/platform_device.h> -#include <linux/mm.h> -#include <linux/delay.h> -#include <linux/dma-mapping.h> -#include <linux/dmapool.h> -#include <linux/list.h> #include <linux/slab.h> #include <linux/spinlock.h> -#include <linux/pm.h> - -/* cache.h required for L1_CACHE_ALIGN() and cache_line_size() */ -#include <linux/cache.h> -#include <linux/io.h> -#include <linux/uaccess.h> -#include <linux/pagemap.h> -#include <linux/sched.h> -#include <linux/random.h> #include <linux/of.h> #include <linux/clk.h> #include <linux/of_address.h> -#include "ssi_config.h" -#include "ssi_driver.h" -#include "ssi_request_mgr.h" -#include "ssi_buffer_mgr.h" -#include "ssi_sysfs.h" -#include "ssi_cipher.h" -#include "ssi_aead.h" -#include "ssi_hash.h" -#include "ssi_ivgen.h" -#include "ssi_sram_mgr.h" -#include "ssi_pm.h" -#include "ssi_fips.h" - -#ifdef DX_DUMP_BYTES -void dump_byte_array(const char *name, const u8 *buf, size_t len) +#include "cc_driver.h" +#include "cc_request_mgr.h" +#include "cc_buffer_mgr.h" +#include "cc_debugfs.h" +#include "cc_cipher.h" +#include "cc_aead.h" +#include "cc_hash.h" +#include "cc_ivgen.h" +#include "cc_sram_mgr.h" +#include "cc_pm.h" +#include "cc_fips.h" + +bool cc_dump_desc; +module_param_named(dump_desc, cc_dump_desc, bool, 0600); +MODULE_PARM_DESC(cc_dump_desc, "Dump descriptors to kernel log as debugging aid"); + +bool cc_dump_bytes; +module_param_named(dump_bytes, cc_dump_bytes, bool, 0600); +MODULE_PARM_DESC(cc_dump_bytes, "Dump buffers to kernel log as debugging aid"); + +void __dump_byte_array(const char *name, const u8 *buf, size_t len) { - char prefix[NAME_LEN]; + char prefix[64]; if (!buf) return; - snprintf(prefix, sizeof(prefix), "%s[%lu]: ", name, len); + snprintf(prefix, sizeof(prefix), "%s[%zu]: ", name, len); - print_hex_dump(KERN_DEBUG, prefix, DUMP_PREFIX_ADDRESS, 16, 1, len, - false); + print_hex_dump(KERN_DEBUG, prefix, DUMP_PREFIX_ADDRESS, 16, 1, buf, + len, false); } -#endif static irqreturn_t cc_isr(int irq, void *dev_id) { - struct ssi_drvdata *drvdata = (struct ssi_drvdata *)dev_id; + struct cc_drvdata *drvdata = (struct cc_drvdata *)dev_id; struct device *dev = drvdata_to_dev(drvdata); u32 irr; u32 imr; @@ -100,7 +60,7 @@ static irqreturn_t cc_isr(int irq, void *dev_id) /* read the interrupt status */ irr = cc_ioread(drvdata, CC_REG(HOST_IRR)); dev_dbg(dev, "Got IRR=0x%08X\n", irr); - if (unlikely(irr == 0)) { /* Probably shared interrupt line */ + if (irr == 0) { /* Probably shared interrupt line */ dev_err(dev, "Got interrupt with empty IRR\n"); return IRQ_NONE; } @@ -111,23 +71,27 @@ static irqreturn_t cc_isr(int irq, void *dev_id) drvdata->irq = irr; /* Completion interrupt - most probable */ - if (likely((irr & SSI_COMP_IRQ_MASK) != 0)) { - /* Mask AXI completion interrupt - will be unmasked in Deferred service handler */ - cc_iowrite(drvdata, CC_REG(HOST_IMR), imr | SSI_COMP_IRQ_MASK); - irr &= ~SSI_COMP_IRQ_MASK; + if (irr & CC_COMP_IRQ_MASK) { + /* Mask AXI completion interrupt - will be unmasked in + * Deferred service handler + */ + cc_iowrite(drvdata, CC_REG(HOST_IMR), imr | CC_COMP_IRQ_MASK); + irr &= ~CC_COMP_IRQ_MASK; complete_request(drvdata); } -#ifdef CC_SUPPORT_FIPS +#ifdef CONFIG_CRYPTO_FIPS /* TEE FIPS interrupt */ - if (likely((irr & SSI_GPR0_IRQ_MASK) != 0)) { - /* Mask interrupt - will be unmasked in Deferred service handler */ - cc_iowrite(drvdata, CC_REG(HOST_IMR), imr | SSI_GPR0_IRQ_MASK); - irr &= ~SSI_GPR0_IRQ_MASK; + if (irr & CC_GPR0_IRQ_MASK) { + /* Mask interrupt - will be unmasked in Deferred service + * handler + */ + cc_iowrite(drvdata, CC_REG(HOST_IMR), imr | CC_GPR0_IRQ_MASK); + irr &= ~CC_GPR0_IRQ_MASK; fips_handler(drvdata); } #endif /* AXI error interrupt */ - if (unlikely((irr & SSI_AXI_ERR_IRQ_MASK) != 0)) { + if (irr & CC_AXI_ERR_IRQ_MASK) { u32 axi_err; /* Read the AXI error ID */ @@ -135,10 +99,10 @@ static irqreturn_t cc_isr(int irq, void *dev_id) dev_dbg(dev, "AXI completion error: axim_mon_err=0x%08X\n", axi_err); - irr &= ~SSI_AXI_ERR_IRQ_MASK; + irr &= ~CC_AXI_ERR_IRQ_MASK; } - if (unlikely(irr != 0)) { + if (irr) { dev_dbg(dev, "IRR includes unknown cause bits (0x%08X)\n", irr); /* Just warning */ @@ -147,14 +111,14 @@ static irqreturn_t cc_isr(int irq, void *dev_id) return IRQ_HANDLED; } -int init_cc_regs(struct ssi_drvdata *drvdata, bool is_probe) +int init_cc_regs(struct cc_drvdata *drvdata, bool is_probe) { unsigned int val, cache_params; struct device *dev = drvdata_to_dev(drvdata); /* Unmask all AXI interrupt sources AXI_CFG1 register */ val = cc_ioread(drvdata, CC_REG(AXIM_CFG)); - cc_iowrite(drvdata, CC_REG(AXIM_CFG), val & ~SSI_AXI_IRQ_MASK); + cc_iowrite(drvdata, CC_REG(AXIM_CFG), val & ~CC_AXI_IRQ_MASK); dev_dbg(dev, "AXIM_CFG=0x%08X\n", cc_ioread(drvdata, CC_REG(AXIM_CFG))); @@ -164,21 +128,10 @@ int init_cc_regs(struct ssi_drvdata *drvdata, bool is_probe) cc_iowrite(drvdata, CC_REG(HOST_ICR), val); /* Unmask relevant interrupt cause */ - val = (unsigned int)(~(SSI_COMP_IRQ_MASK | SSI_AXI_ERR_IRQ_MASK | - SSI_GPR0_IRQ_MASK)); + val = (unsigned int)(~(CC_COMP_IRQ_MASK | CC_AXI_ERR_IRQ_MASK | + CC_GPR0_IRQ_MASK)); cc_iowrite(drvdata, CC_REG(HOST_IMR), val); -#ifdef DX_HOST_IRQ_TIMER_INIT_VAL_REG_OFFSET -#ifdef DX_IRQ_DELAY - /* Set CC IRQ delay */ - cc_iowrite(drvdata, CC_REG(HOST_IRQ_TIMER_INIT_VAL), DX_IRQ_DELAY); -#endif - if (cc_ioread(drvdata, CC_REG(HOST_IRQ_TIMER_INIT_VAL)) > 0) { - dev_dbg(dev, "irq_delay=%d CC cycles\n", - cc_ioread(drvdata, CC_REG(HOST_IRQ_TIMER_INIT_VAL))); - } -#endif - cache_params = (drvdata->coherent ? CC_COHERENT_CACHE_PARAMS : 0x0); val = cc_ioread(drvdata, CC_REG(AXIM_CACHE_PARAMS)); @@ -199,12 +152,11 @@ int init_cc_regs(struct ssi_drvdata *drvdata, bool is_probe) static int init_cc_resources(struct platform_device *plat_dev) { struct resource *req_mem_cc_regs = NULL; - void __iomem *cc_base = NULL; - struct ssi_drvdata *new_drvdata; + struct cc_drvdata *new_drvdata; struct device *dev = &plat_dev->dev; struct device_node *np = dev->of_node; u32 signature_val; - dma_addr_t dma_mask; + u64 dma_mask; int rc = 0; new_drvdata = devm_kzalloc(dev, sizeof(*new_drvdata), GFP_KERNEL); @@ -222,18 +174,14 @@ static int init_cc_resources(struct platform_device *plat_dev) req_mem_cc_regs = platform_get_resource(plat_dev, IORESOURCE_MEM, 0); /* Map registers space */ new_drvdata->cc_base = devm_ioremap_resource(dev, req_mem_cc_regs); - if (IS_ERR(new_drvdata->cc_base)) { - dev_err(dev, "Failed to ioremap registers"); + if (IS_ERR(new_drvdata->cc_base)) return PTR_ERR(new_drvdata->cc_base); - } dev_dbg(dev, "Got MEM resource (%s): %pR\n", req_mem_cc_regs->name, req_mem_cc_regs); dev_dbg(dev, "CC registers mapped from %pa to 0x%p\n", &req_mem_cc_regs->start, new_drvdata->cc_base); - cc_base = new_drvdata->cc_base; - /* Then IRQ */ new_drvdata->irq = platform_get_irq(plat_dev, 0); if (new_drvdata->irq < 0) { @@ -250,10 +198,12 @@ static int init_cc_resources(struct platform_device *plat_dev) } dev_dbg(dev, "Registered to IRQ: %d\n", new_drvdata->irq); + init_completion(&new_drvdata->hw_queue_avail); + if (!plat_dev->dev.dma_mask) plat_dev->dev.dma_mask = &plat_dev->dev.coherent_dma_mask; - dma_mask = (dma_addr_t)(DMA_BIT_MASK(DMA_BIT_MASK_LEN)); + dma_mask = DMA_BIT_MASK(DMA_BIT_MASK_LEN); while (dma_mask > 0x7fffffffUL) { if (dma_supported(&plat_dev->dev, dma_mask)) { rc = dma_set_coherent_mask(&plat_dev->dev, dma_mask); @@ -264,8 +214,7 @@ static int init_cc_resources(struct platform_device *plat_dev) } if (rc) { - dev_err(dev, "Failed in dma_set_mask, mask=%par\n", - &dma_mask); + dev_err(dev, "Failed in dma_set_mask, mask=%par\n", &dma_mask); return rc; } @@ -277,9 +226,9 @@ static int init_cc_resources(struct platform_device *plat_dev) /* Verify correct mapping */ signature_val = cc_ioread(new_drvdata, CC_REG(HOST_SIGNATURE)); - if (signature_val != DX_DEV_SIGNATURE) { + if (signature_val != CC_DEV_SIGNATURE) { dev_err(dev, "Invalid CC signature: SIGNATURE=0x%08X != expected=0x%08X\n", - signature_val, (u32)DX_DEV_SIGNATURE); + signature_val, (u32)CC_DEV_SIGNATURE); rc = -EINVAL; goto post_clk_err; } @@ -287,84 +236,82 @@ static int init_cc_resources(struct platform_device *plat_dev) /* Display HW versions */ dev_info(dev, "ARM CryptoCell %s Driver: HW version 0x%08X, Driver version %s\n", - SSI_DEV_NAME_STR, + CC_DEV_NAME_STR, cc_ioread(new_drvdata, CC_REG(HOST_VERSION)), DRV_MODULE_VERSION); rc = init_cc_regs(new_drvdata, true); - if (unlikely(rc != 0)) { + if (rc) { dev_err(dev, "init_cc_regs failed\n"); goto post_clk_err; } -#ifdef ENABLE_CC_SYSFS - rc = ssi_sysfs_init(&dev->kobj, new_drvdata); - if (unlikely(rc != 0)) { - dev_err(dev, "init_stat_db failed\n"); + rc = cc_debugfs_init(new_drvdata); + if (rc) { + dev_err(dev, "Failed registering debugfs interface\n"); goto post_regs_err; } -#endif - rc = ssi_fips_init(new_drvdata); - if (unlikely(rc != 0)) { - dev_err(dev, "SSI_FIPS_INIT failed 0x%x\n", rc); - goto post_sysfs_err; + rc = cc_fips_init(new_drvdata); + if (rc) { + dev_err(dev, "CC_FIPS_INIT failed 0x%x\n", rc); + goto post_debugfs_err; } - rc = ssi_sram_mgr_init(new_drvdata); - if (unlikely(rc != 0)) { - dev_err(dev, "ssi_sram_mgr_init failed\n"); + rc = cc_sram_mgr_init(new_drvdata); + if (rc) { + dev_err(dev, "cc_sram_mgr_init failed\n"); goto post_fips_init_err; } new_drvdata->mlli_sram_addr = - ssi_sram_mgr_alloc(new_drvdata, MAX_MLLI_BUFF_SIZE); - if (unlikely(new_drvdata->mlli_sram_addr == NULL_SRAM_ADDR)) { + cc_sram_alloc(new_drvdata, MAX_MLLI_BUFF_SIZE); + if (new_drvdata->mlli_sram_addr == NULL_SRAM_ADDR) { dev_err(dev, "Failed to alloc MLLI Sram buffer\n"); rc = -ENOMEM; goto post_sram_mgr_err; } - rc = request_mgr_init(new_drvdata); - if (unlikely(rc != 0)) { - dev_err(dev, "request_mgr_init failed\n"); + rc = cc_req_mgr_init(new_drvdata); + if (rc) { + dev_err(dev, "cc_req_mgr_init failed\n"); goto post_sram_mgr_err; } - rc = ssi_buffer_mgr_init(new_drvdata); - if (unlikely(rc != 0)) { + rc = cc_buffer_mgr_init(new_drvdata); + if (rc) { dev_err(dev, "buffer_mgr_init failed\n"); goto post_req_mgr_err; } - rc = ssi_power_mgr_init(new_drvdata); - if (unlikely(rc != 0)) { + rc = cc_pm_init(new_drvdata); + if (rc) { dev_err(dev, "ssi_power_mgr_init failed\n"); goto post_buf_mgr_err; } - rc = ssi_ivgen_init(new_drvdata); - if (unlikely(rc != 0)) { - dev_err(dev, "ssi_ivgen_init failed\n"); + rc = cc_ivgen_init(new_drvdata); + if (rc) { + dev_err(dev, "cc_ivgen_init failed\n"); goto post_power_mgr_err; } /* Allocate crypto algs */ - rc = ssi_ablkcipher_alloc(new_drvdata); - if (unlikely(rc != 0)) { - dev_err(dev, "ssi_ablkcipher_alloc failed\n"); + rc = cc_cipher_alloc(new_drvdata); + if (rc) { + dev_err(dev, "cc_cipher_alloc failed\n"); goto post_ivgen_err; } /* hash must be allocated before aead since hash exports APIs */ - rc = ssi_hash_alloc(new_drvdata); - if (unlikely(rc != 0)) { - dev_err(dev, "ssi_hash_alloc failed\n"); + rc = cc_hash_alloc(new_drvdata); + if (rc) { + dev_err(dev, "cc_hash_alloc failed\n"); goto post_cipher_err; } - rc = ssi_aead_alloc(new_drvdata); - if (unlikely(rc != 0)) { - dev_err(dev, "ssi_aead_alloc failed\n"); + rc = cc_aead_alloc(new_drvdata); + if (rc) { + dev_err(dev, "cc_aead_alloc failed\n"); goto post_hash_err; } @@ -377,25 +324,23 @@ static int init_cc_resources(struct platform_device *plat_dev) return 0; post_hash_err: - ssi_hash_free(new_drvdata); + cc_hash_free(new_drvdata); post_cipher_err: - ssi_ablkcipher_free(new_drvdata); + cc_cipher_free(new_drvdata); post_ivgen_err: - ssi_ivgen_fini(new_drvdata); + cc_ivgen_fini(new_drvdata); post_power_mgr_err: - ssi_power_mgr_fini(new_drvdata); + cc_pm_fini(new_drvdata); post_buf_mgr_err: - ssi_buffer_mgr_fini(new_drvdata); + cc_buffer_mgr_fini(new_drvdata); post_req_mgr_err: - request_mgr_fini(new_drvdata); + cc_req_mgr_fini(new_drvdata); post_sram_mgr_err: - ssi_sram_mgr_fini(new_drvdata); + cc_sram_mgr_fini(new_drvdata); post_fips_init_err: - ssi_fips_fini(new_drvdata); -post_sysfs_err: -#ifdef ENABLE_CC_SYSFS - ssi_sysfs_fini(); -#endif + cc_fips_fini(new_drvdata); +post_debugfs_err: + cc_debugfs_fini(new_drvdata); post_regs_err: fini_cc_regs(new_drvdata); post_clk_err: @@ -403,7 +348,7 @@ post_clk_err: return rc; } -void fini_cc_regs(struct ssi_drvdata *drvdata) +void fini_cc_regs(struct cc_drvdata *drvdata) { /* Mask all interrupts */ cc_iowrite(drvdata, CC_REG(HOST_IMR), 0xFFFFFFFF); @@ -411,26 +356,24 @@ void fini_cc_regs(struct ssi_drvdata *drvdata) static void cleanup_cc_resources(struct platform_device *plat_dev) { - struct ssi_drvdata *drvdata = - (struct ssi_drvdata *)platform_get_drvdata(plat_dev); - - ssi_aead_free(drvdata); - ssi_hash_free(drvdata); - ssi_ablkcipher_free(drvdata); - ssi_ivgen_fini(drvdata); - ssi_power_mgr_fini(drvdata); - ssi_buffer_mgr_fini(drvdata); - request_mgr_fini(drvdata); - ssi_sram_mgr_fini(drvdata); - ssi_fips_fini(drvdata); -#ifdef ENABLE_CC_SYSFS - ssi_sysfs_fini(); -#endif + struct cc_drvdata *drvdata = + (struct cc_drvdata *)platform_get_drvdata(plat_dev); + + cc_aead_free(drvdata); + cc_hash_free(drvdata); + cc_cipher_free(drvdata); + cc_ivgen_fini(drvdata); + cc_pm_fini(drvdata); + cc_buffer_mgr_fini(drvdata); + cc_req_mgr_fini(drvdata); + cc_sram_mgr_fini(drvdata); + cc_fips_fini(drvdata); + cc_debugfs_fini(drvdata); fini_cc_regs(drvdata); cc_clk_off(drvdata); } -int cc_clk_on(struct ssi_drvdata *drvdata) +int cc_clk_on(struct cc_drvdata *drvdata) { struct clk *clk = drvdata->clk; int rc; @@ -446,7 +389,7 @@ int cc_clk_on(struct ssi_drvdata *drvdata) return 0; } -void cc_clk_off(struct ssi_drvdata *drvdata) +void cc_clk_off(struct cc_drvdata *drvdata) { struct clk *clk = drvdata->clk; @@ -461,23 +404,10 @@ static int cc7x_probe(struct platform_device *plat_dev) { int rc; struct device *dev = &plat_dev->dev; -#if defined(CONFIG_ARM) && defined(CC_DEBUG) - u32 ctr, cacheline_size; - - asm volatile("mrc p15, 0, %0, c0, c0, 1" : "=r" (ctr)); - cacheline_size = 4 << ((ctr >> 16) & 0xf); - dev_dbg(dev, "CP15(L1_CACHE_BYTES) = %u , Kconfig(L1_CACHE_BYTES) = %u\n", - cacheline_size, L1_CACHE_BYTES); - - asm volatile("mrc p15, 0, %0, c0, c0, 0" : "=r" (ctr)); - dev_dbg(dev, "Main ID register (MIDR): Implementer 0x%02X, Arch 0x%01X, Part 0x%03X, Rev r%dp%d\n", - (ctr >> 24), (ctr >> 16) & 0xF, (ctr >> 4) & 0xFFF, - (ctr >> 20) & 0xF, ctr & 0xF); -#endif /* Map registers space */ rc = init_cc_resources(plat_dev); - if (rc != 0) + if (rc) return rc; dev_info(dev, "ARM ccree device initialized\n"); @@ -498,38 +428,44 @@ static int cc7x_remove(struct platform_device *plat_dev) return 0; } -#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP) -static const struct dev_pm_ops arm_cc7x_driver_pm = { - SET_RUNTIME_PM_OPS(ssi_power_mgr_runtime_suspend, ssi_power_mgr_runtime_resume, NULL) -}; -#endif - -#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP) -#define DX_DRIVER_RUNTIME_PM (&arm_cc7x_driver_pm) -#else -#define DX_DRIVER_RUNTIME_PM NULL -#endif - -#ifdef CONFIG_OF static const struct of_device_id arm_cc7x_dev_of_match[] = { {.compatible = "arm,cryptocell-712-ree"}, {} }; MODULE_DEVICE_TABLE(of, arm_cc7x_dev_of_match); -#endif static struct platform_driver cc7x_driver = { .driver = { .name = "cc7xree", -#ifdef CONFIG_OF .of_match_table = arm_cc7x_dev_of_match, +#ifdef CONFIG_PM + .pm = &ccree_pm, #endif - .pm = DX_DRIVER_RUNTIME_PM, }, .probe = cc7x_probe, .remove = cc7x_remove, }; -module_platform_driver(cc7x_driver); + +static int __init ccree_init(void) +{ + int ret; + + cc_hash_global_init(); + + ret = cc_debugfs_global_init(); + if (ret) + return ret; + + return platform_driver_register(&cc7x_driver); +} +module_init(ccree_init); + +static void __exit ccree_exit(void) +{ + platform_driver_unregister(&cc7x_driver); + cc_debugfs_global_fini(); +} +module_exit(ccree_exit); /* Module description */ MODULE_DESCRIPTION("ARM TrustZone CryptoCell REE Driver"); diff --git a/drivers/staging/ccree/cc_driver.h b/drivers/staging/ccree/cc_driver.h new file mode 100644 index 000000000000..773ac591c45c --- /dev/null +++ b/drivers/staging/ccree/cc_driver.h @@ -0,0 +1,194 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ + +/* \file cc_driver.h + * ARM CryptoCell Linux Crypto Driver + */ + +#ifndef __CC_DRIVER_H__ +#define __CC_DRIVER_H__ + +#ifdef COMP_IN_WQ +#include <linux/workqueue.h> +#else +#include <linux/interrupt.h> +#endif +#include <linux/dma-mapping.h> +#include <crypto/algapi.h> +#include <crypto/internal/skcipher.h> +#include <crypto/aes.h> +#include <crypto/sha.h> +#include <crypto/aead.h> +#include <crypto/authenc.h> +#include <crypto/hash.h> +#include <linux/version.h> +#include <linux/clk.h> +#include <linux/platform_device.h> + +/* Registers definitions from shared/hw/ree_include */ +#include "cc_host_regs.h" +#define CC_DEV_SHA_MAX 512 +#include "cc_crypto_ctx.h" +#include "cc_hw_queue_defs.h" +#include "cc_sram_mgr.h" + +extern bool cc_dump_desc; +extern bool cc_dump_bytes; + +#define DRV_MODULE_VERSION "3.0" + +#define CC_DEV_NAME_STR "cc715ree" +#define CC_COHERENT_CACHE_PARAMS 0xEEE + +/* Maximum DMA mask supported by IP */ +#define DMA_BIT_MASK_LEN 48 + +#define CC_DEV_SIGNATURE 0xDCC71200UL + +#define CC_AXI_IRQ_MASK ((1 << CC_AXIM_CFG_BRESPMASK_BIT_SHIFT) | \ + (1 << CC_AXIM_CFG_RRESPMASK_BIT_SHIFT) | \ + (1 << CC_AXIM_CFG_INFLTMASK_BIT_SHIFT) | \ + (1 << CC_AXIM_CFG_COMPMASK_BIT_SHIFT)) + +#define CC_AXI_ERR_IRQ_MASK BIT(CC_HOST_IRR_AXI_ERR_INT_BIT_SHIFT) + +#define CC_COMP_IRQ_MASK BIT(CC_HOST_IRR_AXIM_COMP_INT_BIT_SHIFT) + +#define AXIM_MON_COMP_VALUE GENMASK(CC_AXIM_MON_COMP_VALUE_BIT_SIZE + \ + CC_AXIM_MON_COMP_VALUE_BIT_SHIFT, \ + CC_AXIM_MON_COMP_VALUE_BIT_SHIFT) + +/* Register name mangling macro */ +#define CC_REG(reg_name) CC_ ## reg_name ## _REG_OFFSET + +/* TEE FIPS status interrupt */ +#define CC_GPR0_IRQ_MASK BIT(CC_HOST_IRR_GPR0_BIT_SHIFT) + +#define CC_CRA_PRIO 3000 + +#define MIN_HW_QUEUE_SIZE 50 /* Minimum size required for proper function */ + +#define MAX_REQUEST_QUEUE_SIZE 4096 +#define MAX_MLLI_BUFF_SIZE 2080 +#define MAX_ICV_NENTS_SUPPORTED 2 + +/* Definitions for HW descriptors DIN/DOUT fields */ +#define NS_BIT 1 +#define AXI_ID 0 +/* AXI_ID is not actually the AXI ID of the transaction but the value of AXI_ID + * field in the HW descriptor. The DMA engine +8 that value. + */ + +#define CC_MAX_IVGEN_DMA_ADDRESSES 3 +struct cc_crypto_req { + void (*user_cb)(struct device *dev, void *req, int err); + void *user_arg; + dma_addr_t ivgen_dma_addr[CC_MAX_IVGEN_DMA_ADDRESSES]; + /* For the first 'ivgen_dma_addr_len' addresses of this array, + * generated IV would be placed in it by send_request(). + * Same generated IV for all addresses! + */ + /* Amount of 'ivgen_dma_addr' elements to be filled. */ + unsigned int ivgen_dma_addr_len; + /* The generated IV size required, 8/16 B allowed. */ + unsigned int ivgen_size; + struct completion seq_compl; /* request completion */ +}; + +/** + * struct cc_drvdata - driver private data context + * @cc_base: virt address of the CC registers + * @irq: device IRQ number + * @irq_mask: Interrupt mask shadow (1 for masked interrupts) + * @fw_ver: SeP loaded firmware version + */ +struct cc_drvdata { + void __iomem *cc_base; + int irq; + u32 irq_mask; + u32 fw_ver; + struct completion hw_queue_avail; /* wait for HW queue availability */ + struct platform_device *plat_dev; + cc_sram_addr_t mlli_sram_addr; + void *buff_mgr_handle; + void *hash_handle; + void *aead_handle; + void *blkcipher_handle; + void *request_mgr_handle; + void *fips_handle; + void *ivgen_handle; + void *sram_mgr_handle; + void *debugfs; + struct clk *clk; + bool coherent; +}; + +struct cc_crypto_alg { + struct list_head entry; + int cipher_mode; + int flow_mode; /* Note: currently, refers to the cipher mode only. */ + int auth_mode; + struct cc_drvdata *drvdata; + struct crypto_alg crypto_alg; + struct aead_alg aead_alg; +}; + +struct cc_alg_template { + char name[CRYPTO_MAX_ALG_NAME]; + char driver_name[CRYPTO_MAX_ALG_NAME]; + unsigned int blocksize; + u32 type; + union { + struct ablkcipher_alg ablkcipher; + struct aead_alg aead; + struct blkcipher_alg blkcipher; + struct cipher_alg cipher; + struct compress_alg compress; + } template_u; + int cipher_mode; + int flow_mode; /* Note: currently, refers to the cipher mode only. */ + int auth_mode; + struct cc_drvdata *drvdata; +}; + +struct async_gen_req_ctx { + dma_addr_t iv_dma_addr; + enum drv_crypto_direction op_type; +}; + +static inline struct device *drvdata_to_dev(struct cc_drvdata *drvdata) +{ + return &drvdata->plat_dev->dev; +} + +void __dump_byte_array(const char *name, const u8 *buf, size_t len); +static inline void dump_byte_array(const char *name, const u8 *the_array, + size_t size) +{ + if (cc_dump_bytes) + __dump_byte_array(name, the_array, size); +} + +int init_cc_regs(struct cc_drvdata *drvdata, bool is_probe); +void fini_cc_regs(struct cc_drvdata *drvdata); +int cc_clk_on(struct cc_drvdata *drvdata); +void cc_clk_off(struct cc_drvdata *drvdata); + +static inline void cc_iowrite(struct cc_drvdata *drvdata, u32 reg, u32 val) +{ + iowrite32(val, (drvdata->cc_base + reg)); +} + +static inline u32 cc_ioread(struct cc_drvdata *drvdata, u32 reg) +{ + return ioread32(drvdata->cc_base + reg); +} + +static inline gfp_t cc_gfp_flags(struct crypto_async_request *req) +{ + return (req->flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? + GFP_KERNEL : GFP_ATOMIC; +} + +#endif /*__CC_DRIVER_H__*/ + diff --git a/drivers/staging/ccree/ssi_fips.c b/drivers/staging/ccree/cc_fips.c index 4aea99fa129f..de08af976b7f 100644 --- a/drivers/staging/ccree/ssi_fips.c +++ b/drivers/staging/ccree/cc_fips.c @@ -1,36 +1,22 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ #include <linux/kernel.h> #include <linux/fips.h> -#include "ssi_config.h" -#include "ssi_driver.h" -#include "ssi_fips.h" +#include "cc_driver.h" +#include "cc_fips.h" static void fips_dsr(unsigned long devarg); -struct ssi_fips_handle { +struct cc_fips_handle { struct tasklet_struct tasklet; }; /* The function called once at driver entry point to check * whether TEE FIPS error occurred. */ -static bool cc_get_tee_fips_status(struct ssi_drvdata *drvdata) +static bool cc_get_tee_fips_status(struct cc_drvdata *drvdata) { u32 reg; @@ -42,7 +28,7 @@ static bool cc_get_tee_fips_status(struct ssi_drvdata *drvdata) * This function should push the FIPS REE library status towards the TEE library * by writing the error state to HOST_GPR0 register. */ -void cc_set_ree_fips_status(struct ssi_drvdata *drvdata, bool status) +void cc_set_ree_fips_status(struct cc_drvdata *drvdata, bool status) { int val = CC_FIPS_SYNC_REE_STATUS; @@ -51,9 +37,9 @@ void cc_set_ree_fips_status(struct ssi_drvdata *drvdata, bool status) cc_iowrite(drvdata, CC_REG(HOST_GPR0), val); } -void ssi_fips_fini(struct ssi_drvdata *drvdata) +void cc_fips_fini(struct cc_drvdata *drvdata) { - struct ssi_fips_handle *fips_h = drvdata->fips_handle; + struct cc_fips_handle *fips_h = drvdata->fips_handle; if (!fips_h) return; /* Not allocated */ @@ -65,10 +51,9 @@ void ssi_fips_fini(struct ssi_drvdata *drvdata) drvdata->fips_handle = NULL; } -void fips_handler(struct ssi_drvdata *drvdata) +void fips_handler(struct cc_drvdata *drvdata) { - struct ssi_fips_handle *fips_handle_ptr = - drvdata->fips_handle; + struct cc_fips_handle *fips_handle_ptr = drvdata->fips_handle; tasklet_schedule(&fips_handle_ptr->tasklet); } @@ -84,11 +69,11 @@ static inline void tee_fips_error(struct device *dev) /* Deferred service handler, run as interrupt-fired tasklet */ static void fips_dsr(unsigned long devarg) { - struct ssi_drvdata *drvdata = (struct ssi_drvdata *)devarg; + struct cc_drvdata *drvdata = (struct cc_drvdata *)devarg; struct device *dev = drvdata_to_dev(drvdata); u32 irq, state, val; - irq = (drvdata->irq & (SSI_GPR0_IRQ_MASK)); + irq = (drvdata->irq & (CC_GPR0_IRQ_MASK)); if (irq) { state = cc_ioread(drvdata, CC_REG(GPR_HOST)); @@ -105,9 +90,9 @@ static void fips_dsr(unsigned long devarg) } /* The function called once at driver entry point .*/ -int ssi_fips_init(struct ssi_drvdata *p_drvdata) +int cc_fips_init(struct cc_drvdata *p_drvdata) { - struct ssi_fips_handle *fips_h; + struct cc_fips_handle *fips_h; struct device *dev = drvdata_to_dev(p_drvdata); fips_h = kzalloc(sizeof(*fips_h), GFP_KERNEL); diff --git a/drivers/staging/ccree/cc_fips.h b/drivers/staging/ccree/cc_fips.h new file mode 100644 index 000000000000..0d520030095b --- /dev/null +++ b/drivers/staging/ccree/cc_fips.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ + +#ifndef __CC_FIPS_H__ +#define __CC_FIPS_H__ + +#ifdef CONFIG_CRYPTO_FIPS + +enum cc_fips_status { + CC_FIPS_SYNC_MODULE_OK = 0x0, + CC_FIPS_SYNC_MODULE_ERROR = 0x1, + CC_FIPS_SYNC_REE_STATUS = 0x4, + CC_FIPS_SYNC_TEE_STATUS = 0x8, + CC_FIPS_SYNC_STATUS_RESERVE32B = S32_MAX +}; + +int cc_fips_init(struct cc_drvdata *p_drvdata); +void cc_fips_fini(struct cc_drvdata *drvdata); +void fips_handler(struct cc_drvdata *drvdata); +void cc_set_ree_fips_status(struct cc_drvdata *drvdata, bool ok); + +#else /* CONFIG_CRYPTO_FIPS */ + +static inline int cc_fips_init(struct cc_drvdata *p_drvdata) +{ + return 0; +} + +static inline void cc_fips_fini(struct cc_drvdata *drvdata) {} +static inline void cc_set_ree_fips_status(struct cc_drvdata *drvdata, + bool ok) {} +static inline void fips_handler(struct cc_drvdata *drvdata) {} + +#endif /* CONFIG_CRYPTO_FIPS */ + +#endif /*__CC_FIPS_H__*/ + diff --git a/drivers/staging/ccree/ssi_hash.c b/drivers/staging/ccree/cc_hash.c index 2035835b62dc..8afc39f10bb3 100644 --- a/drivers/staging/ccree/ssi_hash.c +++ b/drivers/staging/ccree/cc_hash.c @@ -1,44 +1,26 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ #include <linux/kernel.h> #include <linux/module.h> -#include <linux/platform_device.h> #include <crypto/algapi.h> #include <crypto/hash.h> -#include <crypto/sha.h> #include <crypto/md5.h> #include <crypto/internal/hash.h> -#include "ssi_config.h" -#include "ssi_driver.h" -#include "ssi_request_mgr.h" -#include "ssi_buffer_mgr.h" -#include "ssi_sysfs.h" -#include "ssi_hash.h" -#include "ssi_sram_mgr.h" +#include "cc_driver.h" +#include "cc_request_mgr.h" +#include "cc_buffer_mgr.h" +#include "cc_hash.h" +#include "cc_sram_mgr.h" -#define SSI_MAX_AHASH_SEQ_LEN 12 -#define SSI_MAX_HASH_OPAD_TMP_KEYS_SIZE MAX(SSI_MAX_HASH_BLCK_SIZE, 3 * AES_BLOCK_SIZE) +#define CC_MAX_HASH_SEQ_LEN 12 +#define CC_MAX_OPAD_KEYS_SIZE CC_MAX_HASH_BLCK_SIZE -struct ssi_hash_handle { - ssi_sram_addr_t digest_len_sram_addr; /* const value in SRAM*/ - ssi_sram_addr_t larval_digest_sram_addr; /* const value in SRAM */ +struct cc_hash_handle { + cc_sram_addr_t digest_len_sram_addr; /* const value in SRAM*/ + cc_sram_addr_t larval_digest_sram_addr; /* const value in SRAM */ struct list_head hash_list; - struct completion init_comp; }; static const u32 digest_len_init[] = { @@ -53,32 +35,31 @@ static const u32 sha224_init[] = { static const u32 sha256_init[] = { SHA256_H7, SHA256_H6, SHA256_H5, SHA256_H4, SHA256_H3, SHA256_H2, SHA256_H1, SHA256_H0 }; -#if (DX_DEV_SHA_MAX > 256) +#if (CC_DEV_SHA_MAX > 256) static const u32 digest_len_sha512_init[] = { 0x00000080, 0x00000000, 0x00000000, 0x00000000 }; -static const u64 sha384_init[] = { +static u64 sha384_init[] = { SHA384_H7, SHA384_H6, SHA384_H5, SHA384_H4, SHA384_H3, SHA384_H2, SHA384_H1, SHA384_H0 }; -static const u64 sha512_init[] = { +static u64 sha512_init[] = { SHA512_H7, SHA512_H6, SHA512_H5, SHA512_H4, SHA512_H3, SHA512_H2, SHA512_H1, SHA512_H0 }; #endif -static void ssi_hash_create_xcbc_setup( - struct ahash_request *areq, - struct cc_hw_desc desc[], - unsigned int *seq_size); +static void cc_setup_xcbc(struct ahash_request *areq, struct cc_hw_desc desc[], + unsigned int *seq_size); + +static void cc_setup_cmac(struct ahash_request *areq, struct cc_hw_desc desc[], + unsigned int *seq_size); -static void ssi_hash_create_cmac_setup(struct ahash_request *areq, - struct cc_hw_desc desc[], - unsigned int *seq_size); +static const void *cc_larval_digest(struct device *dev, u32 mode); -struct ssi_hash_alg { +struct cc_hash_alg { struct list_head entry; int hash_mode; int hw_mode; int inter_digestsize; - struct ssi_drvdata *drvdata; + struct cc_drvdata *drvdata; struct ahash_alg ahash_alg; }; @@ -88,13 +69,13 @@ struct hash_key_req_ctx { }; /* hash per-session context */ -struct ssi_hash_ctx { - struct ssi_drvdata *drvdata; +struct cc_hash_ctx { + struct cc_drvdata *drvdata; /* holds the origin digest; the digest after "setkey" if HMAC,* * the initial digest if HASH. */ - u8 digest_buff[SSI_MAX_HASH_DIGEST_SIZE] ____cacheline_aligned; - u8 opad_tmp_keys_buff[SSI_MAX_HASH_OPAD_TMP_KEYS_SIZE] ____cacheline_aligned; + u8 digest_buff[CC_MAX_HASH_DIGEST_SIZE] ____cacheline_aligned; + u8 opad_tmp_keys_buff[CC_MAX_OPAD_KEYS_SIZE] ____cacheline_aligned; dma_addr_t opad_tmp_keys_dma_addr ____cacheline_aligned; dma_addr_t digest_buff_dma_addr; @@ -107,33 +88,27 @@ struct ssi_hash_ctx { bool is_hmac; }; -static void ssi_hash_create_data_desc( - struct ahash_req_ctx *areq_ctx, - struct ssi_hash_ctx *ctx, - unsigned int flow_mode, struct cc_hw_desc desc[], - bool is_not_last_data, - unsigned int *seq_size); +static void cc_set_desc(struct ahash_req_ctx *areq_ctx, struct cc_hash_ctx *ctx, + unsigned int flow_mode, struct cc_hw_desc desc[], + bool is_not_last_data, unsigned int *seq_size); -static inline void ssi_set_hash_endianity(u32 mode, struct cc_hw_desc *desc) +static void cc_set_endianity(u32 mode, struct cc_hw_desc *desc) { - if (unlikely((mode == DRV_HASH_MD5) || - (mode == DRV_HASH_SHA384) || - (mode == DRV_HASH_SHA512))) { + if (mode == DRV_HASH_MD5 || mode == DRV_HASH_SHA384 || + mode == DRV_HASH_SHA512) { set_bytes_swap(desc, 1); } else { set_cipher_config0(desc, HASH_DIGEST_RESULT_LITTLE_ENDIAN); } } -static int ssi_hash_map_result(struct device *dev, - struct ahash_req_ctx *state, - unsigned int digestsize) +static int cc_map_result(struct device *dev, struct ahash_req_ctx *state, + unsigned int digestsize) { state->digest_result_dma_addr = - dma_map_single(dev, (void *)state->digest_result_buff, - digestsize, - DMA_BIDIRECTIONAL); - if (unlikely(dma_mapping_error(dev, state->digest_result_dma_addr))) { + dma_map_single(dev, state->digest_result_buff, + digestsize, DMA_BIDIRECTIONAL); + if (dma_mapping_error(dev, state->digest_result_dma_addr)) { dev_err(dev, "Mapping digest result buffer %u B for DMA failed\n", digestsize); return -ENOMEM; @@ -145,302 +120,331 @@ static int ssi_hash_map_result(struct device *dev, return 0; } -static int ssi_hash_map_request(struct device *dev, - struct ahash_req_ctx *state, - struct ssi_hash_ctx *ctx) +static void cc_init_req(struct device *dev, struct ahash_req_ctx *state, + struct cc_hash_ctx *ctx) { bool is_hmac = ctx->is_hmac; - ssi_sram_addr_t larval_digest_addr = ssi_ahash_get_larval_digest_sram_addr( - ctx->drvdata, ctx->hash_mode); - struct ssi_crypto_req ssi_req = {}; - struct cc_hw_desc desc; - int rc = -ENOMEM; - - state->buff0 = kzalloc(SSI_MAX_HASH_BLCK_SIZE, GFP_KERNEL | GFP_DMA); - if (!state->buff0) - goto fail0; - - state->buff1 = kzalloc(SSI_MAX_HASH_BLCK_SIZE, GFP_KERNEL | GFP_DMA); - if (!state->buff1) - goto fail_buff0; - - state->digest_result_buff = kzalloc(SSI_MAX_HASH_DIGEST_SIZE, GFP_KERNEL | GFP_DMA); - if (!state->digest_result_buff) - goto fail_buff1; - - state->digest_buff = kzalloc(ctx->inter_digestsize, GFP_KERNEL | GFP_DMA); - if (!state->digest_buff) - goto fail_digest_result_buff; - - dev_dbg(dev, "Allocated digest-buffer in context ctx->digest_buff=@%p\n", - state->digest_buff); - if (ctx->hw_mode != DRV_CIPHER_XCBC_MAC) { - state->digest_bytes_len = kzalloc(HASH_LEN_SIZE, GFP_KERNEL | GFP_DMA); - if (!state->digest_bytes_len) - goto fail1; - dev_dbg(dev, "Allocated digest-bytes-len in context state->>digest_bytes_len=@%p\n", - state->digest_bytes_len); - } else { - state->digest_bytes_len = NULL; - } - - state->opad_digest_buff = kzalloc(ctx->inter_digestsize, GFP_KERNEL | GFP_DMA); - if (!state->opad_digest_buff) - goto fail2; - - dev_dbg(dev, "Allocated opad-digest-buffer in context state->digest_bytes_len=@%p\n", - state->opad_digest_buff); - - state->digest_buff_dma_addr = dma_map_single(dev, (void *)state->digest_buff, ctx->inter_digestsize, DMA_BIDIRECTIONAL); - if (dma_mapping_error(dev, state->digest_buff_dma_addr)) { - dev_err(dev, "Mapping digest len %d B at va=%pK for DMA failed\n", - ctx->inter_digestsize, state->digest_buff); - goto fail3; - } - dev_dbg(dev, "Mapped digest %d B at va=%pK to dma=%pad\n", - ctx->inter_digestsize, state->digest_buff, - &state->digest_buff_dma_addr); + memset(state, 0, sizeof(*state)); if (is_hmac) { - dma_sync_single_for_cpu(dev, ctx->digest_buff_dma_addr, ctx->inter_digestsize, DMA_BIDIRECTIONAL); - if ((ctx->hw_mode == DRV_CIPHER_XCBC_MAC) || (ctx->hw_mode == DRV_CIPHER_CMAC)) { - memset(state->digest_buff, 0, ctx->inter_digestsize); - } else { /*sha*/ - memcpy(state->digest_buff, ctx->digest_buff, ctx->inter_digestsize); -#if (DX_DEV_SHA_MAX > 256) - if (unlikely((ctx->hash_mode == DRV_HASH_SHA512) || (ctx->hash_mode == DRV_HASH_SHA384))) - memcpy(state->digest_bytes_len, digest_len_sha512_init, HASH_LEN_SIZE); + if (ctx->hw_mode != DRV_CIPHER_XCBC_MAC && + ctx->hw_mode != DRV_CIPHER_CMAC) { + dma_sync_single_for_cpu(dev, ctx->digest_buff_dma_addr, + ctx->inter_digestsize, + DMA_BIDIRECTIONAL); + + memcpy(state->digest_buff, ctx->digest_buff, + ctx->inter_digestsize); +#if (CC_DEV_SHA_MAX > 256) + if (ctx->hash_mode == DRV_HASH_SHA512 || + ctx->hash_mode == DRV_HASH_SHA384) + memcpy(state->digest_bytes_len, + digest_len_sha512_init, HASH_LEN_SIZE); else - memcpy(state->digest_bytes_len, digest_len_init, HASH_LEN_SIZE); + memcpy(state->digest_bytes_len, + digest_len_init, HASH_LEN_SIZE); #else - memcpy(state->digest_bytes_len, digest_len_init, HASH_LEN_SIZE); + memcpy(state->digest_bytes_len, digest_len_init, + HASH_LEN_SIZE); #endif } - dma_sync_single_for_device(dev, state->digest_buff_dma_addr, ctx->inter_digestsize, DMA_BIDIRECTIONAL); if (ctx->hash_mode != DRV_HASH_NULL) { - dma_sync_single_for_cpu(dev, ctx->opad_tmp_keys_dma_addr, ctx->inter_digestsize, DMA_BIDIRECTIONAL); - memcpy(state->opad_digest_buff, ctx->opad_tmp_keys_buff, ctx->inter_digestsize); + dma_sync_single_for_cpu(dev, + ctx->opad_tmp_keys_dma_addr, + ctx->inter_digestsize, + DMA_BIDIRECTIONAL); + memcpy(state->opad_digest_buff, + ctx->opad_tmp_keys_buff, ctx->inter_digestsize); } } else { /*hash*/ - /* Copy the initial digests if hash flow. The SRAM contains the - * initial digests in the expected order for all SHA* - */ - hw_desc_init(&desc); - set_din_sram(&desc, larval_digest_addr, ctx->inter_digestsize); - set_dout_dlli(&desc, state->digest_buff_dma_addr, - ctx->inter_digestsize, NS_BIT, 0); - set_flow_mode(&desc, BYPASS); - - rc = send_request(ctx->drvdata, &ssi_req, &desc, 1, 0); - if (unlikely(rc != 0)) { - dev_err(dev, "send_request() failed (rc=%d)\n", rc); - goto fail4; - } + /* Copy the initial digests if hash flow. */ + const void *larval = cc_larval_digest(dev, ctx->hash_mode); + + memcpy(state->digest_buff, larval, ctx->inter_digestsize); + } +} + +static int cc_map_req(struct device *dev, struct ahash_req_ctx *state, + struct cc_hash_ctx *ctx) +{ + bool is_hmac = ctx->is_hmac; + + state->digest_buff_dma_addr = + dma_map_single(dev, state->digest_buff, + ctx->inter_digestsize, DMA_BIDIRECTIONAL); + if (dma_mapping_error(dev, state->digest_buff_dma_addr)) { + dev_err(dev, "Mapping digest len %d B at va=%pK for DMA failed\n", + ctx->inter_digestsize, state->digest_buff); + return -EINVAL; } + dev_dbg(dev, "Mapped digest %d B at va=%pK to dma=%pad\n", + ctx->inter_digestsize, state->digest_buff, + &state->digest_buff_dma_addr); if (ctx->hw_mode != DRV_CIPHER_XCBC_MAC) { - state->digest_bytes_len_dma_addr = dma_map_single(dev, (void *)state->digest_bytes_len, HASH_LEN_SIZE, DMA_BIDIRECTIONAL); + state->digest_bytes_len_dma_addr = + dma_map_single(dev, state->digest_bytes_len, + HASH_LEN_SIZE, DMA_BIDIRECTIONAL); if (dma_mapping_error(dev, state->digest_bytes_len_dma_addr)) { dev_err(dev, "Mapping digest len %u B at va=%pK for DMA failed\n", HASH_LEN_SIZE, state->digest_bytes_len); - goto fail4; + goto unmap_digest_buf; } dev_dbg(dev, "Mapped digest len %u B at va=%pK to dma=%pad\n", HASH_LEN_SIZE, state->digest_bytes_len, &state->digest_bytes_len_dma_addr); - } else { - state->digest_bytes_len_dma_addr = 0; } if (is_hmac && ctx->hash_mode != DRV_HASH_NULL) { - state->opad_digest_dma_addr = dma_map_single(dev, (void *)state->opad_digest_buff, ctx->inter_digestsize, DMA_BIDIRECTIONAL); + state->opad_digest_dma_addr = + dma_map_single(dev, state->opad_digest_buff, + ctx->inter_digestsize, + DMA_BIDIRECTIONAL); if (dma_mapping_error(dev, state->opad_digest_dma_addr)) { dev_err(dev, "Mapping opad digest %d B at va=%pK for DMA failed\n", ctx->inter_digestsize, state->opad_digest_buff); - goto fail5; + goto unmap_digest_len; } dev_dbg(dev, "Mapped opad digest %d B at va=%pK to dma=%pad\n", ctx->inter_digestsize, state->opad_digest_buff, &state->opad_digest_dma_addr); - } else { - state->opad_digest_dma_addr = 0; } - state->buff0_cnt = 0; - state->buff1_cnt = 0; - state->buff_index = 0; - state->mlli_params.curr_pool = NULL; return 0; -fail5: - if (state->digest_bytes_len_dma_addr != 0) { - dma_unmap_single(dev, state->digest_bytes_len_dma_addr, HASH_LEN_SIZE, DMA_BIDIRECTIONAL); +unmap_digest_len: + if (state->digest_bytes_len_dma_addr) { + dma_unmap_single(dev, state->digest_bytes_len_dma_addr, + HASH_LEN_SIZE, DMA_BIDIRECTIONAL); state->digest_bytes_len_dma_addr = 0; } -fail4: - if (state->digest_buff_dma_addr != 0) { - dma_unmap_single(dev, state->digest_buff_dma_addr, ctx->inter_digestsize, DMA_BIDIRECTIONAL); +unmap_digest_buf: + if (state->digest_buff_dma_addr) { + dma_unmap_single(dev, state->digest_buff_dma_addr, + ctx->inter_digestsize, DMA_BIDIRECTIONAL); state->digest_buff_dma_addr = 0; } -fail3: - kfree(state->opad_digest_buff); -fail2: - kfree(state->digest_bytes_len); -fail1: - kfree(state->digest_buff); -fail_digest_result_buff: - kfree(state->digest_result_buff); - state->digest_result_buff = NULL; -fail_buff1: - kfree(state->buff1); - state->buff1 = NULL; -fail_buff0: - kfree(state->buff0); - state->buff0 = NULL; -fail0: - return rc; + + return -EINVAL; } -static void ssi_hash_unmap_request(struct device *dev, - struct ahash_req_ctx *state, - struct ssi_hash_ctx *ctx) +static void cc_unmap_req(struct device *dev, struct ahash_req_ctx *state, + struct cc_hash_ctx *ctx) { - if (state->digest_buff_dma_addr != 0) { + if (state->digest_buff_dma_addr) { dma_unmap_single(dev, state->digest_buff_dma_addr, ctx->inter_digestsize, DMA_BIDIRECTIONAL); dev_dbg(dev, "Unmapped digest-buffer: digest_buff_dma_addr=%pad\n", &state->digest_buff_dma_addr); state->digest_buff_dma_addr = 0; } - if (state->digest_bytes_len_dma_addr != 0) { + if (state->digest_bytes_len_dma_addr) { dma_unmap_single(dev, state->digest_bytes_len_dma_addr, HASH_LEN_SIZE, DMA_BIDIRECTIONAL); dev_dbg(dev, "Unmapped digest-bytes-len buffer: digest_bytes_len_dma_addr=%pad\n", &state->digest_bytes_len_dma_addr); state->digest_bytes_len_dma_addr = 0; } - if (state->opad_digest_dma_addr != 0) { + if (state->opad_digest_dma_addr) { dma_unmap_single(dev, state->opad_digest_dma_addr, ctx->inter_digestsize, DMA_BIDIRECTIONAL); dev_dbg(dev, "Unmapped opad-digest: opad_digest_dma_addr=%pad\n", &state->opad_digest_dma_addr); state->opad_digest_dma_addr = 0; } - - kfree(state->opad_digest_buff); - kfree(state->digest_bytes_len); - kfree(state->digest_buff); - kfree(state->digest_result_buff); - kfree(state->buff1); - kfree(state->buff0); } -static void ssi_hash_unmap_result(struct device *dev, - struct ahash_req_ctx *state, - unsigned int digestsize, u8 *result) +static void cc_unmap_result(struct device *dev, struct ahash_req_ctx *state, + unsigned int digestsize, u8 *result) { - if (state->digest_result_dma_addr != 0) { - dma_unmap_single(dev, - state->digest_result_dma_addr, - digestsize, - DMA_BIDIRECTIONAL); + if (state->digest_result_dma_addr) { + dma_unmap_single(dev, state->digest_result_dma_addr, digestsize, + DMA_BIDIRECTIONAL); dev_dbg(dev, "unmpa digest result buffer va (%pK) pa (%pad) len %u\n", state->digest_result_buff, &state->digest_result_dma_addr, digestsize); - memcpy(result, - state->digest_result_buff, - digestsize); + memcpy(result, state->digest_result_buff, digestsize); } state->digest_result_dma_addr = 0; } -static void ssi_hash_update_complete(struct device *dev, void *ssi_req, void __iomem *cc_base) +static void cc_update_complete(struct device *dev, void *cc_req, int err) { - struct ahash_request *req = (struct ahash_request *)ssi_req; + struct ahash_request *req = (struct ahash_request *)cc_req; struct ahash_req_ctx *state = ahash_request_ctx(req); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct cc_hash_ctx *ctx = crypto_ahash_ctx(tfm); dev_dbg(dev, "req=%pK\n", req); - ssi_buffer_mgr_unmap_hash_request(dev, state, req->src, false); - req->base.complete(&req->base, 0); + cc_unmap_hash_request(dev, state, req->src, false); + cc_unmap_req(dev, state, ctx); + req->base.complete(&req->base, err); } -static void ssi_hash_digest_complete(struct device *dev, void *ssi_req, void __iomem *cc_base) +static void cc_digest_complete(struct device *dev, void *cc_req, int err) { - struct ahash_request *req = (struct ahash_request *)ssi_req; + struct ahash_request *req = (struct ahash_request *)cc_req; struct ahash_req_ctx *state = ahash_request_ctx(req); struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct ssi_hash_ctx *ctx = crypto_ahash_ctx(tfm); + struct cc_hash_ctx *ctx = crypto_ahash_ctx(tfm); u32 digestsize = crypto_ahash_digestsize(tfm); dev_dbg(dev, "req=%pK\n", req); - ssi_buffer_mgr_unmap_hash_request(dev, state, req->src, false); - ssi_hash_unmap_result(dev, state, digestsize, req->result); - ssi_hash_unmap_request(dev, state, ctx); - req->base.complete(&req->base, 0); + cc_unmap_hash_request(dev, state, req->src, false); + cc_unmap_result(dev, state, digestsize, req->result); + cc_unmap_req(dev, state, ctx); + req->base.complete(&req->base, err); } -static void ssi_hash_complete(struct device *dev, void *ssi_req, void __iomem *cc_base) +static void cc_hash_complete(struct device *dev, void *cc_req, int err) { - struct ahash_request *req = (struct ahash_request *)ssi_req; + struct ahash_request *req = (struct ahash_request *)cc_req; struct ahash_req_ctx *state = ahash_request_ctx(req); struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct ssi_hash_ctx *ctx = crypto_ahash_ctx(tfm); + struct cc_hash_ctx *ctx = crypto_ahash_ctx(tfm); u32 digestsize = crypto_ahash_digestsize(tfm); dev_dbg(dev, "req=%pK\n", req); - ssi_buffer_mgr_unmap_hash_request(dev, state, req->src, false); - ssi_hash_unmap_result(dev, state, digestsize, req->result); - ssi_hash_unmap_request(dev, state, ctx); - req->base.complete(&req->base, 0); + cc_unmap_hash_request(dev, state, req->src, false); + cc_unmap_result(dev, state, digestsize, req->result); + cc_unmap_req(dev, state, ctx); + req->base.complete(&req->base, err); +} + +static int cc_fin_result(struct cc_hw_desc *desc, struct ahash_request *req, + int idx) +{ + struct ahash_req_ctx *state = ahash_request_ctx(req); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct cc_hash_ctx *ctx = crypto_ahash_ctx(tfm); + u32 digestsize = crypto_ahash_digestsize(tfm); + + /* Get final MAC result */ + hw_desc_init(&desc[idx]); + set_cipher_mode(&desc[idx], ctx->hw_mode); + /* TODO */ + set_dout_dlli(&desc[idx], state->digest_result_dma_addr, digestsize, + NS_BIT, 1); + set_queue_last_ind(&desc[idx]); + set_flow_mode(&desc[idx], S_HASH_to_DOUT); + set_setup_mode(&desc[idx], SETUP_WRITE_STATE0); + set_cipher_config1(&desc[idx], HASH_PADDING_DISABLED); + cc_set_endianity(ctx->hash_mode, &desc[idx]); + idx++; + + return idx; +} + +static int cc_fin_hmac(struct cc_hw_desc *desc, struct ahash_request *req, + int idx) +{ + struct ahash_req_ctx *state = ahash_request_ctx(req); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct cc_hash_ctx *ctx = crypto_ahash_ctx(tfm); + u32 digestsize = crypto_ahash_digestsize(tfm); + + /* store the hash digest result in the context */ + hw_desc_init(&desc[idx]); + set_cipher_mode(&desc[idx], ctx->hw_mode); + set_dout_dlli(&desc[idx], state->digest_buff_dma_addr, digestsize, + NS_BIT, 0); + set_flow_mode(&desc[idx], S_HASH_to_DOUT); + cc_set_endianity(ctx->hash_mode, &desc[idx]); + set_setup_mode(&desc[idx], SETUP_WRITE_STATE0); + idx++; + + /* Loading hash opad xor key state */ + hw_desc_init(&desc[idx]); + set_cipher_mode(&desc[idx], ctx->hw_mode); + set_din_type(&desc[idx], DMA_DLLI, state->opad_digest_dma_addr, + ctx->inter_digestsize, NS_BIT); + set_flow_mode(&desc[idx], S_DIN_to_HASH); + set_setup_mode(&desc[idx], SETUP_LOAD_STATE0); + idx++; + + /* Load the hash current length */ + hw_desc_init(&desc[idx]); + set_cipher_mode(&desc[idx], ctx->hw_mode); + set_din_sram(&desc[idx], + cc_digest_len_addr(ctx->drvdata, ctx->hash_mode), + HASH_LEN_SIZE); + set_cipher_config1(&desc[idx], HASH_PADDING_ENABLED); + set_flow_mode(&desc[idx], S_DIN_to_HASH); + set_setup_mode(&desc[idx], SETUP_LOAD_KEY0); + idx++; + + /* Memory Barrier: wait for IPAD/OPAD axi write to complete */ + hw_desc_init(&desc[idx]); + set_din_no_dma(&desc[idx], 0, 0xfffff0); + set_dout_no_dma(&desc[idx], 0, 0, 1); + idx++; + + /* Perform HASH update */ + hw_desc_init(&desc[idx]); + set_din_type(&desc[idx], DMA_DLLI, state->digest_buff_dma_addr, + digestsize, NS_BIT); + set_flow_mode(&desc[idx], DIN_HASH); + idx++; + + return idx; } -static int ssi_hash_digest(struct ahash_req_ctx *state, - struct ssi_hash_ctx *ctx, - unsigned int digestsize, - struct scatterlist *src, - unsigned int nbytes, u8 *result, - void *async_req) +static int cc_hash_digest(struct ahash_request *req) { + struct ahash_req_ctx *state = ahash_request_ctx(req); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct cc_hash_ctx *ctx = crypto_ahash_ctx(tfm); + u32 digestsize = crypto_ahash_digestsize(tfm); + struct scatterlist *src = req->src; + unsigned int nbytes = req->nbytes; + u8 *result = req->result; struct device *dev = drvdata_to_dev(ctx->drvdata); bool is_hmac = ctx->is_hmac; - struct ssi_crypto_req ssi_req = {}; - struct cc_hw_desc desc[SSI_MAX_AHASH_SEQ_LEN]; - ssi_sram_addr_t larval_digest_addr = ssi_ahash_get_larval_digest_sram_addr( - ctx->drvdata, ctx->hash_mode); + struct cc_crypto_req cc_req = {}; + struct cc_hw_desc desc[CC_MAX_HASH_SEQ_LEN]; + cc_sram_addr_t larval_digest_addr = + cc_larval_digest_addr(ctx->drvdata, ctx->hash_mode); int idx = 0; int rc = 0; + gfp_t flags = cc_gfp_flags(&req->base); dev_dbg(dev, "===== %s-digest (%d) ====\n", is_hmac ? "hmac" : "hash", nbytes); - if (unlikely(ssi_hash_map_request(dev, state, ctx) != 0)) { + cc_init_req(dev, state, ctx); + + if (cc_map_req(dev, state, ctx)) { dev_err(dev, "map_ahash_source() failed\n"); return -ENOMEM; } - if (unlikely(ssi_hash_map_result(dev, state, digestsize) != 0)) { + if (cc_map_result(dev, state, digestsize)) { dev_err(dev, "map_ahash_digest() failed\n"); + cc_unmap_req(dev, state, ctx); return -ENOMEM; } - if (unlikely(ssi_buffer_mgr_map_hash_request_final(ctx->drvdata, state, src, nbytes, 1) != 0)) { + if (cc_map_hash_request_final(ctx->drvdata, state, src, nbytes, 1, + flags)) { dev_err(dev, "map_ahash_request_final() failed\n"); + cc_unmap_result(dev, state, digestsize, result); + cc_unmap_req(dev, state, ctx); return -ENOMEM; } - if (async_req) { - /* Setup DX request structure */ - ssi_req.user_cb = (void *)ssi_hash_digest_complete; - ssi_req.user_arg = (void *)async_req; - } + /* Setup DX request structure */ + cc_req.user_cb = cc_digest_complete; + cc_req.user_arg = req; - /* If HMAC then load hash IPAD xor key, if HASH then load initial digest */ + /* If HMAC then load hash IPAD xor key, if HASH then load initial + * digest + */ hw_desc_init(&desc[idx]); set_cipher_mode(&desc[idx], ctx->hw_mode); if (is_hmac) { @@ -464,7 +468,7 @@ static int ssi_hash_digest(struct ahash_req_ctx *state, NS_BIT); } else { set_din_const(&desc[idx], 0, HASH_LEN_SIZE); - if (likely(nbytes != 0)) + if (nbytes) set_cipher_config1(&desc[idx], HASH_PADDING_ENABLED); else set_cipher_do(&desc[idx], DO_PAD); @@ -473,7 +477,7 @@ static int ssi_hash_digest(struct ahash_req_ctx *state, set_setup_mode(&desc[idx], SETUP_LOAD_KEY0); idx++; - ssi_hash_create_data_desc(state, ctx, DIN_HASH, desc, false, &idx); + cc_set_desc(state, ctx, DIN_HASH, desc, false, &idx); if (is_hmac) { /* HW last hash block padding (aka. "DO_PAD") */ @@ -486,98 +490,62 @@ static int ssi_hash_digest(struct ahash_req_ctx *state, set_cipher_do(&desc[idx], DO_PAD); idx++; - /* store the hash digest result in the context */ - hw_desc_init(&desc[idx]); - set_cipher_mode(&desc[idx], ctx->hw_mode); - set_dout_dlli(&desc[idx], state->digest_buff_dma_addr, - digestsize, NS_BIT, 0); - set_flow_mode(&desc[idx], S_HASH_to_DOUT); - ssi_set_hash_endianity(ctx->hash_mode, &desc[idx]); - set_setup_mode(&desc[idx], SETUP_WRITE_STATE0); - idx++; - - /* Loading hash opad xor key state */ - hw_desc_init(&desc[idx]); - set_cipher_mode(&desc[idx], ctx->hw_mode); - set_din_type(&desc[idx], DMA_DLLI, state->opad_digest_dma_addr, - ctx->inter_digestsize, NS_BIT); - set_flow_mode(&desc[idx], S_DIN_to_HASH); - set_setup_mode(&desc[idx], SETUP_LOAD_STATE0); - idx++; - - /* Load the hash current length */ - hw_desc_init(&desc[idx]); - set_cipher_mode(&desc[idx], ctx->hw_mode); - set_din_sram(&desc[idx], - ssi_ahash_get_initial_digest_len_sram_addr( -ctx->drvdata, ctx->hash_mode), HASH_LEN_SIZE); - set_cipher_config1(&desc[idx], HASH_PADDING_ENABLED); - set_flow_mode(&desc[idx], S_DIN_to_HASH); - set_setup_mode(&desc[idx], SETUP_LOAD_KEY0); - idx++; + idx = cc_fin_hmac(desc, req, idx); + } - /* Memory Barrier: wait for IPAD/OPAD axi write to complete */ - hw_desc_init(&desc[idx]); - set_din_no_dma(&desc[idx], 0, 0xfffff0); - set_dout_no_dma(&desc[idx], 0, 0, 1); - idx++; + idx = cc_fin_result(desc, req, idx); - /* Perform HASH update */ - hw_desc_init(&desc[idx]); - set_din_type(&desc[idx], DMA_DLLI, state->digest_buff_dma_addr, - digestsize, NS_BIT); - set_flow_mode(&desc[idx], DIN_HASH); - idx++; + rc = cc_send_request(ctx->drvdata, &cc_req, desc, idx, &req->base); + if (rc != -EINPROGRESS && rc != -EBUSY) { + dev_err(dev, "send_request() failed (rc=%d)\n", rc); + cc_unmap_hash_request(dev, state, src, true); + cc_unmap_result(dev, state, digestsize, result); + cc_unmap_req(dev, state, ctx); } + return rc; +} - /* Get final MAC result */ +static int cc_restore_hash(struct cc_hw_desc *desc, struct cc_hash_ctx *ctx, + struct ahash_req_ctx *state, int idx) +{ + /* Restore hash digest */ + hw_desc_init(&desc[idx]); + set_cipher_mode(&desc[idx], ctx->hw_mode); + set_din_type(&desc[idx], DMA_DLLI, state->digest_buff_dma_addr, + ctx->inter_digestsize, NS_BIT); + set_flow_mode(&desc[idx], S_DIN_to_HASH); + set_setup_mode(&desc[idx], SETUP_LOAD_STATE0); + idx++; + + /* Restore hash current length */ hw_desc_init(&desc[idx]); set_cipher_mode(&desc[idx], ctx->hw_mode); - /* TODO */ - set_dout_dlli(&desc[idx], state->digest_result_dma_addr, digestsize, - NS_BIT, (async_req ? 1 : 0)); - if (async_req) - set_queue_last_ind(&desc[idx]); - set_flow_mode(&desc[idx], S_HASH_to_DOUT); - set_setup_mode(&desc[idx], SETUP_WRITE_STATE0); set_cipher_config1(&desc[idx], HASH_PADDING_DISABLED); - ssi_set_hash_endianity(ctx->hash_mode, &desc[idx]); + set_din_type(&desc[idx], DMA_DLLI, state->digest_bytes_len_dma_addr, + HASH_LEN_SIZE, NS_BIT); + set_flow_mode(&desc[idx], S_DIN_to_HASH); + set_setup_mode(&desc[idx], SETUP_LOAD_KEY0); idx++; - if (async_req) { - rc = send_request(ctx->drvdata, &ssi_req, desc, idx, 1); - if (unlikely(rc != -EINPROGRESS)) { - dev_err(dev, "send_request() failed (rc=%d)\n", rc); - ssi_buffer_mgr_unmap_hash_request(dev, state, src, true); - ssi_hash_unmap_result(dev, state, digestsize, result); - ssi_hash_unmap_request(dev, state, ctx); - } - } else { - rc = send_request(ctx->drvdata, &ssi_req, desc, idx, 0); - if (rc != 0) { - dev_err(dev, "send_request() failed (rc=%d)\n", rc); - ssi_buffer_mgr_unmap_hash_request(dev, state, src, true); - } else { - ssi_buffer_mgr_unmap_hash_request(dev, state, src, false); - } - ssi_hash_unmap_result(dev, state, digestsize, result); - ssi_hash_unmap_request(dev, state, ctx); - } - return rc; + cc_set_desc(state, ctx, DIN_HASH, desc, false, &idx); + + return idx; } -static int ssi_hash_update(struct ahash_req_ctx *state, - struct ssi_hash_ctx *ctx, - unsigned int block_size, - struct scatterlist *src, - unsigned int nbytes, - void *async_req) +static int cc_hash_update(struct ahash_request *req) { + struct ahash_req_ctx *state = ahash_request_ctx(req); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct cc_hash_ctx *ctx = crypto_ahash_ctx(tfm); + unsigned int block_size = crypto_tfm_alg_blocksize(&tfm->base); + struct scatterlist *src = req->src; + unsigned int nbytes = req->nbytes; struct device *dev = drvdata_to_dev(ctx->drvdata); - struct ssi_crypto_req ssi_req = {}; - struct cc_hw_desc desc[SSI_MAX_AHASH_SEQ_LEN]; + struct cc_crypto_req cc_req = {}; + struct cc_hw_desc desc[CC_MAX_HASH_SEQ_LEN]; u32 idx = 0; int rc; + gfp_t flags = cc_gfp_flags(&req->base); dev_dbg(dev, "===== %s-update (%d) ====\n", ctx->is_hmac ? "hmac" : "hash", nbytes); @@ -587,8 +555,9 @@ static int ssi_hash_update(struct ahash_req_ctx *state, return 0; } - rc = ssi_buffer_mgr_map_hash_request_update(ctx->drvdata, state, src, nbytes, block_size); - if (unlikely(rc)) { + rc = cc_map_hash_request_update(ctx->drvdata, state, src, nbytes, + block_size, flags); + if (rc) { if (rc == 1) { dev_dbg(dev, " data size not require HW update %x\n", nbytes); @@ -599,30 +568,17 @@ static int ssi_hash_update(struct ahash_req_ctx *state, return -ENOMEM; } - if (async_req) { - /* Setup DX request structure */ - ssi_req.user_cb = (void *)ssi_hash_update_complete; - ssi_req.user_arg = async_req; + if (cc_map_req(dev, state, ctx)) { + dev_err(dev, "map_ahash_source() failed\n"); + cc_unmap_hash_request(dev, state, src, true); + return -EINVAL; } - /* Restore hash digest */ - hw_desc_init(&desc[idx]); - set_cipher_mode(&desc[idx], ctx->hw_mode); - set_din_type(&desc[idx], DMA_DLLI, state->digest_buff_dma_addr, - ctx->inter_digestsize, NS_BIT); - set_flow_mode(&desc[idx], S_DIN_to_HASH); - set_setup_mode(&desc[idx], SETUP_LOAD_STATE0); - idx++; - /* Restore hash current length */ - hw_desc_init(&desc[idx]); - set_cipher_mode(&desc[idx], ctx->hw_mode); - set_din_type(&desc[idx], DMA_DLLI, state->digest_bytes_len_dma_addr, - HASH_LEN_SIZE, NS_BIT); - set_flow_mode(&desc[idx], S_DIN_to_HASH); - set_setup_mode(&desc[idx], SETUP_LOAD_KEY0); - idx++; + /* Setup DX request structure */ + cc_req.user_cb = cc_update_complete; + cc_req.user_arg = req; - ssi_hash_create_data_desc(state, ctx, DIN_HASH, desc, false, &idx); + idx = cc_restore_hash(desc, ctx, state, idx); /* store the hash digest result in context */ hw_desc_init(&desc[idx]); @@ -637,220 +593,124 @@ static int ssi_hash_update(struct ahash_req_ctx *state, hw_desc_init(&desc[idx]); set_cipher_mode(&desc[idx], ctx->hw_mode); set_dout_dlli(&desc[idx], state->digest_bytes_len_dma_addr, - HASH_LEN_SIZE, NS_BIT, (async_req ? 1 : 0)); - if (async_req) - set_queue_last_ind(&desc[idx]); + HASH_LEN_SIZE, NS_BIT, 1); + set_queue_last_ind(&desc[idx]); set_flow_mode(&desc[idx], S_HASH_to_DOUT); set_setup_mode(&desc[idx], SETUP_WRITE_STATE1); idx++; - if (async_req) { - rc = send_request(ctx->drvdata, &ssi_req, desc, idx, 1); - if (unlikely(rc != -EINPROGRESS)) { - dev_err(dev, "send_request() failed (rc=%d)\n", rc); - ssi_buffer_mgr_unmap_hash_request(dev, state, src, true); - } - } else { - rc = send_request(ctx->drvdata, &ssi_req, desc, idx, 0); - if (rc != 0) { - dev_err(dev, "send_request() failed (rc=%d)\n", rc); - ssi_buffer_mgr_unmap_hash_request(dev, state, src, true); - } else { - ssi_buffer_mgr_unmap_hash_request(dev, state, src, false); - } + rc = cc_send_request(ctx->drvdata, &cc_req, desc, idx, &req->base); + if (rc != -EINPROGRESS && rc != -EBUSY) { + dev_err(dev, "send_request() failed (rc=%d)\n", rc); + cc_unmap_hash_request(dev, state, src, true); + cc_unmap_req(dev, state, ctx); } return rc; } -static int ssi_hash_finup(struct ahash_req_ctx *state, - struct ssi_hash_ctx *ctx, - unsigned int digestsize, - struct scatterlist *src, - unsigned int nbytes, - u8 *result, - void *async_req) +static int cc_hash_finup(struct ahash_request *req) { + struct ahash_req_ctx *state = ahash_request_ctx(req); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct cc_hash_ctx *ctx = crypto_ahash_ctx(tfm); + u32 digestsize = crypto_ahash_digestsize(tfm); + struct scatterlist *src = req->src; + unsigned int nbytes = req->nbytes; + u8 *result = req->result; struct device *dev = drvdata_to_dev(ctx->drvdata); bool is_hmac = ctx->is_hmac; - struct ssi_crypto_req ssi_req = {}; - struct cc_hw_desc desc[SSI_MAX_AHASH_SEQ_LEN]; + struct cc_crypto_req cc_req = {}; + struct cc_hw_desc desc[CC_MAX_HASH_SEQ_LEN]; int idx = 0; int rc; + gfp_t flags = cc_gfp_flags(&req->base); dev_dbg(dev, "===== %s-finup (%d) ====\n", is_hmac ? "hmac" : "hash", nbytes); - if (unlikely(ssi_buffer_mgr_map_hash_request_final(ctx->drvdata, state, src, nbytes, 1) != 0)) { + if (cc_map_req(dev, state, ctx)) { + dev_err(dev, "map_ahash_source() failed\n"); + return -EINVAL; + } + + if (cc_map_hash_request_final(ctx->drvdata, state, src, nbytes, 1, + flags)) { dev_err(dev, "map_ahash_request_final() failed\n"); + cc_unmap_req(dev, state, ctx); return -ENOMEM; } - if (unlikely(ssi_hash_map_result(dev, state, digestsize) != 0)) { + if (cc_map_result(dev, state, digestsize)) { dev_err(dev, "map_ahash_digest() failed\n"); + cc_unmap_hash_request(dev, state, src, true); + cc_unmap_req(dev, state, ctx); return -ENOMEM; } - if (async_req) { - /* Setup DX request structure */ - ssi_req.user_cb = (void *)ssi_hash_complete; - ssi_req.user_arg = async_req; - } - - /* Restore hash digest */ - hw_desc_init(&desc[idx]); - set_cipher_mode(&desc[idx], ctx->hw_mode); - set_din_type(&desc[idx], DMA_DLLI, state->digest_buff_dma_addr, - ctx->inter_digestsize, NS_BIT); - set_flow_mode(&desc[idx], S_DIN_to_HASH); - set_setup_mode(&desc[idx], SETUP_LOAD_STATE0); - idx++; - - /* Restore hash current length */ - hw_desc_init(&desc[idx]); - set_cipher_mode(&desc[idx], ctx->hw_mode); - set_cipher_config1(&desc[idx], HASH_PADDING_ENABLED); - set_din_type(&desc[idx], DMA_DLLI, state->digest_bytes_len_dma_addr, - HASH_LEN_SIZE, NS_BIT); - set_flow_mode(&desc[idx], S_DIN_to_HASH); - set_setup_mode(&desc[idx], SETUP_LOAD_KEY0); - idx++; - - ssi_hash_create_data_desc(state, ctx, DIN_HASH, desc, false, &idx); - - if (is_hmac) { - /* Store the hash digest result in the context */ - hw_desc_init(&desc[idx]); - set_cipher_mode(&desc[idx], ctx->hw_mode); - set_dout_dlli(&desc[idx], state->digest_buff_dma_addr, - digestsize, NS_BIT, 0); - ssi_set_hash_endianity(ctx->hash_mode, &desc[idx]); - set_flow_mode(&desc[idx], S_HASH_to_DOUT); - set_setup_mode(&desc[idx], SETUP_WRITE_STATE0); - idx++; - - /* Loading hash OPAD xor key state */ - hw_desc_init(&desc[idx]); - set_cipher_mode(&desc[idx], ctx->hw_mode); - set_din_type(&desc[idx], DMA_DLLI, state->opad_digest_dma_addr, - ctx->inter_digestsize, NS_BIT); - set_flow_mode(&desc[idx], S_DIN_to_HASH); - set_setup_mode(&desc[idx], SETUP_LOAD_STATE0); - idx++; - - /* Load the hash current length */ - hw_desc_init(&desc[idx]); - set_cipher_mode(&desc[idx], ctx->hw_mode); - set_din_sram(&desc[idx], - ssi_ahash_get_initial_digest_len_sram_addr( -ctx->drvdata, ctx->hash_mode), HASH_LEN_SIZE); - set_cipher_config1(&desc[idx], HASH_PADDING_ENABLED); - set_flow_mode(&desc[idx], S_DIN_to_HASH); - set_setup_mode(&desc[idx], SETUP_LOAD_KEY0); - idx++; + /* Setup DX request structure */ + cc_req.user_cb = cc_hash_complete; + cc_req.user_arg = req; - /* Memory Barrier: wait for IPAD/OPAD axi write to complete */ - hw_desc_init(&desc[idx]); - set_din_no_dma(&desc[idx], 0, 0xfffff0); - set_dout_no_dma(&desc[idx], 0, 0, 1); - idx++; + idx = cc_restore_hash(desc, ctx, state, idx); - /* Perform HASH update on last digest */ - hw_desc_init(&desc[idx]); - set_din_type(&desc[idx], DMA_DLLI, state->digest_buff_dma_addr, - digestsize, NS_BIT); - set_flow_mode(&desc[idx], DIN_HASH); - idx++; - } + if (is_hmac) + idx = cc_fin_hmac(desc, req, idx); - /* Get final MAC result */ - hw_desc_init(&desc[idx]); - /* TODO */ - set_dout_dlli(&desc[idx], state->digest_result_dma_addr, digestsize, - NS_BIT, (async_req ? 1 : 0)); - if (async_req) - set_queue_last_ind(&desc[idx]); - set_flow_mode(&desc[idx], S_HASH_to_DOUT); - set_cipher_config1(&desc[idx], HASH_PADDING_DISABLED); - set_setup_mode(&desc[idx], SETUP_WRITE_STATE0); - ssi_set_hash_endianity(ctx->hash_mode, &desc[idx]); - set_cipher_mode(&desc[idx], ctx->hw_mode); - idx++; + idx = cc_fin_result(desc, req, idx); - if (async_req) { - rc = send_request(ctx->drvdata, &ssi_req, desc, idx, 1); - if (unlikely(rc != -EINPROGRESS)) { - dev_err(dev, "send_request() failed (rc=%d)\n", rc); - ssi_buffer_mgr_unmap_hash_request(dev, state, src, true); - ssi_hash_unmap_result(dev, state, digestsize, result); - } - } else { - rc = send_request(ctx->drvdata, &ssi_req, desc, idx, 0); - if (rc != 0) { - dev_err(dev, "send_request() failed (rc=%d)\n", rc); - ssi_buffer_mgr_unmap_hash_request(dev, state, src, true); - ssi_hash_unmap_result(dev, state, digestsize, result); - } else { - ssi_buffer_mgr_unmap_hash_request(dev, state, src, false); - ssi_hash_unmap_result(dev, state, digestsize, result); - ssi_hash_unmap_request(dev, state, ctx); - } + rc = cc_send_request(ctx->drvdata, &cc_req, desc, idx, &req->base); + if (rc != -EINPROGRESS && rc != -EBUSY) { + dev_err(dev, "send_request() failed (rc=%d)\n", rc); + cc_unmap_hash_request(dev, state, src, true); + cc_unmap_result(dev, state, digestsize, result); + cc_unmap_req(dev, state, ctx); } return rc; } -static int ssi_hash_final(struct ahash_req_ctx *state, - struct ssi_hash_ctx *ctx, - unsigned int digestsize, - struct scatterlist *src, - unsigned int nbytes, - u8 *result, - void *async_req) +static int cc_hash_final(struct ahash_request *req) { + struct ahash_req_ctx *state = ahash_request_ctx(req); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct cc_hash_ctx *ctx = crypto_ahash_ctx(tfm); + u32 digestsize = crypto_ahash_digestsize(tfm); + struct scatterlist *src = req->src; + unsigned int nbytes = req->nbytes; + u8 *result = req->result; struct device *dev = drvdata_to_dev(ctx->drvdata); bool is_hmac = ctx->is_hmac; - struct ssi_crypto_req ssi_req = {}; - struct cc_hw_desc desc[SSI_MAX_AHASH_SEQ_LEN]; + struct cc_crypto_req cc_req = {}; + struct cc_hw_desc desc[CC_MAX_HASH_SEQ_LEN]; int idx = 0; int rc; + gfp_t flags = cc_gfp_flags(&req->base); dev_dbg(dev, "===== %s-final (%d) ====\n", is_hmac ? "hmac" : "hash", nbytes); - if (unlikely(ssi_buffer_mgr_map_hash_request_final(ctx->drvdata, state, src, nbytes, 0) != 0)) { + if (cc_map_req(dev, state, ctx)) { + dev_err(dev, "map_ahash_source() failed\n"); + return -EINVAL; + } + + if (cc_map_hash_request_final(ctx->drvdata, state, src, nbytes, 0, + flags)) { dev_err(dev, "map_ahash_request_final() failed\n"); + cc_unmap_req(dev, state, ctx); return -ENOMEM; } - if (unlikely(ssi_hash_map_result(dev, state, digestsize) != 0)) { + if (cc_map_result(dev, state, digestsize)) { dev_err(dev, "map_ahash_digest() failed\n"); + cc_unmap_hash_request(dev, state, src, true); + cc_unmap_req(dev, state, ctx); return -ENOMEM; } - if (async_req) { - /* Setup DX request structure */ - ssi_req.user_cb = (void *)ssi_hash_complete; - ssi_req.user_arg = async_req; - } - - /* Restore hash digest */ - hw_desc_init(&desc[idx]); - set_cipher_mode(&desc[idx], ctx->hw_mode); - set_din_type(&desc[idx], DMA_DLLI, state->digest_buff_dma_addr, - ctx->inter_digestsize, NS_BIT); - set_flow_mode(&desc[idx], S_DIN_to_HASH); - set_setup_mode(&desc[idx], SETUP_LOAD_STATE0); - idx++; - - /* Restore hash current length */ - hw_desc_init(&desc[idx]); - set_cipher_mode(&desc[idx], ctx->hw_mode); - set_cipher_config1(&desc[idx], HASH_PADDING_DISABLED); - set_din_type(&desc[idx], DMA_DLLI, state->digest_bytes_len_dma_addr, - HASH_LEN_SIZE, NS_BIT); - set_flow_mode(&desc[idx], S_DIN_to_HASH); - set_setup_mode(&desc[idx], SETUP_LOAD_KEY0); - idx++; + /* Setup DX request structure */ + cc_req.user_cb = cc_hash_complete; + cc_req.user_arg = req; - ssi_hash_create_data_desc(state, ctx, DIN_HASH, desc, false, &idx); + idx = cc_restore_hash(desc, ctx, state, idx); /* "DO-PAD" must be enabled only when writing current length to HW */ hw_desc_init(&desc[idx]); @@ -862,121 +722,56 @@ static int ssi_hash_final(struct ahash_req_ctx *state, set_flow_mode(&desc[idx], S_HASH_to_DOUT); idx++; - if (is_hmac) { - /* Store the hash digest result in the context */ - hw_desc_init(&desc[idx]); - set_cipher_mode(&desc[idx], ctx->hw_mode); - set_dout_dlli(&desc[idx], state->digest_buff_dma_addr, - digestsize, NS_BIT, 0); - ssi_set_hash_endianity(ctx->hash_mode, &desc[idx]); - set_flow_mode(&desc[idx], S_HASH_to_DOUT); - set_setup_mode(&desc[idx], SETUP_WRITE_STATE0); - idx++; - - /* Loading hash OPAD xor key state */ - hw_desc_init(&desc[idx]); - set_cipher_mode(&desc[idx], ctx->hw_mode); - set_din_type(&desc[idx], DMA_DLLI, state->opad_digest_dma_addr, - ctx->inter_digestsize, NS_BIT); - set_flow_mode(&desc[idx], S_DIN_to_HASH); - set_setup_mode(&desc[idx], SETUP_LOAD_STATE0); - idx++; - - /* Load the hash current length */ - hw_desc_init(&desc[idx]); - set_cipher_mode(&desc[idx], ctx->hw_mode); - set_din_sram(&desc[idx], - ssi_ahash_get_initial_digest_len_sram_addr( -ctx->drvdata, ctx->hash_mode), HASH_LEN_SIZE); - set_cipher_config1(&desc[idx], HASH_PADDING_ENABLED); - set_flow_mode(&desc[idx], S_DIN_to_HASH); - set_setup_mode(&desc[idx], SETUP_LOAD_KEY0); - idx++; - - /* Memory Barrier: wait for IPAD/OPAD axi write to complete */ - hw_desc_init(&desc[idx]); - set_din_no_dma(&desc[idx], 0, 0xfffff0); - set_dout_no_dma(&desc[idx], 0, 0, 1); - idx++; - - /* Perform HASH update on last digest */ - hw_desc_init(&desc[idx]); - set_din_type(&desc[idx], DMA_DLLI, state->digest_buff_dma_addr, - digestsize, NS_BIT); - set_flow_mode(&desc[idx], DIN_HASH); - idx++; - } + if (is_hmac) + idx = cc_fin_hmac(desc, req, idx); - /* Get final MAC result */ - hw_desc_init(&desc[idx]); - set_dout_dlli(&desc[idx], state->digest_result_dma_addr, digestsize, - NS_BIT, (async_req ? 1 : 0)); - if (async_req) - set_queue_last_ind(&desc[idx]); - set_flow_mode(&desc[idx], S_HASH_to_DOUT); - set_cipher_config1(&desc[idx], HASH_PADDING_DISABLED); - set_setup_mode(&desc[idx], SETUP_WRITE_STATE0); - ssi_set_hash_endianity(ctx->hash_mode, &desc[idx]); - set_cipher_mode(&desc[idx], ctx->hw_mode); - idx++; + idx = cc_fin_result(desc, req, idx); - if (async_req) { - rc = send_request(ctx->drvdata, &ssi_req, desc, idx, 1); - if (unlikely(rc != -EINPROGRESS)) { - dev_err(dev, "send_request() failed (rc=%d)\n", rc); - ssi_buffer_mgr_unmap_hash_request(dev, state, src, true); - ssi_hash_unmap_result(dev, state, digestsize, result); - } - } else { - rc = send_request(ctx->drvdata, &ssi_req, desc, idx, 0); - if (rc != 0) { - dev_err(dev, "send_request() failed (rc=%d)\n", rc); - ssi_buffer_mgr_unmap_hash_request(dev, state, src, true); - ssi_hash_unmap_result(dev, state, digestsize, result); - } else { - ssi_buffer_mgr_unmap_hash_request(dev, state, src, false); - ssi_hash_unmap_result(dev, state, digestsize, result); - ssi_hash_unmap_request(dev, state, ctx); - } + rc = cc_send_request(ctx->drvdata, &cc_req, desc, idx, &req->base); + if (rc != -EINPROGRESS && rc != -EBUSY) { + dev_err(dev, "send_request() failed (rc=%d)\n", rc); + cc_unmap_hash_request(dev, state, src, true); + cc_unmap_result(dev, state, digestsize, result); + cc_unmap_req(dev, state, ctx); } return rc; } -static int ssi_hash_init(struct ahash_req_ctx *state, struct ssi_hash_ctx *ctx) +static int cc_hash_init(struct ahash_request *req) { + struct ahash_req_ctx *state = ahash_request_ctx(req); + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct cc_hash_ctx *ctx = crypto_ahash_ctx(tfm); struct device *dev = drvdata_to_dev(ctx->drvdata); - state->xcbc_count = 0; + dev_dbg(dev, "===== init (%d) ====\n", req->nbytes); - ssi_hash_map_request(dev, state, ctx); + cc_init_req(dev, state, ctx); return 0; } -static int ssi_hash_setkey(void *hash, - const u8 *key, - unsigned int keylen, - bool synchronize) +static int cc_hash_setkey(struct crypto_ahash *ahash, const u8 *key, + unsigned int keylen) { unsigned int hmac_pad_const[2] = { HMAC_IPAD_CONST, HMAC_OPAD_CONST }; - struct ssi_crypto_req ssi_req = {}; - struct ssi_hash_ctx *ctx = NULL; + struct cc_crypto_req cc_req = {}; + struct cc_hash_ctx *ctx = NULL; int blocksize = 0; int digestsize = 0; int i, idx = 0, rc = 0; - struct cc_hw_desc desc[SSI_MAX_AHASH_SEQ_LEN]; - ssi_sram_addr_t larval_addr; + struct cc_hw_desc desc[CC_MAX_HASH_SEQ_LEN]; + cc_sram_addr_t larval_addr; struct device *dev; - ctx = crypto_ahash_ctx(((struct crypto_ahash *)hash)); + ctx = crypto_ahash_ctx(ahash); dev = drvdata_to_dev(ctx->drvdata); dev_dbg(dev, "start keylen: %d", keylen); - blocksize = crypto_tfm_alg_blocksize(&((struct crypto_ahash *)hash)->base); - digestsize = crypto_ahash_digestsize(((struct crypto_ahash *)hash)); + blocksize = crypto_tfm_alg_blocksize(&ahash->base); + digestsize = crypto_ahash_digestsize(ahash); - larval_addr = ssi_ahash_get_larval_digest_sram_addr( - ctx->drvdata, ctx->hash_mode); + larval_addr = cc_larval_digest_addr(ctx->drvdata, ctx->hash_mode); /* The keylen value distinguishes HASH in case keylen is ZERO bytes, * any NON-ZERO value utilizes HMAC flow @@ -985,12 +780,10 @@ static int ssi_hash_setkey(void *hash, ctx->key_params.key_dma_addr = 0; ctx->is_hmac = true; - if (keylen != 0) { - ctx->key_params.key_dma_addr = dma_map_single( - dev, (void *)key, - keylen, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(dev, - ctx->key_params.key_dma_addr))) { + if (keylen) { + ctx->key_params.key_dma_addr = + dma_map_single(dev, (void *)key, keylen, DMA_TO_DEVICE); + if (dma_mapping_error(dev, ctx->key_params.key_dma_addr)) { dev_err(dev, "Mapping key va=0x%p len=%u for DMA failed\n", key, keylen); return -ENOMEM; @@ -1032,14 +825,15 @@ static int ssi_hash_setkey(void *hash, set_flow_mode(&desc[idx], S_HASH_to_DOUT); set_setup_mode(&desc[idx], SETUP_WRITE_STATE0); set_cipher_config1(&desc[idx], HASH_PADDING_DISABLED); - ssi_set_hash_endianity(ctx->hash_mode, &desc[idx]); + cc_set_endianity(ctx->hash_mode, &desc[idx]); idx++; hw_desc_init(&desc[idx]); set_din_const(&desc[idx], 0, (blocksize - digestsize)); set_flow_mode(&desc[idx], BYPASS); - set_dout_dlli(&desc[idx], (ctx->opad_tmp_keys_dma_addr + - digestsize), + set_dout_dlli(&desc[idx], + (ctx->opad_tmp_keys_dma_addr + + digestsize), (blocksize - digestsize), NS_BIT, 0); idx++; } else { @@ -1052,7 +846,7 @@ static int ssi_hash_setkey(void *hash, keylen, NS_BIT, 0); idx++; - if ((blocksize - keylen) != 0) { + if ((blocksize - keylen)) { hw_desc_init(&desc[idx]); set_din_const(&desc[idx], 0, (blocksize - keylen)); @@ -1073,8 +867,8 @@ static int ssi_hash_setkey(void *hash, idx++; } - rc = send_request(ctx->drvdata, &ssi_req, desc, idx, 0); - if (unlikely(rc != 0)) { + rc = cc_send_sync_request(ctx->drvdata, &cc_req, desc, idx); + if (rc) { dev_err(dev, "send_request() failed (rc=%d)\n", rc); goto out; } @@ -1114,7 +908,9 @@ static int ssi_hash_setkey(void *hash, set_flow_mode(&desc[idx], DIN_HASH); idx++; - /* Get the IPAD/OPAD xor key (Note, IPAD is the initial digest of the first HASH "update" state) */ + /* Get the IPAD/OPAD xor key (Note, IPAD is the initial digest + * of the first HASH "update" state) + */ hw_desc_init(&desc[idx]); set_cipher_mode(&desc[idx], ctx->hw_mode); if (i > 0) /* Not first iteration */ @@ -1128,11 +924,11 @@ static int ssi_hash_setkey(void *hash, idx++; } - rc = send_request(ctx->drvdata, &ssi_req, desc, idx, 0); + rc = cc_send_sync_request(ctx->drvdata, &cc_req, desc, idx); out: if (rc) - crypto_ahash_set_flags((struct crypto_ahash *)hash, CRYPTO_TFM_RES_BAD_KEY_LEN); + crypto_ahash_set_flags(ahash, CRYPTO_TFM_RES_BAD_KEY_LEN); if (ctx->key_params.key_dma_addr) { dma_unmap_single(dev, ctx->key_params.key_dma_addr, @@ -1143,14 +939,14 @@ out: return rc; } -static int ssi_xcbc_setkey(struct crypto_ahash *ahash, - const u8 *key, unsigned int keylen) +static int cc_xcbc_setkey(struct crypto_ahash *ahash, + const u8 *key, unsigned int keylen) { - struct ssi_crypto_req ssi_req = {}; - struct ssi_hash_ctx *ctx = crypto_ahash_ctx(ahash); + struct cc_crypto_req cc_req = {}; + struct cc_hash_ctx *ctx = crypto_ahash_ctx(ahash); struct device *dev = drvdata_to_dev(ctx->drvdata); int idx = 0, rc = 0; - struct cc_hw_desc desc[SSI_MAX_AHASH_SEQ_LEN]; + struct cc_hw_desc desc[CC_MAX_HASH_SEQ_LEN]; dev_dbg(dev, "===== setkey (%d) ====\n", keylen); @@ -1165,10 +961,9 @@ static int ssi_xcbc_setkey(struct crypto_ahash *ahash, ctx->key_params.keylen = keylen; - ctx->key_params.key_dma_addr = dma_map_single( - dev, (void *)key, - keylen, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(dev, ctx->key_params.key_dma_addr))) { + ctx->key_params.key_dma_addr = + dma_map_single(dev, (void *)key, keylen, DMA_TO_DEVICE); + if (dma_mapping_error(dev, ctx->key_params.key_dma_addr)) { dev_err(dev, "Mapping key va=0x%p len=%u for DMA failed\n", key, keylen); return -ENOMEM; @@ -1191,30 +986,30 @@ static int ssi_xcbc_setkey(struct crypto_ahash *ahash, hw_desc_init(&desc[idx]); set_din_const(&desc[idx], 0x01010101, CC_AES_128_BIT_KEY_SIZE); set_flow_mode(&desc[idx], DIN_AES_DOUT); - set_dout_dlli(&desc[idx], (ctx->opad_tmp_keys_dma_addr + - XCBC_MAC_K1_OFFSET), - CC_AES_128_BIT_KEY_SIZE, NS_BIT, 0); + set_dout_dlli(&desc[idx], + (ctx->opad_tmp_keys_dma_addr + XCBC_MAC_K1_OFFSET), + CC_AES_128_BIT_KEY_SIZE, NS_BIT, 0); idx++; hw_desc_init(&desc[idx]); set_din_const(&desc[idx], 0x02020202, CC_AES_128_BIT_KEY_SIZE); set_flow_mode(&desc[idx], DIN_AES_DOUT); - set_dout_dlli(&desc[idx], (ctx->opad_tmp_keys_dma_addr + - XCBC_MAC_K2_OFFSET), - CC_AES_128_BIT_KEY_SIZE, NS_BIT, 0); + set_dout_dlli(&desc[idx], + (ctx->opad_tmp_keys_dma_addr + XCBC_MAC_K2_OFFSET), + CC_AES_128_BIT_KEY_SIZE, NS_BIT, 0); idx++; hw_desc_init(&desc[idx]); set_din_const(&desc[idx], 0x03030303, CC_AES_128_BIT_KEY_SIZE); set_flow_mode(&desc[idx], DIN_AES_DOUT); - set_dout_dlli(&desc[idx], (ctx->opad_tmp_keys_dma_addr + - XCBC_MAC_K3_OFFSET), - CC_AES_128_BIT_KEY_SIZE, NS_BIT, 0); + set_dout_dlli(&desc[idx], + (ctx->opad_tmp_keys_dma_addr + XCBC_MAC_K3_OFFSET), + CC_AES_128_BIT_KEY_SIZE, NS_BIT, 0); idx++; - rc = send_request(ctx->drvdata, &ssi_req, desc, idx, 0); + rc = cc_send_sync_request(ctx->drvdata, &cc_req, desc, idx); - if (rc != 0) + if (rc) crypto_ahash_set_flags(ahash, CRYPTO_TFM_RES_BAD_KEY_LEN); dma_unmap_single(dev, ctx->key_params.key_dma_addr, @@ -1225,11 +1020,10 @@ static int ssi_xcbc_setkey(struct crypto_ahash *ahash, return rc; } -#if SSI_CC_HAS_CMAC -static int ssi_cmac_setkey(struct crypto_ahash *ahash, - const u8 *key, unsigned int keylen) +static int cc_cmac_setkey(struct crypto_ahash *ahash, + const u8 *key, unsigned int keylen) { - struct ssi_hash_ctx *ctx = crypto_ahash_ctx(ahash); + struct cc_hash_ctx *ctx = crypto_ahash_ctx(ahash); struct device *dev = drvdata_to_dev(ctx->drvdata); dev_dbg(dev, "===== setkey (%d) ====\n", keylen); @@ -1253,8 +1047,10 @@ static int ssi_cmac_setkey(struct crypto_ahash *ahash, keylen, DMA_TO_DEVICE); memcpy(ctx->opad_tmp_keys_buff, key, keylen); - if (keylen == 24) - memset(ctx->opad_tmp_keys_buff + 24, 0, CC_AES_KEY_SIZE_MAX - 24); + if (keylen == 24) { + memset(ctx->opad_tmp_keys_buff + 24, 0, + CC_AES_KEY_SIZE_MAX - 24); + } dma_sync_single_for_device(dev, ctx->opad_tmp_keys_dma_addr, keylen, DMA_TO_DEVICE); @@ -1263,20 +1059,19 @@ static int ssi_cmac_setkey(struct crypto_ahash *ahash, return 0; } -#endif -static void ssi_hash_free_ctx(struct ssi_hash_ctx *ctx) +static void cc_free_ctx(struct cc_hash_ctx *ctx) { struct device *dev = drvdata_to_dev(ctx->drvdata); - if (ctx->digest_buff_dma_addr != 0) { + if (ctx->digest_buff_dma_addr) { dma_unmap_single(dev, ctx->digest_buff_dma_addr, sizeof(ctx->digest_buff), DMA_BIDIRECTIONAL); dev_dbg(dev, "Unmapped digest-buffer: digest_buff_dma_addr=%pad\n", &ctx->digest_buff_dma_addr); ctx->digest_buff_dma_addr = 0; } - if (ctx->opad_tmp_keys_dma_addr != 0) { + if (ctx->opad_tmp_keys_dma_addr) { dma_unmap_single(dev, ctx->opad_tmp_keys_dma_addr, sizeof(ctx->opad_tmp_keys_buff), DMA_BIDIRECTIONAL); @@ -1288,13 +1083,15 @@ static void ssi_hash_free_ctx(struct ssi_hash_ctx *ctx) ctx->key_params.keylen = 0; } -static int ssi_hash_alloc_ctx(struct ssi_hash_ctx *ctx) +static int cc_alloc_ctx(struct cc_hash_ctx *ctx) { struct device *dev = drvdata_to_dev(ctx->drvdata); ctx->key_params.keylen = 0; - ctx->digest_buff_dma_addr = dma_map_single(dev, (void *)ctx->digest_buff, sizeof(ctx->digest_buff), DMA_BIDIRECTIONAL); + ctx->digest_buff_dma_addr = + dma_map_single(dev, (void *)ctx->digest_buff, + sizeof(ctx->digest_buff), DMA_BIDIRECTIONAL); if (dma_mapping_error(dev, ctx->digest_buff_dma_addr)) { dev_err(dev, "Mapping digest len %zu B at va=%pK for DMA failed\n", sizeof(ctx->digest_buff), ctx->digest_buff); @@ -1304,7 +1101,10 @@ static int ssi_hash_alloc_ctx(struct ssi_hash_ctx *ctx) sizeof(ctx->digest_buff), ctx->digest_buff, &ctx->digest_buff_dma_addr); - ctx->opad_tmp_keys_dma_addr = dma_map_single(dev, (void *)ctx->opad_tmp_keys_buff, sizeof(ctx->opad_tmp_keys_buff), DMA_BIDIRECTIONAL); + ctx->opad_tmp_keys_dma_addr = + dma_map_single(dev, (void *)ctx->opad_tmp_keys_buff, + sizeof(ctx->opad_tmp_keys_buff), + DMA_BIDIRECTIONAL); if (dma_mapping_error(dev, ctx->opad_tmp_keys_dma_addr)) { dev_err(dev, "Mapping opad digest %zu B at va=%pK for DMA failed\n", sizeof(ctx->opad_tmp_keys_buff), @@ -1319,51 +1119,52 @@ static int ssi_hash_alloc_ctx(struct ssi_hash_ctx *ctx) return 0; fail: - ssi_hash_free_ctx(ctx); + cc_free_ctx(ctx); return -ENOMEM; } -static int ssi_ahash_cra_init(struct crypto_tfm *tfm) +static int cc_cra_init(struct crypto_tfm *tfm) { - struct ssi_hash_ctx *ctx = crypto_tfm_ctx(tfm); + struct cc_hash_ctx *ctx = crypto_tfm_ctx(tfm); struct hash_alg_common *hash_alg_common = container_of(tfm->__crt_alg, struct hash_alg_common, base); struct ahash_alg *ahash_alg = container_of(hash_alg_common, struct ahash_alg, halg); - struct ssi_hash_alg *ssi_alg = - container_of(ahash_alg, struct ssi_hash_alg, ahash_alg); + struct cc_hash_alg *cc_alg = + container_of(ahash_alg, struct cc_hash_alg, ahash_alg); crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), sizeof(struct ahash_req_ctx)); - ctx->hash_mode = ssi_alg->hash_mode; - ctx->hw_mode = ssi_alg->hw_mode; - ctx->inter_digestsize = ssi_alg->inter_digestsize; - ctx->drvdata = ssi_alg->drvdata; + ctx->hash_mode = cc_alg->hash_mode; + ctx->hw_mode = cc_alg->hw_mode; + ctx->inter_digestsize = cc_alg->inter_digestsize; + ctx->drvdata = cc_alg->drvdata; - return ssi_hash_alloc_ctx(ctx); + return cc_alloc_ctx(ctx); } -static void ssi_hash_cra_exit(struct crypto_tfm *tfm) +static void cc_cra_exit(struct crypto_tfm *tfm) { - struct ssi_hash_ctx *ctx = crypto_tfm_ctx(tfm); + struct cc_hash_ctx *ctx = crypto_tfm_ctx(tfm); struct device *dev = drvdata_to_dev(ctx->drvdata); - dev_dbg(dev, "ssi_hash_cra_exit"); - ssi_hash_free_ctx(ctx); + dev_dbg(dev, "cc_cra_exit"); + cc_free_ctx(ctx); } -static int ssi_mac_update(struct ahash_request *req) +static int cc_mac_update(struct ahash_request *req) { struct ahash_req_ctx *state = ahash_request_ctx(req); struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct ssi_hash_ctx *ctx = crypto_ahash_ctx(tfm); + struct cc_hash_ctx *ctx = crypto_ahash_ctx(tfm); struct device *dev = drvdata_to_dev(ctx->drvdata); unsigned int block_size = crypto_tfm_alg_blocksize(&tfm->base); - struct ssi_crypto_req ssi_req = {}; - struct cc_hw_desc desc[SSI_MAX_AHASH_SEQ_LEN]; + struct cc_crypto_req cc_req = {}; + struct cc_hw_desc desc[CC_MAX_HASH_SEQ_LEN]; int rc; u32 idx = 0; + gfp_t flags = cc_gfp_flags(&req->base); if (req->nbytes == 0) { /* no real updates required */ @@ -1372,8 +1173,9 @@ static int ssi_mac_update(struct ahash_request *req) state->xcbc_count++; - rc = ssi_buffer_mgr_map_hash_request_update(ctx->drvdata, state, req->src, req->nbytes, block_size); - if (unlikely(rc)) { + rc = cc_map_hash_request_update(ctx->drvdata, state, req->src, + req->nbytes, block_size, flags); + if (rc) { if (rc == 1) { dev_dbg(dev, " data size not require HW update %x\n", req->nbytes); @@ -1384,12 +1186,17 @@ static int ssi_mac_update(struct ahash_request *req) return -ENOMEM; } + if (cc_map_req(dev, state, ctx)) { + dev_err(dev, "map_ahash_source() failed\n"); + return -EINVAL; + } + if (ctx->hw_mode == DRV_CIPHER_XCBC_MAC) - ssi_hash_create_xcbc_setup(req, desc, &idx); + cc_setup_xcbc(req, desc, &idx); else - ssi_hash_create_cmac_setup(req, desc, &idx); + cc_setup_cmac(req, desc, &idx); - ssi_hash_create_data_desc(state, ctx, DIN_AES_DOUT, desc, true, &idx); + cc_set_desc(state, ctx, DIN_AES_DOUT, desc, true, &idx); /* store the hash digest result in context */ hw_desc_init(&desc[idx]); @@ -1402,32 +1209,32 @@ static int ssi_mac_update(struct ahash_request *req) idx++; /* Setup DX request structure */ - ssi_req.user_cb = (void *)ssi_hash_update_complete; - ssi_req.user_arg = (void *)req; + cc_req.user_cb = (void *)cc_update_complete; + cc_req.user_arg = (void *)req; - rc = send_request(ctx->drvdata, &ssi_req, desc, idx, 1); - if (unlikely(rc != -EINPROGRESS)) { + rc = cc_send_request(ctx->drvdata, &cc_req, desc, idx, &req->base); + if (rc != -EINPROGRESS && rc != -EBUSY) { dev_err(dev, "send_request() failed (rc=%d)\n", rc); - ssi_buffer_mgr_unmap_hash_request(dev, state, req->src, true); + cc_unmap_hash_request(dev, state, req->src, true); + cc_unmap_req(dev, state, ctx); } return rc; } -static int ssi_mac_final(struct ahash_request *req) +static int cc_mac_final(struct ahash_request *req) { struct ahash_req_ctx *state = ahash_request_ctx(req); struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct ssi_hash_ctx *ctx = crypto_ahash_ctx(tfm); + struct cc_hash_ctx *ctx = crypto_ahash_ctx(tfm); struct device *dev = drvdata_to_dev(ctx->drvdata); - struct ssi_crypto_req ssi_req = {}; - struct cc_hw_desc desc[SSI_MAX_AHASH_SEQ_LEN]; + struct cc_crypto_req cc_req = {}; + struct cc_hw_desc desc[CC_MAX_HASH_SEQ_LEN]; int idx = 0; int rc = 0; u32 key_size, key_len; u32 digestsize = crypto_ahash_digestsize(tfm); - - u32 rem_cnt = state->buff_index ? state->buff1_cnt : - state->buff0_cnt; + gfp_t flags = cc_gfp_flags(&req->base); + u32 rem_cnt = *cc_hash_buf_cnt(state); if (ctx->hw_mode == DRV_CIPHER_XCBC_MAC) { key_size = CC_AES_128_BIT_KEY_SIZE; @@ -1440,34 +1247,45 @@ static int ssi_mac_final(struct ahash_request *req) dev_dbg(dev, "===== final xcbc reminder (%d) ====\n", rem_cnt); - if (unlikely(ssi_buffer_mgr_map_hash_request_final(ctx->drvdata, state, req->src, req->nbytes, 0) != 0)) { + if (cc_map_req(dev, state, ctx)) { + dev_err(dev, "map_ahash_source() failed\n"); + return -EINVAL; + } + + if (cc_map_hash_request_final(ctx->drvdata, state, req->src, + req->nbytes, 0, flags)) { dev_err(dev, "map_ahash_request_final() failed\n"); + cc_unmap_req(dev, state, ctx); return -ENOMEM; } - if (unlikely(ssi_hash_map_result(dev, state, digestsize) != 0)) { + if (cc_map_result(dev, state, digestsize)) { dev_err(dev, "map_ahash_digest() failed\n"); + cc_unmap_hash_request(dev, state, req->src, true); + cc_unmap_req(dev, state, ctx); return -ENOMEM; } /* Setup DX request structure */ - ssi_req.user_cb = (void *)ssi_hash_complete; - ssi_req.user_arg = (void *)req; + cc_req.user_cb = (void *)cc_hash_complete; + cc_req.user_arg = (void *)req; - if (state->xcbc_count && (rem_cnt == 0)) { + if (state->xcbc_count && rem_cnt == 0) { /* Load key for ECB decryption */ hw_desc_init(&desc[idx]); set_cipher_mode(&desc[idx], DRV_CIPHER_ECB); set_cipher_config0(&desc[idx], DRV_CRYPTO_DIRECTION_DECRYPT); set_din_type(&desc[idx], DMA_DLLI, - (ctx->opad_tmp_keys_dma_addr + - XCBC_MAC_K1_OFFSET), key_size, NS_BIT); + (ctx->opad_tmp_keys_dma_addr + XCBC_MAC_K1_OFFSET), + key_size, NS_BIT); set_key_size_aes(&desc[idx], key_len); set_flow_mode(&desc[idx], S_DIN_to_AES); set_setup_mode(&desc[idx], SETUP_LOAD_KEY0); idx++; - /* Initiate decryption of block state to previous block_state-XOR-M[n] */ + /* Initiate decryption of block state to previous + * block_state-XOR-M[n] + */ hw_desc_init(&desc[idx]); set_din_type(&desc[idx], DMA_DLLI, state->digest_buff_dma_addr, CC_AES_BLOCK_SIZE, NS_BIT); @@ -1484,9 +1302,9 @@ static int ssi_mac_final(struct ahash_request *req) } if (ctx->hw_mode == DRV_CIPHER_XCBC_MAC) - ssi_hash_create_xcbc_setup(req, desc, &idx); + cc_setup_xcbc(req, desc, &idx); else - ssi_hash_create_cmac_setup(req, desc, &idx); + cc_setup_cmac(req, desc, &idx); if (state->xcbc_count == 0) { hw_desc_init(&desc[idx]); @@ -1496,7 +1314,7 @@ static int ssi_mac_final(struct ahash_request *req) set_flow_mode(&desc[idx], S_DIN_to_AES); idx++; } else if (rem_cnt > 0) { - ssi_hash_create_data_desc(state, ctx, DIN_AES_DOUT, desc, false, &idx); + cc_set_desc(state, ctx, DIN_AES_DOUT, desc, false, &idx); } else { hw_desc_init(&desc[idx]); set_din_const(&desc[idx], 0x00, CC_AES_BLOCK_SIZE); @@ -1515,53 +1333,64 @@ static int ssi_mac_final(struct ahash_request *req) set_cipher_mode(&desc[idx], ctx->hw_mode); idx++; - rc = send_request(ctx->drvdata, &ssi_req, desc, idx, 1); - if (unlikely(rc != -EINPROGRESS)) { + rc = cc_send_request(ctx->drvdata, &cc_req, desc, idx, &req->base); + if (rc != -EINPROGRESS && rc != -EBUSY) { dev_err(dev, "send_request() failed (rc=%d)\n", rc); - ssi_buffer_mgr_unmap_hash_request(dev, state, req->src, true); - ssi_hash_unmap_result(dev, state, digestsize, req->result); + cc_unmap_hash_request(dev, state, req->src, true); + cc_unmap_result(dev, state, digestsize, req->result); + cc_unmap_req(dev, state, ctx); } return rc; } -static int ssi_mac_finup(struct ahash_request *req) +static int cc_mac_finup(struct ahash_request *req) { struct ahash_req_ctx *state = ahash_request_ctx(req); struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct ssi_hash_ctx *ctx = crypto_ahash_ctx(tfm); + struct cc_hash_ctx *ctx = crypto_ahash_ctx(tfm); struct device *dev = drvdata_to_dev(ctx->drvdata); - struct ssi_crypto_req ssi_req = {}; - struct cc_hw_desc desc[SSI_MAX_AHASH_SEQ_LEN]; + struct cc_crypto_req cc_req = {}; + struct cc_hw_desc desc[CC_MAX_HASH_SEQ_LEN]; int idx = 0; int rc = 0; u32 key_len = 0; u32 digestsize = crypto_ahash_digestsize(tfm); + gfp_t flags = cc_gfp_flags(&req->base); dev_dbg(dev, "===== finup xcbc(%d) ====\n", req->nbytes); if (state->xcbc_count > 0 && req->nbytes == 0) { dev_dbg(dev, "No data to update. Call to fdx_mac_final\n"); - return ssi_mac_final(req); + return cc_mac_final(req); + } + + if (cc_map_req(dev, state, ctx)) { + dev_err(dev, "map_ahash_source() failed\n"); + return -EINVAL; } - if (unlikely(ssi_buffer_mgr_map_hash_request_final(ctx->drvdata, state, req->src, req->nbytes, 1) != 0)) { + if (cc_map_hash_request_final(ctx->drvdata, state, req->src, + req->nbytes, 1, flags)) { dev_err(dev, "map_ahash_request_final() failed\n"); + cc_unmap_req(dev, state, ctx); return -ENOMEM; } - if (unlikely(ssi_hash_map_result(dev, state, digestsize) != 0)) { + if (cc_map_result(dev, state, digestsize)) { dev_err(dev, "map_ahash_digest() failed\n"); + cc_unmap_hash_request(dev, state, req->src, true); + cc_unmap_req(dev, state, ctx); return -ENOMEM; } /* Setup DX request structure */ - ssi_req.user_cb = (void *)ssi_hash_complete; - ssi_req.user_arg = (void *)req; + cc_req.user_cb = (void *)cc_hash_complete; + cc_req.user_arg = (void *)req; if (ctx->hw_mode == DRV_CIPHER_XCBC_MAC) { key_len = CC_AES_128_BIT_KEY_SIZE; - ssi_hash_create_xcbc_setup(req, desc, &idx); + cc_setup_xcbc(req, desc, &idx); } else { key_len = ctx->key_params.keylen; - ssi_hash_create_cmac_setup(req, desc, &idx); + cc_setup_cmac(req, desc, &idx); } if (req->nbytes == 0) { @@ -1572,7 +1401,7 @@ static int ssi_mac_finup(struct ahash_request *req) set_flow_mode(&desc[idx], S_DIN_to_AES); idx++; } else { - ssi_hash_create_data_desc(state, ctx, DIN_AES_DOUT, desc, false, &idx); + cc_set_desc(state, ctx, DIN_AES_DOUT, desc, false, &idx); } /* Get final MAC result */ @@ -1586,54 +1415,61 @@ static int ssi_mac_finup(struct ahash_request *req) set_cipher_mode(&desc[idx], ctx->hw_mode); idx++; - rc = send_request(ctx->drvdata, &ssi_req, desc, idx, 1); - if (unlikely(rc != -EINPROGRESS)) { + rc = cc_send_request(ctx->drvdata, &cc_req, desc, idx, &req->base); + if (rc != -EINPROGRESS && rc != -EBUSY) { dev_err(dev, "send_request() failed (rc=%d)\n", rc); - ssi_buffer_mgr_unmap_hash_request(dev, state, req->src, true); - ssi_hash_unmap_result(dev, state, digestsize, req->result); + cc_unmap_hash_request(dev, state, req->src, true); + cc_unmap_result(dev, state, digestsize, req->result); + cc_unmap_req(dev, state, ctx); } return rc; } -static int ssi_mac_digest(struct ahash_request *req) +static int cc_mac_digest(struct ahash_request *req) { struct ahash_req_ctx *state = ahash_request_ctx(req); struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct ssi_hash_ctx *ctx = crypto_ahash_ctx(tfm); + struct cc_hash_ctx *ctx = crypto_ahash_ctx(tfm); struct device *dev = drvdata_to_dev(ctx->drvdata); u32 digestsize = crypto_ahash_digestsize(tfm); - struct ssi_crypto_req ssi_req = {}; - struct cc_hw_desc desc[SSI_MAX_AHASH_SEQ_LEN]; + struct cc_crypto_req cc_req = {}; + struct cc_hw_desc desc[CC_MAX_HASH_SEQ_LEN]; u32 key_len; int idx = 0; int rc; + gfp_t flags = cc_gfp_flags(&req->base); dev_dbg(dev, "===== -digest mac (%d) ====\n", req->nbytes); - if (unlikely(ssi_hash_map_request(dev, state, ctx) != 0)) { + cc_init_req(dev, state, ctx); + + if (cc_map_req(dev, state, ctx)) { dev_err(dev, "map_ahash_source() failed\n"); return -ENOMEM; } - if (unlikely(ssi_hash_map_result(dev, state, digestsize) != 0)) { + if (cc_map_result(dev, state, digestsize)) { dev_err(dev, "map_ahash_digest() failed\n"); + cc_unmap_req(dev, state, ctx); return -ENOMEM; } - if (unlikely(ssi_buffer_mgr_map_hash_request_final(ctx->drvdata, state, req->src, req->nbytes, 1) != 0)) { + if (cc_map_hash_request_final(ctx->drvdata, state, req->src, + req->nbytes, 1, flags)) { dev_err(dev, "map_ahash_request_final() failed\n"); + cc_unmap_req(dev, state, ctx); return -ENOMEM; } /* Setup DX request structure */ - ssi_req.user_cb = (void *)ssi_hash_digest_complete; - ssi_req.user_arg = (void *)req; + cc_req.user_cb = (void *)cc_digest_complete; + cc_req.user_arg = (void *)req; if (ctx->hw_mode == DRV_CIPHER_XCBC_MAC) { key_len = CC_AES_128_BIT_KEY_SIZE; - ssi_hash_create_xcbc_setup(req, desc, &idx); + cc_setup_xcbc(req, desc, &idx); } else { key_len = ctx->key_params.keylen; - ssi_hash_create_cmac_setup(req, desc, &idx); + cc_setup_cmac(req, desc, &idx); } if (req->nbytes == 0) { @@ -1644,7 +1480,7 @@ static int ssi_mac_digest(struct ahash_request *req) set_flow_mode(&desc[idx], S_DIN_to_AES); idx++; } else { - ssi_hash_create_data_desc(state, ctx, DIN_AES_DOUT, desc, false, &idx); + cc_set_desc(state, ctx, DIN_AES_DOUT, desc, false, &idx); } /* Get final MAC result */ @@ -1658,96 +1494,32 @@ static int ssi_mac_digest(struct ahash_request *req) set_cipher_mode(&desc[idx], ctx->hw_mode); idx++; - rc = send_request(ctx->drvdata, &ssi_req, desc, idx, 1); - if (unlikely(rc != -EINPROGRESS)) { + rc = cc_send_request(ctx->drvdata, &cc_req, desc, idx, &req->base); + if (rc != -EINPROGRESS && rc != -EBUSY) { dev_err(dev, "send_request() failed (rc=%d)\n", rc); - ssi_buffer_mgr_unmap_hash_request(dev, state, req->src, true); - ssi_hash_unmap_result(dev, state, digestsize, req->result); - ssi_hash_unmap_request(dev, state, ctx); + cc_unmap_hash_request(dev, state, req->src, true); + cc_unmap_result(dev, state, digestsize, req->result); + cc_unmap_req(dev, state, ctx); } return rc; } -//ahash wrap functions -static int ssi_ahash_digest(struct ahash_request *req) -{ - struct ahash_req_ctx *state = ahash_request_ctx(req); - struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct ssi_hash_ctx *ctx = crypto_ahash_ctx(tfm); - u32 digestsize = crypto_ahash_digestsize(tfm); - - return ssi_hash_digest(state, ctx, digestsize, req->src, req->nbytes, req->result, (void *)req); -} - -static int ssi_ahash_update(struct ahash_request *req) -{ - struct ahash_req_ctx *state = ahash_request_ctx(req); - struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct ssi_hash_ctx *ctx = crypto_ahash_ctx(tfm); - unsigned int block_size = crypto_tfm_alg_blocksize(&tfm->base); - - return ssi_hash_update(state, ctx, block_size, req->src, req->nbytes, (void *)req); -} - -static int ssi_ahash_finup(struct ahash_request *req) -{ - struct ahash_req_ctx *state = ahash_request_ctx(req); - struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct ssi_hash_ctx *ctx = crypto_ahash_ctx(tfm); - u32 digestsize = crypto_ahash_digestsize(tfm); - - return ssi_hash_finup(state, ctx, digestsize, req->src, req->nbytes, req->result, (void *)req); -} - -static int ssi_ahash_final(struct ahash_request *req) -{ - struct ahash_req_ctx *state = ahash_request_ctx(req); - struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct ssi_hash_ctx *ctx = crypto_ahash_ctx(tfm); - u32 digestsize = crypto_ahash_digestsize(tfm); - - return ssi_hash_final(state, ctx, digestsize, req->src, req->nbytes, req->result, (void *)req); -} - -static int ssi_ahash_init(struct ahash_request *req) -{ - struct ahash_req_ctx *state = ahash_request_ctx(req); - struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); - struct ssi_hash_ctx *ctx = crypto_ahash_ctx(tfm); - struct device *dev = drvdata_to_dev(ctx->drvdata); - - dev_dbg(dev, "===== init (%d) ====\n", req->nbytes); - - return ssi_hash_init(state, ctx); -} - -static int ssi_ahash_export(struct ahash_request *req, void *out) +static int cc_hash_export(struct ahash_request *req, void *out) { struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); - struct ssi_hash_ctx *ctx = crypto_ahash_ctx(ahash); - struct device *dev = drvdata_to_dev(ctx->drvdata); + struct cc_hash_ctx *ctx = crypto_ahash_ctx(ahash); struct ahash_req_ctx *state = ahash_request_ctx(req); - u8 *curr_buff = state->buff_index ? state->buff1 : state->buff0; - u32 curr_buff_cnt = state->buff_index ? state->buff1_cnt : - state->buff0_cnt; + u8 *curr_buff = cc_hash_buf(state); + u32 curr_buff_cnt = *cc_hash_buf_cnt(state); const u32 tmp = CC_EXPORT_MAGIC; memcpy(out, &tmp, sizeof(u32)); out += sizeof(u32); - dma_sync_single_for_cpu(dev, state->digest_buff_dma_addr, - ctx->inter_digestsize, DMA_BIDIRECTIONAL); memcpy(out, state->digest_buff, ctx->inter_digestsize); out += ctx->inter_digestsize; - if (state->digest_bytes_len_dma_addr) { - dma_sync_single_for_cpu(dev, state->digest_bytes_len_dma_addr, - HASH_LEN_SIZE, DMA_BIDIRECTIONAL); - memcpy(out, state->digest_bytes_len, HASH_LEN_SIZE); - } else { - /* Poison the unused exported digest len field. */ - memset(out, 0x5F, HASH_LEN_SIZE); - } + memcpy(out, state->digest_bytes_len, HASH_LEN_SIZE); out += HASH_LEN_SIZE; memcpy(out, &curr_buff_cnt, sizeof(u32)); @@ -1755,80 +1527,43 @@ static int ssi_ahash_export(struct ahash_request *req, void *out) memcpy(out, curr_buff, curr_buff_cnt); - /* No sync for device ineeded since we did not change the data, - * we only copy it - */ - return 0; } -static int ssi_ahash_import(struct ahash_request *req, const void *in) +static int cc_hash_import(struct ahash_request *req, const void *in) { struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); - struct ssi_hash_ctx *ctx = crypto_ahash_ctx(ahash); + struct cc_hash_ctx *ctx = crypto_ahash_ctx(ahash); struct device *dev = drvdata_to_dev(ctx->drvdata); struct ahash_req_ctx *state = ahash_request_ctx(req); u32 tmp; - int rc = 0; memcpy(&tmp, in, sizeof(u32)); - if (tmp != CC_EXPORT_MAGIC) { - rc = -EINVAL; - goto out; - } + if (tmp != CC_EXPORT_MAGIC) + return -EINVAL; in += sizeof(u32); - /* call init() to allocate bufs if the user hasn't */ - if (!state->digest_buff) { - rc = ssi_hash_init(state, ctx); - if (rc) - goto out; - } + cc_init_req(dev, state, ctx); - dma_sync_single_for_cpu(dev, state->digest_buff_dma_addr, - ctx->inter_digestsize, DMA_BIDIRECTIONAL); memcpy(state->digest_buff, in, ctx->inter_digestsize); in += ctx->inter_digestsize; - if (state->digest_bytes_len_dma_addr) { - dma_sync_single_for_cpu(dev, state->digest_bytes_len_dma_addr, - HASH_LEN_SIZE, DMA_BIDIRECTIONAL); - memcpy(state->digest_bytes_len, in, HASH_LEN_SIZE); - } + memcpy(state->digest_bytes_len, in, HASH_LEN_SIZE); in += HASH_LEN_SIZE; - dma_sync_single_for_device(dev, state->digest_buff_dma_addr, - ctx->inter_digestsize, DMA_BIDIRECTIONAL); - - if (state->digest_bytes_len_dma_addr) - dma_sync_single_for_device(dev, - state->digest_bytes_len_dma_addr, - HASH_LEN_SIZE, DMA_BIDIRECTIONAL); - - state->buff_index = 0; - /* Sanity check the data as much as possible */ memcpy(&tmp, in, sizeof(u32)); - if (tmp > SSI_MAX_HASH_BLCK_SIZE) { - rc = -EINVAL; - goto out; - } + if (tmp > CC_MAX_HASH_BLCK_SIZE) + return -EINVAL; in += sizeof(u32); - state->buff0_cnt = tmp; - memcpy(state->buff0, in, state->buff0_cnt); - -out: - return rc; -} + state->buf_cnt[0] = tmp; + memcpy(state->buffers[0], in, tmp); -static int ssi_ahash_setkey(struct crypto_ahash *ahash, - const u8 *key, unsigned int keylen) -{ - return ssi_hash_setkey((void *)ahash, key, keylen, false); + return 0; } -struct ssi_hash_template { +struct cc_hash_template { char name[CRYPTO_MAX_ALG_NAME]; char driver_name[CRYPTO_MAX_ALG_NAME]; char mac_name[CRYPTO_MAX_ALG_NAME]; @@ -1839,14 +1574,14 @@ struct ssi_hash_template { int hash_mode; int hw_mode; int inter_digestsize; - struct ssi_drvdata *drvdata; + struct cc_drvdata *drvdata; }; #define CC_STATE_SIZE(_x) \ - ((_x) + HASH_LEN_SIZE + SSI_MAX_HASH_BLCK_SIZE + (2 * sizeof(u32))) + ((_x) + HASH_LEN_SIZE + CC_MAX_HASH_BLCK_SIZE + (2 * sizeof(u32))) /* hash descriptors */ -static struct ssi_hash_template driver_hash[] = { +static struct cc_hash_template driver_hash[] = { //Asynchronize hash template { .name = "sha1", @@ -1856,14 +1591,14 @@ static struct ssi_hash_template driver_hash[] = { .blocksize = SHA1_BLOCK_SIZE, .synchronize = false, .template_ahash = { - .init = ssi_ahash_init, - .update = ssi_ahash_update, - .final = ssi_ahash_final, - .finup = ssi_ahash_finup, - .digest = ssi_ahash_digest, - .export = ssi_ahash_export, - .import = ssi_ahash_import, - .setkey = ssi_ahash_setkey, + .init = cc_hash_init, + .update = cc_hash_update, + .final = cc_hash_final, + .finup = cc_hash_finup, + .digest = cc_hash_digest, + .export = cc_hash_export, + .import = cc_hash_import, + .setkey = cc_hash_setkey, .halg = { .digestsize = SHA1_DIGEST_SIZE, .statesize = CC_STATE_SIZE(SHA1_DIGEST_SIZE), @@ -1880,14 +1615,14 @@ static struct ssi_hash_template driver_hash[] = { .mac_driver_name = "hmac-sha256-dx", .blocksize = SHA256_BLOCK_SIZE, .template_ahash = { - .init = ssi_ahash_init, - .update = ssi_ahash_update, - .final = ssi_ahash_final, - .finup = ssi_ahash_finup, - .digest = ssi_ahash_digest, - .export = ssi_ahash_export, - .import = ssi_ahash_import, - .setkey = ssi_ahash_setkey, + .init = cc_hash_init, + .update = cc_hash_update, + .final = cc_hash_final, + .finup = cc_hash_finup, + .digest = cc_hash_digest, + .export = cc_hash_export, + .import = cc_hash_import, + .setkey = cc_hash_setkey, .halg = { .digestsize = SHA256_DIGEST_SIZE, .statesize = CC_STATE_SIZE(SHA256_DIGEST_SIZE) @@ -1904,14 +1639,14 @@ static struct ssi_hash_template driver_hash[] = { .mac_driver_name = "hmac-sha224-dx", .blocksize = SHA224_BLOCK_SIZE, .template_ahash = { - .init = ssi_ahash_init, - .update = ssi_ahash_update, - .final = ssi_ahash_final, - .finup = ssi_ahash_finup, - .digest = ssi_ahash_digest, - .export = ssi_ahash_export, - .import = ssi_ahash_import, - .setkey = ssi_ahash_setkey, + .init = cc_hash_init, + .update = cc_hash_update, + .final = cc_hash_final, + .finup = cc_hash_finup, + .digest = cc_hash_digest, + .export = cc_hash_export, + .import = cc_hash_import, + .setkey = cc_hash_setkey, .halg = { .digestsize = SHA224_DIGEST_SIZE, .statesize = CC_STATE_SIZE(SHA224_DIGEST_SIZE), @@ -1921,7 +1656,7 @@ static struct ssi_hash_template driver_hash[] = { .hw_mode = DRV_HASH_HW_SHA256, .inter_digestsize = SHA256_DIGEST_SIZE, }, -#if (DX_DEV_SHA_MAX > 256) +#if (CC_DEV_SHA_MAX > 256) { .name = "sha384", .driver_name = "sha384-dx", @@ -1929,14 +1664,14 @@ static struct ssi_hash_template driver_hash[] = { .mac_driver_name = "hmac-sha384-dx", .blocksize = SHA384_BLOCK_SIZE, .template_ahash = { - .init = ssi_ahash_init, - .update = ssi_ahash_update, - .final = ssi_ahash_final, - .finup = ssi_ahash_finup, - .digest = ssi_ahash_digest, - .export = ssi_ahash_export, - .import = ssi_ahash_import, - .setkey = ssi_ahash_setkey, + .init = cc_hash_init, + .update = cc_hash_update, + .final = cc_hash_final, + .finup = cc_hash_finup, + .digest = cc_hash_digest, + .export = cc_hash_export, + .import = cc_hash_import, + .setkey = cc_hash_setkey, .halg = { .digestsize = SHA384_DIGEST_SIZE, .statesize = CC_STATE_SIZE(SHA384_DIGEST_SIZE), @@ -1953,14 +1688,14 @@ static struct ssi_hash_template driver_hash[] = { .mac_driver_name = "hmac-sha512-dx", .blocksize = SHA512_BLOCK_SIZE, .template_ahash = { - .init = ssi_ahash_init, - .update = ssi_ahash_update, - .final = ssi_ahash_final, - .finup = ssi_ahash_finup, - .digest = ssi_ahash_digest, - .export = ssi_ahash_export, - .import = ssi_ahash_import, - .setkey = ssi_ahash_setkey, + .init = cc_hash_init, + .update = cc_hash_update, + .final = cc_hash_final, + .finup = cc_hash_finup, + .digest = cc_hash_digest, + .export = cc_hash_export, + .import = cc_hash_import, + .setkey = cc_hash_setkey, .halg = { .digestsize = SHA512_DIGEST_SIZE, .statesize = CC_STATE_SIZE(SHA512_DIGEST_SIZE), @@ -1978,14 +1713,14 @@ static struct ssi_hash_template driver_hash[] = { .mac_driver_name = "hmac-md5-dx", .blocksize = MD5_HMAC_BLOCK_SIZE, .template_ahash = { - .init = ssi_ahash_init, - .update = ssi_ahash_update, - .final = ssi_ahash_final, - .finup = ssi_ahash_finup, - .digest = ssi_ahash_digest, - .export = ssi_ahash_export, - .import = ssi_ahash_import, - .setkey = ssi_ahash_setkey, + .init = cc_hash_init, + .update = cc_hash_update, + .final = cc_hash_final, + .finup = cc_hash_finup, + .digest = cc_hash_digest, + .export = cc_hash_export, + .import = cc_hash_import, + .setkey = cc_hash_setkey, .halg = { .digestsize = MD5_DIGEST_SIZE, .statesize = CC_STATE_SIZE(MD5_DIGEST_SIZE), @@ -2000,14 +1735,14 @@ static struct ssi_hash_template driver_hash[] = { .mac_driver_name = "xcbc-aes-dx", .blocksize = AES_BLOCK_SIZE, .template_ahash = { - .init = ssi_ahash_init, - .update = ssi_mac_update, - .final = ssi_mac_final, - .finup = ssi_mac_finup, - .digest = ssi_mac_digest, - .setkey = ssi_xcbc_setkey, - .export = ssi_ahash_export, - .import = ssi_ahash_import, + .init = cc_hash_init, + .update = cc_mac_update, + .final = cc_mac_final, + .finup = cc_mac_finup, + .digest = cc_mac_digest, + .setkey = cc_xcbc_setkey, + .export = cc_hash_export, + .import = cc_hash_import, .halg = { .digestsize = AES_BLOCK_SIZE, .statesize = CC_STATE_SIZE(AES_BLOCK_SIZE), @@ -2017,20 +1752,19 @@ static struct ssi_hash_template driver_hash[] = { .hw_mode = DRV_CIPHER_XCBC_MAC, .inter_digestsize = AES_BLOCK_SIZE, }, -#if SSI_CC_HAS_CMAC { .mac_name = "cmac(aes)", .mac_driver_name = "cmac-aes-dx", .blocksize = AES_BLOCK_SIZE, .template_ahash = { - .init = ssi_ahash_init, - .update = ssi_mac_update, - .final = ssi_mac_final, - .finup = ssi_mac_finup, - .digest = ssi_mac_digest, - .setkey = ssi_cmac_setkey, - .export = ssi_ahash_export, - .import = ssi_ahash_import, + .init = cc_hash_init, + .update = cc_mac_update, + .final = cc_mac_final, + .finup = cc_mac_finup, + .digest = cc_mac_digest, + .setkey = cc_cmac_setkey, + .export = cc_hash_export, + .import = cc_hash_import, .halg = { .digestsize = AES_BLOCK_SIZE, .statesize = CC_STATE_SIZE(AES_BLOCK_SIZE), @@ -2040,15 +1774,12 @@ static struct ssi_hash_template driver_hash[] = { .hw_mode = DRV_CIPHER_CMAC, .inter_digestsize = AES_BLOCK_SIZE, }, -#endif - }; -static struct ssi_hash_alg * -ssi_hash_create_alg(struct ssi_hash_template *template, struct device *dev, - bool keyed) +static struct cc_hash_alg *cc_alloc_hash_alg(struct cc_hash_template *template, + struct device *dev, bool keyed) { - struct ssi_hash_alg *t_crypto_alg; + struct cc_hash_alg *t_crypto_alg; struct crypto_alg *alg; struct ahash_alg *halg; @@ -2056,7 +1787,6 @@ ssi_hash_create_alg(struct ssi_hash_template *template, struct device *dev, if (!t_crypto_alg) return ERR_PTR(-ENOMEM); - t_crypto_alg->ahash_alg = template->template_ahash; halg = &t_crypto_alg->ahash_alg; alg = &halg->halg.base; @@ -2074,13 +1804,13 @@ ssi_hash_create_alg(struct ssi_hash_template *template, struct device *dev, template->driver_name); } alg->cra_module = THIS_MODULE; - alg->cra_ctxsize = sizeof(struct ssi_hash_ctx); - alg->cra_priority = SSI_CRA_PRIO; + alg->cra_ctxsize = sizeof(struct cc_hash_ctx); + alg->cra_priority = CC_CRA_PRIO; alg->cra_blocksize = template->blocksize; alg->cra_alignmask = 0; - alg->cra_exit = ssi_hash_cra_exit; + alg->cra_exit = cc_cra_exit; - alg->cra_init = ssi_ahash_cra_init; + alg->cra_init = cc_cra_init; alg->cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_KERN_DRIVER_ONLY; alg->cra_type = &crypto_ahash_type; @@ -2092,36 +1822,32 @@ ssi_hash_create_alg(struct ssi_hash_template *template, struct device *dev, return t_crypto_alg; } -int ssi_hash_init_sram_digest_consts(struct ssi_drvdata *drvdata) +int cc_init_hash_sram(struct cc_drvdata *drvdata) { - struct ssi_hash_handle *hash_handle = drvdata->hash_handle; - ssi_sram_addr_t sram_buff_ofs = hash_handle->digest_len_sram_addr; + struct cc_hash_handle *hash_handle = drvdata->hash_handle; + cc_sram_addr_t sram_buff_ofs = hash_handle->digest_len_sram_addr; unsigned int larval_seq_len = 0; struct cc_hw_desc larval_seq[CC_DIGEST_SIZE_MAX / sizeof(u32)]; - struct device *dev = drvdata_to_dev(drvdata); int rc = 0; -#if (DX_DEV_SHA_MAX > 256) - int i; -#endif /* Copy-to-sram digest-len */ - ssi_sram_mgr_const2sram_desc(digest_len_init, sram_buff_ofs, - ARRAY_SIZE(digest_len_init), - larval_seq, &larval_seq_len); + cc_set_sram_desc(digest_len_init, sram_buff_ofs, + ARRAY_SIZE(digest_len_init), larval_seq, + &larval_seq_len); rc = send_request_init(drvdata, larval_seq, larval_seq_len); - if (unlikely(rc != 0)) + if (rc) goto init_digest_const_err; sram_buff_ofs += sizeof(digest_len_init); larval_seq_len = 0; -#if (DX_DEV_SHA_MAX > 256) +#if (CC_DEV_SHA_MAX > 256) /* Copy-to-sram digest-len for sha384/512 */ - ssi_sram_mgr_const2sram_desc(digest_len_sha512_init, sram_buff_ofs, - ARRAY_SIZE(digest_len_sha512_init), - larval_seq, &larval_seq_len); + cc_set_sram_desc(digest_len_sha512_init, sram_buff_ofs, + ARRAY_SIZE(digest_len_sha512_init), + larval_seq, &larval_seq_len); rc = send_request_init(drvdata, larval_seq, larval_seq_len); - if (unlikely(rc != 0)) + if (rc) goto init_digest_const_err; sram_buff_ofs += sizeof(digest_len_sha512_init); @@ -2132,88 +1858,89 @@ int ssi_hash_init_sram_digest_consts(struct ssi_drvdata *drvdata) hash_handle->larval_digest_sram_addr = sram_buff_ofs; /* Copy-to-sram initial SHA* digests */ - ssi_sram_mgr_const2sram_desc(md5_init, sram_buff_ofs, - ARRAY_SIZE(md5_init), larval_seq, - &larval_seq_len); + cc_set_sram_desc(md5_init, sram_buff_ofs, ARRAY_SIZE(md5_init), + larval_seq, &larval_seq_len); rc = send_request_init(drvdata, larval_seq, larval_seq_len); - if (unlikely(rc != 0)) + if (rc) goto init_digest_const_err; sram_buff_ofs += sizeof(md5_init); larval_seq_len = 0; - ssi_sram_mgr_const2sram_desc(sha1_init, sram_buff_ofs, - ARRAY_SIZE(sha1_init), larval_seq, - &larval_seq_len); + cc_set_sram_desc(sha1_init, sram_buff_ofs, + ARRAY_SIZE(sha1_init), larval_seq, + &larval_seq_len); rc = send_request_init(drvdata, larval_seq, larval_seq_len); - if (unlikely(rc != 0)) + if (rc) goto init_digest_const_err; sram_buff_ofs += sizeof(sha1_init); larval_seq_len = 0; - ssi_sram_mgr_const2sram_desc(sha224_init, sram_buff_ofs, - ARRAY_SIZE(sha224_init), larval_seq, - &larval_seq_len); + cc_set_sram_desc(sha224_init, sram_buff_ofs, + ARRAY_SIZE(sha224_init), larval_seq, + &larval_seq_len); rc = send_request_init(drvdata, larval_seq, larval_seq_len); - if (unlikely(rc != 0)) + if (rc) goto init_digest_const_err; sram_buff_ofs += sizeof(sha224_init); larval_seq_len = 0; - ssi_sram_mgr_const2sram_desc(sha256_init, sram_buff_ofs, - ARRAY_SIZE(sha256_init), larval_seq, - &larval_seq_len); + cc_set_sram_desc(sha256_init, sram_buff_ofs, + ARRAY_SIZE(sha256_init), larval_seq, + &larval_seq_len); rc = send_request_init(drvdata, larval_seq, larval_seq_len); - if (unlikely(rc != 0)) + if (rc) goto init_digest_const_err; sram_buff_ofs += sizeof(sha256_init); larval_seq_len = 0; -#if (DX_DEV_SHA_MAX > 256) - /* We are forced to swap each double-word larval before copying to sram */ - for (i = 0; i < ARRAY_SIZE(sha384_init); i++) { - const u32 const0 = ((u32 *)((u64 *)&sha384_init[i]))[1]; - const u32 const1 = ((u32 *)((u64 *)&sha384_init[i]))[0]; - - ssi_sram_mgr_const2sram_desc(&const0, sram_buff_ofs, 1, - larval_seq, &larval_seq_len); - sram_buff_ofs += sizeof(u32); - ssi_sram_mgr_const2sram_desc(&const1, sram_buff_ofs, 1, - larval_seq, &larval_seq_len); - sram_buff_ofs += sizeof(u32); - } +#if (CC_DEV_SHA_MAX > 256) + cc_set_sram_desc((u32 *)sha384_init, sram_buff_ofs, + (ARRAY_SIZE(sha384_init) * 2), larval_seq, + &larval_seq_len); rc = send_request_init(drvdata, larval_seq, larval_seq_len); - if (unlikely(rc != 0)) { - dev_err(dev, "send_request() failed (rc = %d)\n", rc); + if (rc) goto init_digest_const_err; - } + sram_buff_ofs += sizeof(sha384_init); larval_seq_len = 0; - for (i = 0; i < ARRAY_SIZE(sha512_init); i++) { - const u32 const0 = ((u32 *)((u64 *)&sha512_init[i]))[1]; - const u32 const1 = ((u32 *)((u64 *)&sha512_init[i]))[0]; - - ssi_sram_mgr_const2sram_desc(&const0, sram_buff_ofs, 1, - larval_seq, &larval_seq_len); - sram_buff_ofs += sizeof(u32); - ssi_sram_mgr_const2sram_desc(&const1, sram_buff_ofs, 1, - larval_seq, &larval_seq_len); - sram_buff_ofs += sizeof(u32); - } + cc_set_sram_desc((u32 *)sha512_init, sram_buff_ofs, + (ARRAY_SIZE(sha512_init) * 2), larval_seq, + &larval_seq_len); rc = send_request_init(drvdata, larval_seq, larval_seq_len); - if (unlikely(rc != 0)) { - dev_err(dev, "send_request() failed (rc = %d)\n", rc); + if (rc) goto init_digest_const_err; - } #endif init_digest_const_err: return rc; } -int ssi_hash_alloc(struct ssi_drvdata *drvdata) +static void __init cc_swap_dwords(u32 *buf, unsigned long size) { - struct ssi_hash_handle *hash_handle; - ssi_sram_addr_t sram_buff; + int i; + u32 tmp; + + for (i = 0; i < size; i += 2) { + tmp = buf[i]; + buf[i] = buf[i + 1]; + buf[i + 1] = tmp; + } +} + +/* + * Due to the way the HW works we need to swap every + * double word in the SHA384 and SHA512 larval hashes + */ +void __init cc_hash_global_init(void) +{ + cc_swap_dwords((u32 *)&sha384_init, (ARRAY_SIZE(sha384_init) * 2)); + cc_swap_dwords((u32 *)&sha512_init, (ARRAY_SIZE(sha512_init) * 2)); +} + +int cc_hash_alloc(struct cc_drvdata *drvdata) +{ + struct cc_hash_handle *hash_handle; + cc_sram_addr_t sram_buff; u32 sram_size_to_alloc; struct device *dev = drvdata_to_dev(drvdata); int rc = 0; @@ -2227,7 +1954,7 @@ int ssi_hash_alloc(struct ssi_drvdata *drvdata) drvdata->hash_handle = hash_handle; sram_size_to_alloc = sizeof(digest_len_init) + -#if (DX_DEV_SHA_MAX > 256) +#if (CC_DEV_SHA_MAX > 256) sizeof(digest_len_sha512_init) + sizeof(sha384_init) + sizeof(sha512_init) + @@ -2237,7 +1964,7 @@ int ssi_hash_alloc(struct ssi_drvdata *drvdata) sizeof(sha224_init) + sizeof(sha256_init); - sram_buff = ssi_sram_mgr_alloc(drvdata, sram_size_to_alloc); + sram_buff = cc_sram_alloc(drvdata, sram_size_to_alloc); if (sram_buff == NULL_SRAM_ADDR) { dev_err(dev, "SRAM pool exhausted\n"); rc = -ENOMEM; @@ -2248,19 +1975,19 @@ int ssi_hash_alloc(struct ssi_drvdata *drvdata) hash_handle->digest_len_sram_addr = sram_buff; /*must be set before the alg registration as it is being used there*/ - rc = ssi_hash_init_sram_digest_consts(drvdata); - if (unlikely(rc != 0)) { + rc = cc_init_hash_sram(drvdata); + if (rc) { dev_err(dev, "Init digest CONST failed (rc=%d)\n", rc); goto fail; } /* ahash registration */ for (alg = 0; alg < ARRAY_SIZE(driver_hash); alg++) { - struct ssi_hash_alg *t_alg; + struct cc_hash_alg *t_alg; int hw_mode = driver_hash[alg].hw_mode; /* register hmac version */ - t_alg = ssi_hash_create_alg(&driver_hash[alg], dev, true); + t_alg = cc_alloc_hash_alg(&driver_hash[alg], dev, true); if (IS_ERR(t_alg)) { rc = PTR_ERR(t_alg); dev_err(dev, "%s alg allocation failed\n", @@ -2270,22 +1997,21 @@ int ssi_hash_alloc(struct ssi_drvdata *drvdata) t_alg->drvdata = drvdata; rc = crypto_register_ahash(&t_alg->ahash_alg); - if (unlikely(rc)) { + if (rc) { dev_err(dev, "%s alg registration failed\n", driver_hash[alg].driver_name); kfree(t_alg); goto fail; } else { - list_add_tail(&t_alg->entry, - &hash_handle->hash_list); + list_add_tail(&t_alg->entry, &hash_handle->hash_list); } - if ((hw_mode == DRV_CIPHER_XCBC_MAC) || - (hw_mode == DRV_CIPHER_CMAC)) + if (hw_mode == DRV_CIPHER_XCBC_MAC || + hw_mode == DRV_CIPHER_CMAC) continue; /* register hash version */ - t_alg = ssi_hash_create_alg(&driver_hash[alg], dev, false); + t_alg = cc_alloc_hash_alg(&driver_hash[alg], dev, false); if (IS_ERR(t_alg)) { rc = PTR_ERR(t_alg); dev_err(dev, "%s alg allocation failed\n", @@ -2295,7 +2021,7 @@ int ssi_hash_alloc(struct ssi_drvdata *drvdata) t_alg->drvdata = drvdata; rc = crypto_register_ahash(&t_alg->ahash_alg); - if (unlikely(rc)) { + if (rc) { dev_err(dev, "%s alg registration failed\n", driver_hash[alg].driver_name); kfree(t_alg); @@ -2313,13 +2039,14 @@ fail: return rc; } -int ssi_hash_free(struct ssi_drvdata *drvdata) +int cc_hash_free(struct cc_drvdata *drvdata) { - struct ssi_hash_alg *t_hash_alg, *hash_n; - struct ssi_hash_handle *hash_handle = drvdata->hash_handle; + struct cc_hash_alg *t_hash_alg, *hash_n; + struct cc_hash_handle *hash_handle = drvdata->hash_handle; if (hash_handle) { - list_for_each_entry_safe(t_hash_alg, hash_n, &hash_handle->hash_list, entry) { + list_for_each_entry_safe(t_hash_alg, hash_n, + &hash_handle->hash_list, entry) { crypto_unregister_ahash(&t_hash_alg->ahash_alg); list_del(&t_hash_alg->entry); kfree(t_hash_alg); @@ -2331,14 +2058,13 @@ int ssi_hash_free(struct ssi_drvdata *drvdata) return 0; } -static void ssi_hash_create_xcbc_setup(struct ahash_request *areq, - struct cc_hw_desc desc[], - unsigned int *seq_size) +static void cc_setup_xcbc(struct ahash_request *areq, struct cc_hw_desc desc[], + unsigned int *seq_size) { unsigned int idx = *seq_size; struct ahash_req_ctx *state = ahash_request_ctx(areq); struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); - struct ssi_hash_ctx *ctx = crypto_ahash_ctx(tfm); + struct cc_hash_ctx *ctx = crypto_ahash_ctx(tfm); /* Setup XCBC MAC K1 */ hw_desc_init(&desc[idx]); @@ -2354,8 +2080,8 @@ static void ssi_hash_create_xcbc_setup(struct ahash_request *areq, /* Setup XCBC MAC K2 */ hw_desc_init(&desc[idx]); - set_din_type(&desc[idx], DMA_DLLI, (ctx->opad_tmp_keys_dma_addr + - XCBC_MAC_K2_OFFSET), + set_din_type(&desc[idx], DMA_DLLI, + (ctx->opad_tmp_keys_dma_addr + XCBC_MAC_K2_OFFSET), CC_AES_128_BIT_KEY_SIZE, NS_BIT); set_setup_mode(&desc[idx], SETUP_LOAD_STATE1); set_cipher_mode(&desc[idx], DRV_CIPHER_XCBC_MAC); @@ -2366,8 +2092,8 @@ static void ssi_hash_create_xcbc_setup(struct ahash_request *areq, /* Setup XCBC MAC K3 */ hw_desc_init(&desc[idx]); - set_din_type(&desc[idx], DMA_DLLI, (ctx->opad_tmp_keys_dma_addr + - XCBC_MAC_K3_OFFSET), + set_din_type(&desc[idx], DMA_DLLI, + (ctx->opad_tmp_keys_dma_addr + XCBC_MAC_K3_OFFSET), CC_AES_128_BIT_KEY_SIZE, NS_BIT); set_setup_mode(&desc[idx], SETUP_LOAD_STATE2); set_cipher_mode(&desc[idx], DRV_CIPHER_XCBC_MAC); @@ -2389,14 +2115,13 @@ static void ssi_hash_create_xcbc_setup(struct ahash_request *areq, *seq_size = idx; } -static void ssi_hash_create_cmac_setup(struct ahash_request *areq, - struct cc_hw_desc desc[], - unsigned int *seq_size) +static void cc_setup_cmac(struct ahash_request *areq, struct cc_hw_desc desc[], + unsigned int *seq_size) { unsigned int idx = *seq_size; struct ahash_req_ctx *state = ahash_request_ctx(areq); struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); - struct ssi_hash_ctx *ctx = crypto_ahash_ctx(tfm); + struct cc_hash_ctx *ctx = crypto_ahash_ctx(tfm); /* Setup CMAC Key */ hw_desc_init(&desc[idx]); @@ -2423,17 +2148,15 @@ static void ssi_hash_create_cmac_setup(struct ahash_request *areq, *seq_size = idx; } -static void ssi_hash_create_data_desc(struct ahash_req_ctx *areq_ctx, - struct ssi_hash_ctx *ctx, - unsigned int flow_mode, - struct cc_hw_desc desc[], - bool is_not_last_data, - unsigned int *seq_size) +static void cc_set_desc(struct ahash_req_ctx *areq_ctx, + struct cc_hash_ctx *ctx, unsigned int flow_mode, + struct cc_hw_desc desc[], bool is_not_last_data, + unsigned int *seq_size) { unsigned int idx = *seq_size; struct device *dev = drvdata_to_dev(ctx->drvdata); - if (likely(areq_ctx->data_dma_buf_type == SSI_DMA_BUF_DLLI)) { + if (areq_ctx->data_dma_buf_type == CC_DMA_BUF_DLLI) { hw_desc_init(&desc[idx]); set_din_type(&desc[idx], DMA_DLLI, sg_dma_address(areq_ctx->curr_sg), @@ -2441,7 +2164,7 @@ static void ssi_hash_create_data_desc(struct ahash_req_ctx *areq_ctx, set_flow_mode(&desc[idx], flow_mode); idx++; } else { - if (areq_ctx->data_dma_buf_type == SSI_DMA_BUF_NULL) { + if (areq_ctx->data_dma_buf_type == CC_DMA_BUF_NULL) { dev_dbg(dev, " NULL mode\n"); /* nothing to build */ return; @@ -2469,6 +2192,29 @@ static void ssi_hash_create_data_desc(struct ahash_req_ctx *areq_ctx, *seq_size = idx; } +static const void *cc_larval_digest(struct device *dev, u32 mode) +{ + switch (mode) { + case DRV_HASH_MD5: + return md5_init; + case DRV_HASH_SHA1: + return sha1_init; + case DRV_HASH_SHA224: + return sha224_init; + case DRV_HASH_SHA256: + return sha256_init; +#if (CC_DEV_SHA_MAX > 256) + case DRV_HASH_SHA384: + return sha384_init; + case DRV_HASH_SHA512: + return sha512_init; +#endif + default: + dev_err(dev, "Invalid hash mode (%d)\n", mode); + return md5_init; + } +} + /*! * Gets the address of the initial digest in SRAM * according to the given hash mode @@ -2476,12 +2222,12 @@ static void ssi_hash_create_data_desc(struct ahash_req_ctx *areq_ctx, * \param drvdata * \param mode The Hash mode. Supported modes: MD5/SHA1/SHA224/SHA256 * - * \return u32 The address of the inital digest in SRAM + * \return u32 The address of the initial digest in SRAM */ -ssi_sram_addr_t ssi_ahash_get_larval_digest_sram_addr(void *drvdata, u32 mode) +cc_sram_addr_t cc_larval_digest_addr(void *drvdata, u32 mode) { - struct ssi_drvdata *_drvdata = (struct ssi_drvdata *)drvdata; - struct ssi_hash_handle *hash_handle = _drvdata->hash_handle; + struct cc_drvdata *_drvdata = (struct cc_drvdata *)drvdata; + struct cc_hash_handle *hash_handle = _drvdata->hash_handle; struct device *dev = drvdata_to_dev(_drvdata); switch (mode) { @@ -2501,7 +2247,7 @@ ssi_sram_addr_t ssi_ahash_get_larval_digest_sram_addr(void *drvdata, u32 mode) sizeof(md5_init) + sizeof(sha1_init) + sizeof(sha224_init)); -#if (DX_DEV_SHA_MAX > 256) +#if (CC_DEV_SHA_MAX > 256) case DRV_HASH_SHA384: return (hash_handle->larval_digest_sram_addr + sizeof(md5_init) + @@ -2524,12 +2270,12 @@ ssi_sram_addr_t ssi_ahash_get_larval_digest_sram_addr(void *drvdata, u32 mode) return hash_handle->larval_digest_sram_addr; } -ssi_sram_addr_t -ssi_ahash_get_initial_digest_len_sram_addr(void *drvdata, u32 mode) +cc_sram_addr_t +cc_digest_len_addr(void *drvdata, u32 mode) { - struct ssi_drvdata *_drvdata = (struct ssi_drvdata *)drvdata; - struct ssi_hash_handle *hash_handle = _drvdata->hash_handle; - ssi_sram_addr_t digest_len_addr = hash_handle->digest_len_sram_addr; + struct cc_drvdata *_drvdata = (struct cc_drvdata *)drvdata; + struct cc_hash_handle *hash_handle = _drvdata->hash_handle; + cc_sram_addr_t digest_len_addr = hash_handle->digest_len_sram_addr; switch (mode) { case DRV_HASH_SHA1: @@ -2537,7 +2283,7 @@ ssi_ahash_get_initial_digest_len_sram_addr(void *drvdata, u32 mode) case DRV_HASH_SHA256: case DRV_HASH_MD5: return digest_len_addr; -#if (DX_DEV_SHA_MAX > 256) +#if (CC_DEV_SHA_MAX > 256) case DRV_HASH_SHA384: case DRV_HASH_SHA512: return digest_len_addr + sizeof(digest_len_init); diff --git a/drivers/staging/ccree/cc_hash.h b/drivers/staging/ccree/cc_hash.h new file mode 100644 index 000000000000..aa42b8f4348d --- /dev/null +++ b/drivers/staging/ccree/cc_hash.h @@ -0,0 +1,114 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ + +/* \file cc_hash.h + * ARM CryptoCell Hash Crypto API + */ + +#ifndef __CC_HASH_H__ +#define __CC_HASH_H__ + +#include "cc_buffer_mgr.h" + +#define HMAC_IPAD_CONST 0x36363636 +#define HMAC_OPAD_CONST 0x5C5C5C5C +#if (CC_DEV_SHA_MAX > 256) +#define HASH_LEN_SIZE 16 +#define CC_MAX_HASH_DIGEST_SIZE SHA512_DIGEST_SIZE +#define CC_MAX_HASH_BLCK_SIZE SHA512_BLOCK_SIZE +#else +#define HASH_LEN_SIZE 8 +#define CC_MAX_HASH_DIGEST_SIZE SHA256_DIGEST_SIZE +#define CC_MAX_HASH_BLCK_SIZE SHA256_BLOCK_SIZE +#endif + +#define XCBC_MAC_K1_OFFSET 0 +#define XCBC_MAC_K2_OFFSET 16 +#define XCBC_MAC_K3_OFFSET 32 + +#define CC_EXPORT_MAGIC 0xC2EE1070U + +/* this struct was taken from drivers/crypto/nx/nx-aes-xcbc.c and it is used + * for xcbc/cmac statesize + */ +struct aeshash_state { + u8 state[AES_BLOCK_SIZE]; + unsigned int count; + u8 buffer[AES_BLOCK_SIZE]; +}; + +/* ahash state */ +struct ahash_req_ctx { + u8 buffers[2][CC_MAX_HASH_BLCK_SIZE] ____cacheline_aligned; + u8 digest_result_buff[CC_MAX_HASH_DIGEST_SIZE] ____cacheline_aligned; + u8 digest_buff[CC_MAX_HASH_DIGEST_SIZE] ____cacheline_aligned; + u8 opad_digest_buff[CC_MAX_HASH_DIGEST_SIZE] ____cacheline_aligned; + u8 digest_bytes_len[HASH_LEN_SIZE] ____cacheline_aligned; + struct async_gen_req_ctx gen_ctx ____cacheline_aligned; + enum cc_req_dma_buf_type data_dma_buf_type; + dma_addr_t opad_digest_dma_addr; + dma_addr_t digest_buff_dma_addr; + dma_addr_t digest_bytes_len_dma_addr; + dma_addr_t digest_result_dma_addr; + u32 buf_cnt[2]; + u32 buff_index; + u32 xcbc_count; /* count xcbc update operatations */ + struct scatterlist buff_sg[2]; + struct scatterlist *curr_sg; + u32 in_nents; + u32 mlli_nents; + struct mlli_params mlli_params; +}; + +static inline u32 *cc_hash_buf_cnt(struct ahash_req_ctx *state) +{ + return &state->buf_cnt[state->buff_index]; +} + +static inline u8 *cc_hash_buf(struct ahash_req_ctx *state) +{ + return state->buffers[state->buff_index]; +} + +static inline u32 *cc_next_buf_cnt(struct ahash_req_ctx *state) +{ + return &state->buf_cnt[state->buff_index ^ 1]; +} + +static inline u8 *cc_next_buf(struct ahash_req_ctx *state) +{ + return state->buffers[state->buff_index ^ 1]; +} + +int cc_hash_alloc(struct cc_drvdata *drvdata); +int cc_init_hash_sram(struct cc_drvdata *drvdata); +int cc_hash_free(struct cc_drvdata *drvdata); + +/*! + * Gets the initial digest length + * + * \param drvdata + * \param mode The Hash mode. Supported modes: + * MD5/SHA1/SHA224/SHA256/SHA384/SHA512 + * + * \return u32 returns the address of the initial digest length in SRAM + */ +cc_sram_addr_t +cc_digest_len_addr(void *drvdata, u32 mode); + +/*! + * Gets the address of the initial digest in SRAM + * according to the given hash mode + * + * \param drvdata + * \param mode The Hash mode. Supported modes: + * MD5/SHA1/SHA224/SHA256/SHA384/SHA512 + * + * \return u32 The address of the initial digest in SRAM + */ +cc_sram_addr_t cc_larval_digest_addr(void *drvdata, u32 mode); + +void cc_hash_global_init(void); + +#endif /*__CC_HASH_H__*/ + diff --git a/drivers/staging/ccree/cc_host_regs.h b/drivers/staging/ccree/cc_host_regs.h new file mode 100644 index 000000000000..69ef2fa0cb9b --- /dev/null +++ b/drivers/staging/ccree/cc_host_regs.h @@ -0,0 +1,142 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ + +#ifndef __CC_HOST_H__ +#define __CC_HOST_H__ + +// -------------------------------------- +// BLOCK: HOST_P +// -------------------------------------- +#define CC_HOST_IRR_REG_OFFSET 0xA00UL +#define CC_HOST_IRR_DSCRPTR_COMPLETION_LOW_INT_BIT_SHIFT 0x2UL +#define CC_HOST_IRR_DSCRPTR_COMPLETION_LOW_INT_BIT_SIZE 0x1UL +#define CC_HOST_IRR_AXI_ERR_INT_BIT_SHIFT 0x8UL +#define CC_HOST_IRR_AXI_ERR_INT_BIT_SIZE 0x1UL +#define CC_HOST_IRR_GPR0_BIT_SHIFT 0xBUL +#define CC_HOST_IRR_GPR0_BIT_SIZE 0x1UL +#define CC_HOST_IRR_DSCRPTR_WATERMARK_INT_BIT_SHIFT 0x13UL +#define CC_HOST_IRR_DSCRPTR_WATERMARK_INT_BIT_SIZE 0x1UL +#define CC_HOST_IRR_AXIM_COMP_INT_BIT_SHIFT 0x17UL +#define CC_HOST_IRR_AXIM_COMP_INT_BIT_SIZE 0x1UL +#define CC_HOST_IMR_REG_OFFSET 0xA04UL +#define CC_HOST_IMR_NOT_USED_MASK_BIT_SHIFT 0x1UL +#define CC_HOST_IMR_NOT_USED_MASK_BIT_SIZE 0x1UL +#define CC_HOST_IMR_DSCRPTR_COMPLETION_MASK_BIT_SHIFT 0x2UL +#define CC_HOST_IMR_DSCRPTR_COMPLETION_MASK_BIT_SIZE 0x1UL +#define CC_HOST_IMR_AXI_ERR_MASK_BIT_SHIFT 0x8UL +#define CC_HOST_IMR_AXI_ERR_MASK_BIT_SIZE 0x1UL +#define CC_HOST_IMR_GPR0_BIT_SHIFT 0xBUL +#define CC_HOST_IMR_GPR0_BIT_SIZE 0x1UL +#define CC_HOST_IMR_DSCRPTR_WATERMARK_MASK0_BIT_SHIFT 0x13UL +#define CC_HOST_IMR_DSCRPTR_WATERMARK_MASK0_BIT_SIZE 0x1UL +#define CC_HOST_IMR_AXIM_COMP_INT_MASK_BIT_SHIFT 0x17UL +#define CC_HOST_IMR_AXIM_COMP_INT_MASK_BIT_SIZE 0x1UL +#define CC_HOST_ICR_REG_OFFSET 0xA08UL +#define CC_HOST_ICR_DSCRPTR_COMPLETION_BIT_SHIFT 0x2UL +#define CC_HOST_ICR_DSCRPTR_COMPLETION_BIT_SIZE 0x1UL +#define CC_HOST_ICR_AXI_ERR_CLEAR_BIT_SHIFT 0x8UL +#define CC_HOST_ICR_AXI_ERR_CLEAR_BIT_SIZE 0x1UL +#define CC_HOST_ICR_GPR_INT_CLEAR_BIT_SHIFT 0xBUL +#define CC_HOST_ICR_GPR_INT_CLEAR_BIT_SIZE 0x1UL +#define CC_HOST_ICR_DSCRPTR_WATERMARK_QUEUE0_CLEAR_BIT_SHIFT 0x13UL +#define CC_HOST_ICR_DSCRPTR_WATERMARK_QUEUE0_CLEAR_BIT_SIZE 0x1UL +#define CC_HOST_ICR_AXIM_COMP_INT_CLEAR_BIT_SHIFT 0x17UL +#define CC_HOST_ICR_AXIM_COMP_INT_CLEAR_BIT_SIZE 0x1UL +#define CC_HOST_SIGNATURE_REG_OFFSET 0xA24UL +#define CC_HOST_SIGNATURE_VALUE_BIT_SHIFT 0x0UL +#define CC_HOST_SIGNATURE_VALUE_BIT_SIZE 0x20UL +#define CC_HOST_BOOT_REG_OFFSET 0xA28UL +#define CC_HOST_BOOT_SYNTHESIS_CONFIG_BIT_SHIFT 0x0UL +#define CC_HOST_BOOT_SYNTHESIS_CONFIG_BIT_SIZE 0x1UL +#define CC_HOST_BOOT_LARGE_RKEK_LOCAL_BIT_SHIFT 0x1UL +#define CC_HOST_BOOT_LARGE_RKEK_LOCAL_BIT_SIZE 0x1UL +#define CC_HOST_BOOT_HASH_IN_FUSES_LOCAL_BIT_SHIFT 0x2UL +#define CC_HOST_BOOT_HASH_IN_FUSES_LOCAL_BIT_SIZE 0x1UL +#define CC_HOST_BOOT_EXT_MEM_SECURED_LOCAL_BIT_SHIFT 0x3UL +#define CC_HOST_BOOT_EXT_MEM_SECURED_LOCAL_BIT_SIZE 0x1UL +#define CC_HOST_BOOT_RKEK_ECC_EXISTS_LOCAL_N_BIT_SHIFT 0x5UL +#define CC_HOST_BOOT_RKEK_ECC_EXISTS_LOCAL_N_BIT_SIZE 0x1UL +#define CC_HOST_BOOT_SRAM_SIZE_LOCAL_BIT_SHIFT 0x6UL +#define CC_HOST_BOOT_SRAM_SIZE_LOCAL_BIT_SIZE 0x3UL +#define CC_HOST_BOOT_DSCRPTR_EXISTS_LOCAL_BIT_SHIFT 0x9UL +#define CC_HOST_BOOT_DSCRPTR_EXISTS_LOCAL_BIT_SIZE 0x1UL +#define CC_HOST_BOOT_PAU_EXISTS_LOCAL_BIT_SHIFT 0xAUL +#define CC_HOST_BOOT_PAU_EXISTS_LOCAL_BIT_SIZE 0x1UL +#define CC_HOST_BOOT_RNG_EXISTS_LOCAL_BIT_SHIFT 0xBUL +#define CC_HOST_BOOT_RNG_EXISTS_LOCAL_BIT_SIZE 0x1UL +#define CC_HOST_BOOT_PKA_EXISTS_LOCAL_BIT_SHIFT 0xCUL +#define CC_HOST_BOOT_PKA_EXISTS_LOCAL_BIT_SIZE 0x1UL +#define CC_HOST_BOOT_RC4_EXISTS_LOCAL_BIT_SHIFT 0xDUL +#define CC_HOST_BOOT_RC4_EXISTS_LOCAL_BIT_SIZE 0x1UL +#define CC_HOST_BOOT_SHA_512_PRSNT_LOCAL_BIT_SHIFT 0xEUL +#define CC_HOST_BOOT_SHA_512_PRSNT_LOCAL_BIT_SIZE 0x1UL +#define CC_HOST_BOOT_SHA_256_PRSNT_LOCAL_BIT_SHIFT 0xFUL +#define CC_HOST_BOOT_SHA_256_PRSNT_LOCAL_BIT_SIZE 0x1UL +#define CC_HOST_BOOT_MD5_PRSNT_LOCAL_BIT_SHIFT 0x10UL +#define CC_HOST_BOOT_MD5_PRSNT_LOCAL_BIT_SIZE 0x1UL +#define CC_HOST_BOOT_HASH_EXISTS_LOCAL_BIT_SHIFT 0x11UL +#define CC_HOST_BOOT_HASH_EXISTS_LOCAL_BIT_SIZE 0x1UL +#define CC_HOST_BOOT_C2_EXISTS_LOCAL_BIT_SHIFT 0x12UL +#define CC_HOST_BOOT_C2_EXISTS_LOCAL_BIT_SIZE 0x1UL +#define CC_HOST_BOOT_DES_EXISTS_LOCAL_BIT_SHIFT 0x13UL +#define CC_HOST_BOOT_DES_EXISTS_LOCAL_BIT_SIZE 0x1UL +#define CC_HOST_BOOT_AES_XCBC_MAC_EXISTS_LOCAL_BIT_SHIFT 0x14UL +#define CC_HOST_BOOT_AES_XCBC_MAC_EXISTS_LOCAL_BIT_SIZE 0x1UL +#define CC_HOST_BOOT_AES_CMAC_EXISTS_LOCAL_BIT_SHIFT 0x15UL +#define CC_HOST_BOOT_AES_CMAC_EXISTS_LOCAL_BIT_SIZE 0x1UL +#define CC_HOST_BOOT_AES_CCM_EXISTS_LOCAL_BIT_SHIFT 0x16UL +#define CC_HOST_BOOT_AES_CCM_EXISTS_LOCAL_BIT_SIZE 0x1UL +#define CC_HOST_BOOT_AES_XEX_HW_T_CALC_LOCAL_BIT_SHIFT 0x17UL +#define CC_HOST_BOOT_AES_XEX_HW_T_CALC_LOCAL_BIT_SIZE 0x1UL +#define CC_HOST_BOOT_AES_XEX_EXISTS_LOCAL_BIT_SHIFT 0x18UL +#define CC_HOST_BOOT_AES_XEX_EXISTS_LOCAL_BIT_SIZE 0x1UL +#define CC_HOST_BOOT_CTR_EXISTS_LOCAL_BIT_SHIFT 0x19UL +#define CC_HOST_BOOT_CTR_EXISTS_LOCAL_BIT_SIZE 0x1UL +#define CC_HOST_BOOT_AES_DIN_BYTE_RESOLUTION_LOCAL_BIT_SHIFT 0x1AUL +#define CC_HOST_BOOT_AES_DIN_BYTE_RESOLUTION_LOCAL_BIT_SIZE 0x1UL +#define CC_HOST_BOOT_TUNNELING_ENB_LOCAL_BIT_SHIFT 0x1BUL +#define CC_HOST_BOOT_TUNNELING_ENB_LOCAL_BIT_SIZE 0x1UL +#define CC_HOST_BOOT_SUPPORT_256_192_KEY_LOCAL_BIT_SHIFT 0x1CUL +#define CC_HOST_BOOT_SUPPORT_256_192_KEY_LOCAL_BIT_SIZE 0x1UL +#define CC_HOST_BOOT_ONLY_ENCRYPT_LOCAL_BIT_SHIFT 0x1DUL +#define CC_HOST_BOOT_ONLY_ENCRYPT_LOCAL_BIT_SIZE 0x1UL +#define CC_HOST_BOOT_AES_EXISTS_LOCAL_BIT_SHIFT 0x1EUL +#define CC_HOST_BOOT_AES_EXISTS_LOCAL_BIT_SIZE 0x1UL +#define CC_HOST_VERSION_REG_OFFSET 0xA40UL +#define CC_HOST_VERSION_VALUE_BIT_SHIFT 0x0UL +#define CC_HOST_VERSION_VALUE_BIT_SIZE 0x20UL +#define CC_HOST_KFDE0_VALID_REG_OFFSET 0xA60UL +#define CC_HOST_KFDE0_VALID_VALUE_BIT_SHIFT 0x0UL +#define CC_HOST_KFDE0_VALID_VALUE_BIT_SIZE 0x1UL +#define CC_HOST_KFDE1_VALID_REG_OFFSET 0xA64UL +#define CC_HOST_KFDE1_VALID_VALUE_BIT_SHIFT 0x0UL +#define CC_HOST_KFDE1_VALID_VALUE_BIT_SIZE 0x1UL +#define CC_HOST_KFDE2_VALID_REG_OFFSET 0xA68UL +#define CC_HOST_KFDE2_VALID_VALUE_BIT_SHIFT 0x0UL +#define CC_HOST_KFDE2_VALID_VALUE_BIT_SIZE 0x1UL +#define CC_HOST_KFDE3_VALID_REG_OFFSET 0xA6CUL +#define CC_HOST_KFDE3_VALID_VALUE_BIT_SHIFT 0x0UL +#define CC_HOST_KFDE3_VALID_VALUE_BIT_SIZE 0x1UL +#define CC_HOST_GPR0_REG_OFFSET 0xA70UL +#define CC_HOST_GPR0_VALUE_BIT_SHIFT 0x0UL +#define CC_HOST_GPR0_VALUE_BIT_SIZE 0x20UL +#define CC_GPR_HOST_REG_OFFSET 0xA74UL +#define CC_GPR_HOST_VALUE_BIT_SHIFT 0x0UL +#define CC_GPR_HOST_VALUE_BIT_SIZE 0x20UL +#define CC_HOST_POWER_DOWN_EN_REG_OFFSET 0xA78UL +#define CC_HOST_POWER_DOWN_EN_VALUE_BIT_SHIFT 0x0UL +#define CC_HOST_POWER_DOWN_EN_VALUE_BIT_SIZE 0x1UL +// -------------------------------------- +// BLOCK: HOST_SRAM +// -------------------------------------- +#define CC_SRAM_DATA_REG_OFFSET 0xF00UL +#define CC_SRAM_DATA_VALUE_BIT_SHIFT 0x0UL +#define CC_SRAM_DATA_VALUE_BIT_SIZE 0x20UL +#define CC_SRAM_ADDR_REG_OFFSET 0xF04UL +#define CC_SRAM_ADDR_VALUE_BIT_SHIFT 0x0UL +#define CC_SRAM_ADDR_VALUE_BIT_SIZE 0xFUL +#define CC_SRAM_DATA_READY_REG_OFFSET 0xF08UL +#define CC_SRAM_DATA_READY_VALUE_BIT_SHIFT 0x0UL +#define CC_SRAM_DATA_READY_VALUE_BIT_SIZE 0x1UL + +#endif //__CC_HOST_H__ diff --git a/drivers/staging/ccree/cc_hw_queue_defs.h b/drivers/staging/ccree/cc_hw_queue_defs.h index 2ae0f655e7a0..a79f28cec5ae 100644 --- a/drivers/staging/ccree/cc_hw_queue_defs.h +++ b/drivers/staging/ccree/cc_hw_queue_defs.h @@ -1,25 +1,12 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ #ifndef __CC_HW_QUEUE_DEFS_H__ #define __CC_HW_QUEUE_DEFS_H__ #include <linux/types.h> -#include "dx_crys_kernel.h" +#include "cc_kernel_regs.h" #include <linux/bitfield.h> /****************************************************************************** @@ -30,14 +17,12 @@ /* Define max. available slots in HW queue */ #define HW_QUEUE_SLOTS_MAX 15 -#define CC_REG_NAME(word, name) DX_DSCRPTR_QUEUE_WORD ## word ## _ ## name - #define CC_REG_LOW(word, name) \ - (DX_DSCRPTR_QUEUE_WORD ## word ## _ ## name ## _BIT_SHIFT) + (CC_DSCRPTR_QUEUE_WORD ## word ## _ ## name ## _BIT_SHIFT) #define CC_REG_HIGH(word, name) \ (CC_REG_LOW(word, name) + \ - DX_DSCRPTR_QUEUE_WORD ## word ## _ ## name ## _BIT_SIZE - 1) + CC_DSCRPTR_QUEUE_WORD ## word ## _ ## name ## _BIT_SIZE - 1) #define CC_GENMASK(word, name) \ GENMASK(CC_REG_HIGH(word, name), CC_REG_LOW(word, name)) @@ -122,7 +107,6 @@ enum cc_flow_mode { AES_to_AES_to_HASH_and_DOUT = 13, AES_to_AES_to_HASH = 14, AES_to_HASH_and_AES = 15, - DIN_MULTI2_DOUT = 16, DIN_AES_AESMAC = 17, HASH_to_DOUT = 18, /* setup flows */ @@ -130,7 +114,6 @@ enum cc_flow_mode { S_DIN_to_AES2 = 33, S_DIN_to_DES = 34, S_DIN_to_RC4 = 35, - S_DIN_to_MULTI2 = 36, S_DIN_to_HASH = 37, S_AES_to_DOUT = 38, S_AES2_to_DOUT = 39, @@ -203,6 +186,19 @@ enum cc_hw_des_key_size { END_OF_DES_KEYS = S32_MAX, }; +enum cc_hash_conf_pad { + HASH_PADDING_DISABLED = 0, + HASH_PADDING_ENABLED = 1, + HASH_DIGEST_RESULT_LITTLE_ENDIAN = 2, + HASH_CONFIG1_PADDING_RESERVE32 = S32_MAX, +}; + +enum cc_hash_cipher_pad { + DO_NOT_PAD = 0, + DO_PAD = 1, + HASH_CIPHER_DO_PADDING_RESERVE32 = S32_MAX, +}; + /*****************************/ /* Descriptor packing macros */ /*****************************/ diff --git a/drivers/staging/ccree/ssi_ivgen.c b/drivers/staging/ccree/cc_ivgen.c index 3f082f41ae8f..c47f419b277b 100644 --- a/drivers/staging/ccree/ssi_ivgen.c +++ b/drivers/staging/ccree/cc_ivgen.c @@ -1,38 +1,23 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ -#include <linux/platform_device.h> #include <crypto/ctr.h> -#include "ssi_config.h" -#include "ssi_driver.h" -#include "ssi_ivgen.h" -#include "ssi_request_mgr.h" -#include "ssi_sram_mgr.h" -#include "ssi_buffer_mgr.h" +#include "cc_driver.h" +#include "cc_ivgen.h" +#include "cc_request_mgr.h" +#include "cc_sram_mgr.h" +#include "cc_buffer_mgr.h" /* The max. size of pool *MUST* be <= SRAM total size */ -#define SSI_IVPOOL_SIZE 1024 +#define CC_IVPOOL_SIZE 1024 /* The first 32B fraction of pool are dedicated to the * next encryption "key" & "IV" for pool regeneration */ -#define SSI_IVPOOL_META_SIZE (CC_AES_IV_SIZE + AES_KEYSIZE_128) -#define SSI_IVPOOL_GEN_SEQ_LEN 4 +#define CC_IVPOOL_META_SIZE (CC_AES_IV_SIZE + AES_KEYSIZE_128) +#define CC_IVPOOL_GEN_SEQ_LEN 4 /** - * struct ssi_ivgen_ctx -IV pool generation context + * struct cc_ivgen_ctx -IV pool generation context * @pool: the start address of the iv-pool resides in internal RAM * @ctr_key_dma: address of pool's encryption key material in internal RAM * @ctr_iv_dma: address of pool's counter iv in internal RAM @@ -40,31 +25,29 @@ * @pool_meta: virt. address of the initial enc. key/IV * @pool_meta_dma: phys. address of the initial enc. key/IV */ -struct ssi_ivgen_ctx { - ssi_sram_addr_t pool; - ssi_sram_addr_t ctr_key; - ssi_sram_addr_t ctr_iv; +struct cc_ivgen_ctx { + cc_sram_addr_t pool; + cc_sram_addr_t ctr_key; + cc_sram_addr_t ctr_iv; u32 next_iv_ofs; u8 *pool_meta; dma_addr_t pool_meta_dma; }; /*! - * Generates SSI_IVPOOL_SIZE of random bytes by + * Generates CC_IVPOOL_SIZE of random bytes by * encrypting 0's using AES128-CTR. * * \param ivgen iv-pool context * \param iv_seq IN/OUT array to the descriptors sequence * \param iv_seq_len IN/OUT pointer to the sequence length */ -static int ssi_ivgen_generate_pool( - struct ssi_ivgen_ctx *ivgen_ctx, - struct cc_hw_desc iv_seq[], - unsigned int *iv_seq_len) +static int cc_gen_iv_pool(struct cc_ivgen_ctx *ivgen_ctx, + struct cc_hw_desc iv_seq[], unsigned int *iv_seq_len) { unsigned int idx = *iv_seq_len; - if ((*iv_seq_len + SSI_IVPOOL_GEN_SEQ_LEN) > SSI_IVPOOL_SEQ_LEN) { + if ((*iv_seq_len + CC_IVPOOL_GEN_SEQ_LEN) > CC_IVPOOL_SEQ_LEN) { /* The sequence will be longer than allowed */ return -EINVAL; } @@ -97,15 +80,15 @@ static int ssi_ivgen_generate_pool( /* Generate IV pool */ hw_desc_init(&iv_seq[idx]); - set_din_const(&iv_seq[idx], 0, SSI_IVPOOL_SIZE); - set_dout_sram(&iv_seq[idx], ivgen_ctx->pool, SSI_IVPOOL_SIZE); + set_din_const(&iv_seq[idx], 0, CC_IVPOOL_SIZE); + set_dout_sram(&iv_seq[idx], ivgen_ctx->pool, CC_IVPOOL_SIZE); set_flow_mode(&iv_seq[idx], DIN_AES_DOUT); idx++; *iv_seq_len = idx; /* Update sequence length */ /* queue ordering assures pool readiness */ - ivgen_ctx->next_iv_ofs = SSI_IVPOOL_META_SIZE; + ivgen_ctx->next_iv_ofs = CC_IVPOOL_META_SIZE; return 0; } @@ -118,15 +101,15 @@ static int ssi_ivgen_generate_pool( * * \return int Zero for success, negative value otherwise. */ -int ssi_ivgen_init_sram_pool(struct ssi_drvdata *drvdata) +int cc_init_iv_sram(struct cc_drvdata *drvdata) { - struct ssi_ivgen_ctx *ivgen_ctx = drvdata->ivgen_handle; - struct cc_hw_desc iv_seq[SSI_IVPOOL_SEQ_LEN]; + struct cc_ivgen_ctx *ivgen_ctx = drvdata->ivgen_handle; + struct cc_hw_desc iv_seq[CC_IVPOOL_SEQ_LEN]; unsigned int iv_seq_len = 0; int rc; /* Generate initial enc. key/iv */ - get_random_bytes(ivgen_ctx->pool_meta, SSI_IVPOOL_META_SIZE); + get_random_bytes(ivgen_ctx->pool_meta, CC_IVPOOL_META_SIZE); /* The first 32B reserved for the enc. Key/IV */ ivgen_ctx->ctr_key = ivgen_ctx->pool; @@ -135,15 +118,15 @@ int ssi_ivgen_init_sram_pool(struct ssi_drvdata *drvdata) /* Copy initial enc. key and IV to SRAM at a single descriptor */ hw_desc_init(&iv_seq[iv_seq_len]); set_din_type(&iv_seq[iv_seq_len], DMA_DLLI, ivgen_ctx->pool_meta_dma, - SSI_IVPOOL_META_SIZE, NS_BIT); + CC_IVPOOL_META_SIZE, NS_BIT); set_dout_sram(&iv_seq[iv_seq_len], ivgen_ctx->pool, - SSI_IVPOOL_META_SIZE); + CC_IVPOOL_META_SIZE); set_flow_mode(&iv_seq[iv_seq_len], BYPASS); iv_seq_len++; /* Generate initial pool */ - rc = ssi_ivgen_generate_pool(ivgen_ctx, iv_seq, &iv_seq_len); - if (unlikely(rc != 0)) + rc = cc_gen_iv_pool(ivgen_ctx, iv_seq, &iv_seq_len); + if (rc) return rc; /* Fire-and-forget */ @@ -155,17 +138,17 @@ int ssi_ivgen_init_sram_pool(struct ssi_drvdata *drvdata) * * \param drvdata */ -void ssi_ivgen_fini(struct ssi_drvdata *drvdata) +void cc_ivgen_fini(struct cc_drvdata *drvdata) { - struct ssi_ivgen_ctx *ivgen_ctx = drvdata->ivgen_handle; + struct cc_ivgen_ctx *ivgen_ctx = drvdata->ivgen_handle; struct device *device = &drvdata->plat_dev->dev; if (!ivgen_ctx) return; if (ivgen_ctx->pool_meta) { - memset(ivgen_ctx->pool_meta, 0, SSI_IVPOOL_META_SIZE); - dma_free_coherent(device, SSI_IVPOOL_META_SIZE, + memset(ivgen_ctx->pool_meta, 0, CC_IVPOOL_META_SIZE); + dma_free_coherent(device, CC_IVPOOL_META_SIZE, ivgen_ctx->pool_meta, ivgen_ctx->pool_meta_dma); } @@ -184,42 +167,41 @@ void ssi_ivgen_fini(struct ssi_drvdata *drvdata) * * \return int Zero for success, negative value otherwise. */ -int ssi_ivgen_init(struct ssi_drvdata *drvdata) +int cc_ivgen_init(struct cc_drvdata *drvdata) { - struct ssi_ivgen_ctx *ivgen_ctx; + struct cc_ivgen_ctx *ivgen_ctx; struct device *device = &drvdata->plat_dev->dev; int rc; /* Allocate "this" context */ - drvdata->ivgen_handle = kzalloc(sizeof(*drvdata->ivgen_handle), - GFP_KERNEL); - if (!drvdata->ivgen_handle) + ivgen_ctx = kzalloc(sizeof(*ivgen_ctx), GFP_KERNEL); + if (!ivgen_ctx) return -ENOMEM; - ivgen_ctx = drvdata->ivgen_handle; + drvdata->ivgen_handle = ivgen_ctx; - /* Allocate pool's header for intial enc. key/IV */ - ivgen_ctx->pool_meta = dma_alloc_coherent(device, SSI_IVPOOL_META_SIZE, + /* Allocate pool's header for initial enc. key/IV */ + ivgen_ctx->pool_meta = dma_alloc_coherent(device, CC_IVPOOL_META_SIZE, &ivgen_ctx->pool_meta_dma, GFP_KERNEL); if (!ivgen_ctx->pool_meta) { dev_err(device, "Not enough memory to allocate DMA of pool_meta (%u B)\n", - SSI_IVPOOL_META_SIZE); + CC_IVPOOL_META_SIZE); rc = -ENOMEM; goto out; } /* Allocate IV pool in SRAM */ - ivgen_ctx->pool = ssi_sram_mgr_alloc(drvdata, SSI_IVPOOL_SIZE); + ivgen_ctx->pool = cc_sram_alloc(drvdata, CC_IVPOOL_SIZE); if (ivgen_ctx->pool == NULL_SRAM_ADDR) { dev_err(device, "SRAM pool exhausted\n"); rc = -ENOMEM; goto out; } - return ssi_ivgen_init_sram_pool(drvdata); + return cc_init_iv_sram(drvdata); out: - ssi_ivgen_fini(drvdata); + cc_ivgen_fini(drvdata); return rc; } @@ -228,37 +210,36 @@ out: * * \param drvdata Driver private context * \param iv_out_dma Array of physical IV out addresses - * \param iv_out_dma_len Length of iv_out_dma array (additional elements of iv_out_dma array are ignore) + * \param iv_out_dma_len Length of iv_out_dma array (additional elements + * of iv_out_dma array are ignore) * \param iv_out_size May be 8 or 16 bytes long * \param iv_seq IN/OUT array to the descriptors sequence * \param iv_seq_len IN/OUT pointer to the sequence length * * \return int Zero for success, negative value otherwise. */ -int ssi_ivgen_getiv( - struct ssi_drvdata *drvdata, - dma_addr_t iv_out_dma[], - unsigned int iv_out_dma_len, - unsigned int iv_out_size, - struct cc_hw_desc iv_seq[], - unsigned int *iv_seq_len) +int cc_get_iv(struct cc_drvdata *drvdata, dma_addr_t iv_out_dma[], + unsigned int iv_out_dma_len, unsigned int iv_out_size, + struct cc_hw_desc iv_seq[], unsigned int *iv_seq_len) { - struct ssi_ivgen_ctx *ivgen_ctx = drvdata->ivgen_handle; + struct cc_ivgen_ctx *ivgen_ctx = drvdata->ivgen_handle; unsigned int idx = *iv_seq_len; struct device *dev = drvdata_to_dev(drvdata); unsigned int t; - if ((iv_out_size != CC_AES_IV_SIZE) && - (iv_out_size != CTR_RFC3686_IV_SIZE)) { + if (iv_out_size != CC_AES_IV_SIZE && + iv_out_size != CTR_RFC3686_IV_SIZE) { return -EINVAL; } - if ((iv_out_dma_len + 1) > SSI_IVPOOL_SEQ_LEN) { + if ((iv_out_dma_len + 1) > CC_IVPOOL_SEQ_LEN) { /* The sequence will be longer than allowed */ return -EINVAL; } - //check that number of generated IV is limited to max dma address iv buffer size - if (iv_out_dma_len > SSI_MAX_IVGEN_DMA_ADDRESSES) { + /* check that number of generated IV is limited to max dma address + * iv buffer size + */ + if (iv_out_dma_len > CC_MAX_IVGEN_DMA_ADDRESSES) { /* The sequence will be longer than allowed */ return -EINVAL; } @@ -288,10 +269,10 @@ int ssi_ivgen_getiv( /* Update iv index */ ivgen_ctx->next_iv_ofs += iv_out_size; - if ((SSI_IVPOOL_SIZE - ivgen_ctx->next_iv_ofs) < CC_AES_IV_SIZE) { + if ((CC_IVPOOL_SIZE - ivgen_ctx->next_iv_ofs) < CC_AES_IV_SIZE) { dev_dbg(dev, "Pool exhausted, regenerating iv-pool\n"); /* pool is drained -regenerate it! */ - return ssi_ivgen_generate_pool(ivgen_ctx, iv_seq, iv_seq_len); + return cc_gen_iv_pool(ivgen_ctx, iv_seq, iv_seq_len); } return 0; diff --git a/drivers/staging/ccree/cc_ivgen.h b/drivers/staging/ccree/cc_ivgen.h new file mode 100644 index 000000000000..b6ac16903dda --- /dev/null +++ b/drivers/staging/ccree/cc_ivgen.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ + +#ifndef __CC_IVGEN_H__ +#define __CC_IVGEN_H__ + +#include "cc_hw_queue_defs.h" + +#define CC_IVPOOL_SEQ_LEN 8 + +/*! + * Allocates iv-pool and maps resources. + * This function generates the first IV pool. + * + * \param drvdata Driver's private context + * + * \return int Zero for success, negative value otherwise. + */ +int cc_ivgen_init(struct cc_drvdata *drvdata); + +/*! + * Free iv-pool and ivgen context. + * + * \param drvdata + */ +void cc_ivgen_fini(struct cc_drvdata *drvdata); + +/*! + * Generates the initial pool in SRAM. + * This function should be invoked when resuming DX driver. + * + * \param drvdata + * + * \return int Zero for success, negative value otherwise. + */ +int cc_init_iv_sram(struct cc_drvdata *drvdata); + +/*! + * Acquires 16 Bytes IV from the iv-pool + * + * \param drvdata Driver private context + * \param iv_out_dma Array of physical IV out addresses + * \param iv_out_dma_len Length of iv_out_dma array (additional elements of + * iv_out_dma array are ignore) + * \param iv_out_size May be 8 or 16 bytes long + * \param iv_seq IN/OUT array to the descriptors sequence + * \param iv_seq_len IN/OUT pointer to the sequence length + * + * \return int Zero for success, negative value otherwise. + */ +int cc_get_iv(struct cc_drvdata *drvdata, dma_addr_t iv_out_dma[], + unsigned int iv_out_dma_len, unsigned int iv_out_size, + struct cc_hw_desc iv_seq[], unsigned int *iv_seq_len); + +#endif /*__CC_IVGEN_H__*/ diff --git a/drivers/staging/ccree/cc_kernel_regs.h b/drivers/staging/ccree/cc_kernel_regs.h new file mode 100644 index 000000000000..fa994406d610 --- /dev/null +++ b/drivers/staging/ccree/cc_kernel_regs.h @@ -0,0 +1,167 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ + +#ifndef __CC_CRYS_KERNEL_H__ +#define __CC_CRYS_KERNEL_H__ + +// -------------------------------------- +// BLOCK: DSCRPTR +// -------------------------------------- +#define CC_DSCRPTR_COMPLETION_COUNTER_REG_OFFSET 0xE00UL +#define CC_DSCRPTR_COMPLETION_COUNTER_COMPLETION_COUNTER_BIT_SHIFT 0x0UL +#define CC_DSCRPTR_COMPLETION_COUNTER_COMPLETION_COUNTER_BIT_SIZE 0x6UL +#define CC_DSCRPTR_COMPLETION_COUNTER_OVERFLOW_COUNTER_BIT_SHIFT 0x6UL +#define CC_DSCRPTR_COMPLETION_COUNTER_OVERFLOW_COUNTER_BIT_SIZE 0x1UL +#define CC_DSCRPTR_SW_RESET_REG_OFFSET 0xE40UL +#define CC_DSCRPTR_SW_RESET_VALUE_BIT_SHIFT 0x0UL +#define CC_DSCRPTR_SW_RESET_VALUE_BIT_SIZE 0x1UL +#define CC_DSCRPTR_QUEUE_SRAM_SIZE_REG_OFFSET 0xE60UL +#define CC_DSCRPTR_QUEUE_SRAM_SIZE_NUM_OF_DSCRPTR_BIT_SHIFT 0x0UL +#define CC_DSCRPTR_QUEUE_SRAM_SIZE_NUM_OF_DSCRPTR_BIT_SIZE 0xAUL +#define CC_DSCRPTR_QUEUE_SRAM_SIZE_DSCRPTR_SRAM_SIZE_BIT_SHIFT 0xAUL +#define CC_DSCRPTR_QUEUE_SRAM_SIZE_DSCRPTR_SRAM_SIZE_BIT_SIZE 0xCUL +#define CC_DSCRPTR_QUEUE_SRAM_SIZE_SRAM_SIZE_BIT_SHIFT 0x16UL +#define CC_DSCRPTR_QUEUE_SRAM_SIZE_SRAM_SIZE_BIT_SIZE 0x3UL +#define CC_DSCRPTR_SINGLE_ADDR_EN_REG_OFFSET 0xE64UL +#define CC_DSCRPTR_SINGLE_ADDR_EN_VALUE_BIT_SHIFT 0x0UL +#define CC_DSCRPTR_SINGLE_ADDR_EN_VALUE_BIT_SIZE 0x1UL +#define CC_DSCRPTR_MEASURE_CNTR_REG_OFFSET 0xE68UL +#define CC_DSCRPTR_MEASURE_CNTR_VALUE_BIT_SHIFT 0x0UL +#define CC_DSCRPTR_MEASURE_CNTR_VALUE_BIT_SIZE 0x20UL +#define CC_DSCRPTR_QUEUE_WORD0_REG_OFFSET 0xE80UL +#define CC_DSCRPTR_QUEUE_WORD0_VALUE_BIT_SHIFT 0x0UL +#define CC_DSCRPTR_QUEUE_WORD0_VALUE_BIT_SIZE 0x20UL +#define CC_DSCRPTR_QUEUE_WORD1_REG_OFFSET 0xE84UL +#define CC_DSCRPTR_QUEUE_WORD1_DIN_DMA_MODE_BIT_SHIFT 0x0UL +#define CC_DSCRPTR_QUEUE_WORD1_DIN_DMA_MODE_BIT_SIZE 0x2UL +#define CC_DSCRPTR_QUEUE_WORD1_DIN_SIZE_BIT_SHIFT 0x2UL +#define CC_DSCRPTR_QUEUE_WORD1_DIN_SIZE_BIT_SIZE 0x18UL +#define CC_DSCRPTR_QUEUE_WORD1_NS_BIT_BIT_SHIFT 0x1AUL +#define CC_DSCRPTR_QUEUE_WORD1_NS_BIT_BIT_SIZE 0x1UL +#define CC_DSCRPTR_QUEUE_WORD1_DIN_CONST_VALUE_BIT_SHIFT 0x1BUL +#define CC_DSCRPTR_QUEUE_WORD1_DIN_CONST_VALUE_BIT_SIZE 0x1UL +#define CC_DSCRPTR_QUEUE_WORD1_NOT_LAST_BIT_SHIFT 0x1CUL +#define CC_DSCRPTR_QUEUE_WORD1_NOT_LAST_BIT_SIZE 0x1UL +#define CC_DSCRPTR_QUEUE_WORD1_LOCK_QUEUE_BIT_SHIFT 0x1DUL +#define CC_DSCRPTR_QUEUE_WORD1_LOCK_QUEUE_BIT_SIZE 0x1UL +#define CC_DSCRPTR_QUEUE_WORD1_NOT_USED_BIT_SHIFT 0x1EUL +#define CC_DSCRPTR_QUEUE_WORD1_NOT_USED_BIT_SIZE 0x2UL +#define CC_DSCRPTR_QUEUE_WORD2_REG_OFFSET 0xE88UL +#define CC_DSCRPTR_QUEUE_WORD2_VALUE_BIT_SHIFT 0x0UL +#define CC_DSCRPTR_QUEUE_WORD2_VALUE_BIT_SIZE 0x20UL +#define CC_DSCRPTR_QUEUE_WORD3_REG_OFFSET 0xE8CUL +#define CC_DSCRPTR_QUEUE_WORD3_DOUT_DMA_MODE_BIT_SHIFT 0x0UL +#define CC_DSCRPTR_QUEUE_WORD3_DOUT_DMA_MODE_BIT_SIZE 0x2UL +#define CC_DSCRPTR_QUEUE_WORD3_DOUT_SIZE_BIT_SHIFT 0x2UL +#define CC_DSCRPTR_QUEUE_WORD3_DOUT_SIZE_BIT_SIZE 0x18UL +#define CC_DSCRPTR_QUEUE_WORD3_NS_BIT_BIT_SHIFT 0x1AUL +#define CC_DSCRPTR_QUEUE_WORD3_NS_BIT_BIT_SIZE 0x1UL +#define CC_DSCRPTR_QUEUE_WORD3_DOUT_LAST_IND_BIT_SHIFT 0x1BUL +#define CC_DSCRPTR_QUEUE_WORD3_DOUT_LAST_IND_BIT_SIZE 0x1UL +#define CC_DSCRPTR_QUEUE_WORD3_HASH_XOR_BIT_BIT_SHIFT 0x1DUL +#define CC_DSCRPTR_QUEUE_WORD3_HASH_XOR_BIT_BIT_SIZE 0x1UL +#define CC_DSCRPTR_QUEUE_WORD3_NOT_USED_BIT_SHIFT 0x1EUL +#define CC_DSCRPTR_QUEUE_WORD3_NOT_USED_BIT_SIZE 0x1UL +#define CC_DSCRPTR_QUEUE_WORD3_QUEUE_LAST_IND_BIT_SHIFT 0x1FUL +#define CC_DSCRPTR_QUEUE_WORD3_QUEUE_LAST_IND_BIT_SIZE 0x1UL +#define CC_DSCRPTR_QUEUE_WORD4_REG_OFFSET 0xE90UL +#define CC_DSCRPTR_QUEUE_WORD4_DATA_FLOW_MODE_BIT_SHIFT 0x0UL +#define CC_DSCRPTR_QUEUE_WORD4_DATA_FLOW_MODE_BIT_SIZE 0x6UL +#define CC_DSCRPTR_QUEUE_WORD4_AES_SEL_N_HASH_BIT_SHIFT 0x6UL +#define CC_DSCRPTR_QUEUE_WORD4_AES_SEL_N_HASH_BIT_SIZE 0x1UL +#define CC_DSCRPTR_QUEUE_WORD4_AES_XOR_CRYPTO_KEY_BIT_SHIFT 0x7UL +#define CC_DSCRPTR_QUEUE_WORD4_AES_XOR_CRYPTO_KEY_BIT_SIZE 0x1UL +#define CC_DSCRPTR_QUEUE_WORD4_ACK_NEEDED_BIT_SHIFT 0x8UL +#define CC_DSCRPTR_QUEUE_WORD4_ACK_NEEDED_BIT_SIZE 0x2UL +#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_MODE_BIT_SHIFT 0xAUL +#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_MODE_BIT_SIZE 0x4UL +#define CC_DSCRPTR_QUEUE_WORD4_CMAC_SIZE0_BIT_SHIFT 0xEUL +#define CC_DSCRPTR_QUEUE_WORD4_CMAC_SIZE0_BIT_SIZE 0x1UL +#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_DO_BIT_SHIFT 0xFUL +#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_DO_BIT_SIZE 0x2UL +#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_CONF0_BIT_SHIFT 0x11UL +#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_CONF0_BIT_SIZE 0x2UL +#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_CONF1_BIT_SHIFT 0x13UL +#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_CONF1_BIT_SIZE 0x1UL +#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_CONF2_BIT_SHIFT 0x14UL +#define CC_DSCRPTR_QUEUE_WORD4_CIPHER_CONF2_BIT_SIZE 0x2UL +#define CC_DSCRPTR_QUEUE_WORD4_KEY_SIZE_BIT_SHIFT 0x16UL +#define CC_DSCRPTR_QUEUE_WORD4_KEY_SIZE_BIT_SIZE 0x2UL +#define CC_DSCRPTR_QUEUE_WORD4_SETUP_OPERATION_BIT_SHIFT 0x18UL +#define CC_DSCRPTR_QUEUE_WORD4_SETUP_OPERATION_BIT_SIZE 0x4UL +#define CC_DSCRPTR_QUEUE_WORD4_DIN_SRAM_ENDIANNESS_BIT_SHIFT 0x1CUL +#define CC_DSCRPTR_QUEUE_WORD4_DIN_SRAM_ENDIANNESS_BIT_SIZE 0x1UL +#define CC_DSCRPTR_QUEUE_WORD4_DOUT_SRAM_ENDIANNESS_BIT_SHIFT 0x1DUL +#define CC_DSCRPTR_QUEUE_WORD4_DOUT_SRAM_ENDIANNESS_BIT_SIZE 0x1UL +#define CC_DSCRPTR_QUEUE_WORD4_WORD_SWAP_BIT_SHIFT 0x1EUL +#define CC_DSCRPTR_QUEUE_WORD4_WORD_SWAP_BIT_SIZE 0x1UL +#define CC_DSCRPTR_QUEUE_WORD4_BYTES_SWAP_BIT_SHIFT 0x1FUL +#define CC_DSCRPTR_QUEUE_WORD4_BYTES_SWAP_BIT_SIZE 0x1UL +#define CC_DSCRPTR_QUEUE_WORD5_REG_OFFSET 0xE94UL +#define CC_DSCRPTR_QUEUE_WORD5_DIN_ADDR_HIGH_BIT_SHIFT 0x0UL +#define CC_DSCRPTR_QUEUE_WORD5_DIN_ADDR_HIGH_BIT_SIZE 0x10UL +#define CC_DSCRPTR_QUEUE_WORD5_DOUT_ADDR_HIGH_BIT_SHIFT 0x10UL +#define CC_DSCRPTR_QUEUE_WORD5_DOUT_ADDR_HIGH_BIT_SIZE 0x10UL +#define CC_DSCRPTR_QUEUE_WATERMARK_REG_OFFSET 0xE98UL +#define CC_DSCRPTR_QUEUE_WATERMARK_VALUE_BIT_SHIFT 0x0UL +#define CC_DSCRPTR_QUEUE_WATERMARK_VALUE_BIT_SIZE 0xAUL +#define CC_DSCRPTR_QUEUE_CONTENT_REG_OFFSET 0xE9CUL +#define CC_DSCRPTR_QUEUE_CONTENT_VALUE_BIT_SHIFT 0x0UL +#define CC_DSCRPTR_QUEUE_CONTENT_VALUE_BIT_SIZE 0xAUL +// -------------------------------------- +// BLOCK: AXI_P +// -------------------------------------- +#define CC_AXIM_MON_INFLIGHT_REG_OFFSET 0xB00UL +#define CC_AXIM_MON_INFLIGHT_VALUE_BIT_SHIFT 0x0UL +#define CC_AXIM_MON_INFLIGHT_VALUE_BIT_SIZE 0x8UL +#define CC_AXIM_MON_INFLIGHTLAST_REG_OFFSET 0xB40UL +#define CC_AXIM_MON_INFLIGHTLAST_VALUE_BIT_SHIFT 0x0UL +#define CC_AXIM_MON_INFLIGHTLAST_VALUE_BIT_SIZE 0x8UL +#define CC_AXIM_MON_COMP_REG_OFFSET 0xB80UL +#define CC_AXIM_MON_COMP_VALUE_BIT_SHIFT 0x0UL +#define CC_AXIM_MON_COMP_VALUE_BIT_SIZE 0x10UL +#define CC_AXIM_MON_ERR_REG_OFFSET 0xBC4UL +#define CC_AXIM_MON_ERR_BRESP_BIT_SHIFT 0x0UL +#define CC_AXIM_MON_ERR_BRESP_BIT_SIZE 0x2UL +#define CC_AXIM_MON_ERR_BID_BIT_SHIFT 0x2UL +#define CC_AXIM_MON_ERR_BID_BIT_SIZE 0x4UL +#define CC_AXIM_MON_ERR_RRESP_BIT_SHIFT 0x10UL +#define CC_AXIM_MON_ERR_RRESP_BIT_SIZE 0x2UL +#define CC_AXIM_MON_ERR_RID_BIT_SHIFT 0x12UL +#define CC_AXIM_MON_ERR_RID_BIT_SIZE 0x4UL +#define CC_AXIM_CFG_REG_OFFSET 0xBE8UL +#define CC_AXIM_CFG_BRESPMASK_BIT_SHIFT 0x4UL +#define CC_AXIM_CFG_BRESPMASK_BIT_SIZE 0x1UL +#define CC_AXIM_CFG_RRESPMASK_BIT_SHIFT 0x5UL +#define CC_AXIM_CFG_RRESPMASK_BIT_SIZE 0x1UL +#define CC_AXIM_CFG_INFLTMASK_BIT_SHIFT 0x6UL +#define CC_AXIM_CFG_INFLTMASK_BIT_SIZE 0x1UL +#define CC_AXIM_CFG_COMPMASK_BIT_SHIFT 0x7UL +#define CC_AXIM_CFG_COMPMASK_BIT_SIZE 0x1UL +#define CC_AXIM_ACE_CONST_REG_OFFSET 0xBECUL +#define CC_AXIM_ACE_CONST_ARDOMAIN_BIT_SHIFT 0x0UL +#define CC_AXIM_ACE_CONST_ARDOMAIN_BIT_SIZE 0x2UL +#define CC_AXIM_ACE_CONST_AWDOMAIN_BIT_SHIFT 0x2UL +#define CC_AXIM_ACE_CONST_AWDOMAIN_BIT_SIZE 0x2UL +#define CC_AXIM_ACE_CONST_ARBAR_BIT_SHIFT 0x4UL +#define CC_AXIM_ACE_CONST_ARBAR_BIT_SIZE 0x2UL +#define CC_AXIM_ACE_CONST_AWBAR_BIT_SHIFT 0x6UL +#define CC_AXIM_ACE_CONST_AWBAR_BIT_SIZE 0x2UL +#define CC_AXIM_ACE_CONST_ARSNOOP_BIT_SHIFT 0x8UL +#define CC_AXIM_ACE_CONST_ARSNOOP_BIT_SIZE 0x4UL +#define CC_AXIM_ACE_CONST_AWSNOOP_NOT_ALIGNED_BIT_SHIFT 0xCUL +#define CC_AXIM_ACE_CONST_AWSNOOP_NOT_ALIGNED_BIT_SIZE 0x3UL +#define CC_AXIM_ACE_CONST_AWSNOOP_ALIGNED_BIT_SHIFT 0xFUL +#define CC_AXIM_ACE_CONST_AWSNOOP_ALIGNED_BIT_SIZE 0x3UL +#define CC_AXIM_ACE_CONST_AWADDR_NOT_MASKED_BIT_SHIFT 0x12UL +#define CC_AXIM_ACE_CONST_AWADDR_NOT_MASKED_BIT_SIZE 0x7UL +#define CC_AXIM_ACE_CONST_AWLEN_VAL_BIT_SHIFT 0x19UL +#define CC_AXIM_ACE_CONST_AWLEN_VAL_BIT_SIZE 0x4UL +#define CC_AXIM_CACHE_PARAMS_REG_OFFSET 0xBF0UL +#define CC_AXIM_CACHE_PARAMS_AWCACHE_LAST_BIT_SHIFT 0x0UL +#define CC_AXIM_CACHE_PARAMS_AWCACHE_LAST_BIT_SIZE 0x4UL +#define CC_AXIM_CACHE_PARAMS_AWCACHE_BIT_SHIFT 0x4UL +#define CC_AXIM_CACHE_PARAMS_AWCACHE_BIT_SIZE 0x4UL +#define CC_AXIM_CACHE_PARAMS_ARCACHE_BIT_SHIFT 0x8UL +#define CC_AXIM_CACHE_PARAMS_ARCACHE_BIT_SIZE 0x4UL +#endif // __CC_CRYS_KERNEL_H__ diff --git a/drivers/staging/ccree/cc_lli_defs.h b/drivers/staging/ccree/cc_lli_defs.h index a9c417b07b04..64b15ac9f1d3 100644 --- a/drivers/staging/ccree/cc_lli_defs.h +++ b/drivers/staging/ccree/cc_lli_defs.h @@ -1,18 +1,5 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ #ifndef _CC_LLI_DEFS_H_ #define _CC_LLI_DEFS_H_ @@ -20,7 +7,7 @@ #include <linux/types.h> /* Max DLLI size - * AKA DX_DSCRPTR_QUEUE_WORD1_DIN_SIZE_BIT_SIZE + * AKA CC_DSCRPTR_QUEUE_WORD1_DIN_SIZE_BIT_SIZE */ #define DLLI_SIZE_BIT_SIZE 0x18 diff --git a/drivers/staging/ccree/cc_pm.c b/drivers/staging/ccree/cc_pm.c new file mode 100644 index 000000000000..d990f472e89f --- /dev/null +++ b/drivers/staging/ccree/cc_pm.c @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ + +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/pm_runtime.h> +#include "cc_driver.h" +#include "cc_buffer_mgr.h" +#include "cc_request_mgr.h" +#include "cc_sram_mgr.h" +#include "cc_ivgen.h" +#include "cc_hash.h" +#include "cc_pm.h" + +#define POWER_DOWN_ENABLE 0x01 +#define POWER_DOWN_DISABLE 0x00 + +const struct dev_pm_ops ccree_pm = { + SET_RUNTIME_PM_OPS(cc_pm_suspend, cc_pm_resume, NULL) +}; + +int cc_pm_suspend(struct device *dev) +{ + struct cc_drvdata *drvdata = dev_get_drvdata(dev); + int rc; + + dev_dbg(dev, "set HOST_POWER_DOWN_EN\n"); + cc_iowrite(drvdata, CC_REG(HOST_POWER_DOWN_EN), POWER_DOWN_ENABLE); + rc = cc_suspend_req_queue(drvdata); + if (rc) { + dev_err(dev, "cc_suspend_req_queue (%x)\n", rc); + return rc; + } + fini_cc_regs(drvdata); + cc_clk_off(drvdata); + return 0; +} + +int cc_pm_resume(struct device *dev) +{ + int rc; + struct cc_drvdata *drvdata = dev_get_drvdata(dev); + + dev_dbg(dev, "unset HOST_POWER_DOWN_EN\n"); + cc_iowrite(drvdata, CC_REG(HOST_POWER_DOWN_EN), POWER_DOWN_DISABLE); + + rc = cc_clk_on(drvdata); + if (rc) { + dev_err(dev, "failed getting clock back on. We're toast.\n"); + return rc; + } + + rc = init_cc_regs(drvdata, false); + if (rc) { + dev_err(dev, "init_cc_regs (%x)\n", rc); + return rc; + } + + rc = cc_resume_req_queue(drvdata); + if (rc) { + dev_err(dev, "cc_resume_req_queue (%x)\n", rc); + return rc; + } + + /* must be after the queue resuming as it uses the HW queue*/ + cc_init_hash_sram(drvdata); + + cc_init_iv_sram(drvdata); + return 0; +} + +int cc_pm_get(struct device *dev) +{ + int rc = 0; + struct cc_drvdata *drvdata = dev_get_drvdata(dev); + + if (cc_req_queue_suspended(drvdata)) + rc = pm_runtime_get_sync(dev); + else + pm_runtime_get_noresume(dev); + + return rc; +} + +int cc_pm_put_suspend(struct device *dev) +{ + int rc = 0; + struct cc_drvdata *drvdata = dev_get_drvdata(dev); + + if (!cc_req_queue_suspended(drvdata)) { + pm_runtime_mark_last_busy(dev); + rc = pm_runtime_put_autosuspend(dev); + } else { + /* Something wrong happens*/ + dev_err(dev, "request to suspend already suspended queue"); + rc = -EBUSY; + } + return rc; +} + +int cc_pm_init(struct cc_drvdata *drvdata) +{ + int rc = 0; + struct device *dev = drvdata_to_dev(drvdata); + + /* must be before the enabling to avoid resdundent suspending */ + pm_runtime_set_autosuspend_delay(dev, CC_SUSPEND_TIMEOUT); + pm_runtime_use_autosuspend(dev); + /* activate the PM module */ + rc = pm_runtime_set_active(dev); + if (rc) + return rc; + /* enable the PM module*/ + pm_runtime_enable(dev); + + return rc; +} + +void cc_pm_fini(struct cc_drvdata *drvdata) +{ + pm_runtime_disable(drvdata_to_dev(drvdata)); +} diff --git a/drivers/staging/ccree/cc_pm.h b/drivers/staging/ccree/cc_pm.h new file mode 100644 index 000000000000..aac8190fea38 --- /dev/null +++ b/drivers/staging/ccree/cc_pm.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ + +/* \file cc_pm.h + */ + +#ifndef __CC_POWER_MGR_H__ +#define __CC_POWER_MGR_H__ + +#include "cc_driver.h" + +#define CC_SUSPEND_TIMEOUT 3000 + +#if defined(CONFIG_PM) + +extern const struct dev_pm_ops ccree_pm; + +int cc_pm_init(struct cc_drvdata *drvdata); +void cc_pm_fini(struct cc_drvdata *drvdata); +int cc_pm_suspend(struct device *dev); +int cc_pm_resume(struct device *dev); +int cc_pm_get(struct device *dev); +int cc_pm_put_suspend(struct device *dev); + +#else + +static inline int cc_pm_init(struct cc_drvdata *drvdata) +{ + return 0; +} + +static inline void cc_pm_fini(struct cc_drvdata *drvdata) {} + +static inline int cc_pm_suspend(struct device *dev) +{ + return 0; +} + +static inline int cc_pm_resume(struct device *dev) +{ + return 0; +} + +static inline int cc_pm_get(struct device *dev) +{ + return 0; +} + +static inline int cc_pm_put_suspend(struct device *dev) +{ + return 0; +} + +#endif + +#endif /*__POWER_MGR_H__*/ + diff --git a/drivers/staging/ccree/cc_request_mgr.c b/drivers/staging/ccree/cc_request_mgr.c new file mode 100644 index 000000000000..8a7f83407410 --- /dev/null +++ b/drivers/staging/ccree/cc_request_mgr.c @@ -0,0 +1,713 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ + +#include <linux/kernel.h> +#include "cc_driver.h" +#include "cc_buffer_mgr.h" +#include "cc_request_mgr.h" +#include "cc_ivgen.h" +#include "cc_pm.h" + +#define CC_MAX_POLL_ITER 10 +/* The highest descriptor count in used */ +#define CC_MAX_DESC_SEQ_LEN 23 + +struct cc_req_mgr_handle { + /* Request manager resources */ + unsigned int hw_queue_size; /* HW capability */ + unsigned int min_free_hw_slots; + unsigned int max_used_sw_slots; + struct cc_crypto_req req_queue[MAX_REQUEST_QUEUE_SIZE]; + u32 req_queue_head; + u32 req_queue_tail; + u32 axi_completed; + u32 q_free_slots; + /* This lock protects access to HW register + * that must be single request at a time + */ + spinlock_t hw_lock; + struct cc_hw_desc compl_desc; + u8 *dummy_comp_buff; + dma_addr_t dummy_comp_buff_dma; + + /* backlog queue */ + struct list_head backlog; + unsigned int bl_len; + spinlock_t bl_lock; /* protect backlog queue */ + +#ifdef COMP_IN_WQ + struct workqueue_struct *workq; + struct delayed_work compwork; +#else + struct tasklet_struct comptask; +#endif + bool is_runtime_suspended; +}; + +struct cc_bl_item { + struct cc_crypto_req creq; + struct cc_hw_desc desc[CC_MAX_DESC_SEQ_LEN]; + unsigned int len; + struct list_head list; + bool notif; +}; + +static void comp_handler(unsigned long devarg); +#ifdef COMP_IN_WQ +static void comp_work_handler(struct work_struct *work); +#endif + +void cc_req_mgr_fini(struct cc_drvdata *drvdata) +{ + struct cc_req_mgr_handle *req_mgr_h = drvdata->request_mgr_handle; + struct device *dev = drvdata_to_dev(drvdata); + + if (!req_mgr_h) + return; /* Not allocated */ + + if (req_mgr_h->dummy_comp_buff_dma) { + dma_free_coherent(dev, sizeof(u32), req_mgr_h->dummy_comp_buff, + req_mgr_h->dummy_comp_buff_dma); + } + + dev_dbg(dev, "max_used_hw_slots=%d\n", (req_mgr_h->hw_queue_size - + req_mgr_h->min_free_hw_slots)); + dev_dbg(dev, "max_used_sw_slots=%d\n", req_mgr_h->max_used_sw_slots); + +#ifdef COMP_IN_WQ + flush_workqueue(req_mgr_h->workq); + destroy_workqueue(req_mgr_h->workq); +#else + /* Kill tasklet */ + tasklet_kill(&req_mgr_h->comptask); +#endif + memset(req_mgr_h, 0, sizeof(struct cc_req_mgr_handle)); + kfree(req_mgr_h); + drvdata->request_mgr_handle = NULL; +} + +int cc_req_mgr_init(struct cc_drvdata *drvdata) +{ + struct cc_req_mgr_handle *req_mgr_h; + struct device *dev = drvdata_to_dev(drvdata); + int rc = 0; + + req_mgr_h = kzalloc(sizeof(*req_mgr_h), GFP_KERNEL); + if (!req_mgr_h) { + rc = -ENOMEM; + goto req_mgr_init_err; + } + + drvdata->request_mgr_handle = req_mgr_h; + + spin_lock_init(&req_mgr_h->hw_lock); + spin_lock_init(&req_mgr_h->bl_lock); + INIT_LIST_HEAD(&req_mgr_h->backlog); + +#ifdef COMP_IN_WQ + dev_dbg(dev, "Initializing completion workqueue\n"); + req_mgr_h->workq = create_singlethread_workqueue("arm_cc7x_wq"); + if (!req_mgr_h->workq) { + dev_err(dev, "Failed creating work queue\n"); + rc = -ENOMEM; + goto req_mgr_init_err; + } + INIT_DELAYED_WORK(&req_mgr_h->compwork, comp_work_handler); +#else + dev_dbg(dev, "Initializing completion tasklet\n"); + tasklet_init(&req_mgr_h->comptask, comp_handler, + (unsigned long)drvdata); +#endif + req_mgr_h->hw_queue_size = cc_ioread(drvdata, + CC_REG(DSCRPTR_QUEUE_SRAM_SIZE)); + dev_dbg(dev, "hw_queue_size=0x%08X\n", req_mgr_h->hw_queue_size); + if (req_mgr_h->hw_queue_size < MIN_HW_QUEUE_SIZE) { + dev_err(dev, "Invalid HW queue size = %u (Min. required is %u)\n", + req_mgr_h->hw_queue_size, MIN_HW_QUEUE_SIZE); + rc = -ENOMEM; + goto req_mgr_init_err; + } + req_mgr_h->min_free_hw_slots = req_mgr_h->hw_queue_size; + req_mgr_h->max_used_sw_slots = 0; + + /* Allocate DMA word for "dummy" completion descriptor use */ + req_mgr_h->dummy_comp_buff = + dma_alloc_coherent(dev, sizeof(u32), + &req_mgr_h->dummy_comp_buff_dma, + GFP_KERNEL); + if (!req_mgr_h->dummy_comp_buff) { + dev_err(dev, "Not enough memory to allocate DMA (%zu) dropped buffer\n", + sizeof(u32)); + rc = -ENOMEM; + goto req_mgr_init_err; + } + + /* Init. "dummy" completion descriptor */ + hw_desc_init(&req_mgr_h->compl_desc); + set_din_const(&req_mgr_h->compl_desc, 0, sizeof(u32)); + set_dout_dlli(&req_mgr_h->compl_desc, req_mgr_h->dummy_comp_buff_dma, + sizeof(u32), NS_BIT, 1); + set_flow_mode(&req_mgr_h->compl_desc, BYPASS); + set_queue_last_ind(&req_mgr_h->compl_desc); + + return 0; + +req_mgr_init_err: + cc_req_mgr_fini(drvdata); + return rc; +} + +static void enqueue_seq(struct cc_drvdata *drvdata, struct cc_hw_desc seq[], + unsigned int seq_len) +{ + int i, w; + void __iomem *reg = drvdata->cc_base + CC_REG(DSCRPTR_QUEUE_WORD0); + struct device *dev = drvdata_to_dev(drvdata); + + /* + * We do indeed write all 6 command words to the same + * register. The HW supports this. + */ + + for (i = 0; i < seq_len; i++) { + for (w = 0; w <= 5; w++) + writel_relaxed(seq[i].word[w], reg); + + if (cc_dump_desc) + dev_dbg(dev, "desc[%02d]: 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n", + i, seq[i].word[0], seq[i].word[1], + seq[i].word[2], seq[i].word[3], + seq[i].word[4], seq[i].word[5]); + } +} + +/*! + * Completion will take place if and only if user requested completion + * by cc_send_sync_request(). + * + * \param dev + * \param dx_compl_h The completion event to signal + */ +static void request_mgr_complete(struct device *dev, void *dx_compl_h, + int dummy) +{ + struct completion *this_compl = dx_compl_h; + + complete(this_compl); +} + +static int cc_queues_status(struct cc_drvdata *drvdata, + struct cc_req_mgr_handle *req_mgr_h, + unsigned int total_seq_len) +{ + unsigned long poll_queue; + struct device *dev = drvdata_to_dev(drvdata); + + /* SW queue is checked only once as it will not + * be chaned during the poll because the spinlock_bh + * is held by the thread + */ + if (((req_mgr_h->req_queue_head + 1) & (MAX_REQUEST_QUEUE_SIZE - 1)) == + req_mgr_h->req_queue_tail) { + dev_err(dev, "SW FIFO is full. req_queue_head=%d sw_fifo_len=%d\n", + req_mgr_h->req_queue_head, MAX_REQUEST_QUEUE_SIZE); + return -ENOSPC; + } + + if (req_mgr_h->q_free_slots >= total_seq_len) + return 0; + + /* Wait for space in HW queue. Poll constant num of iterations. */ + for (poll_queue = 0; poll_queue < CC_MAX_POLL_ITER ; poll_queue++) { + req_mgr_h->q_free_slots = + cc_ioread(drvdata, CC_REG(DSCRPTR_QUEUE_CONTENT)); + if (req_mgr_h->q_free_slots < req_mgr_h->min_free_hw_slots) + req_mgr_h->min_free_hw_slots = req_mgr_h->q_free_slots; + + if (req_mgr_h->q_free_slots >= total_seq_len) { + /* If there is enough place return */ + return 0; + } + + dev_dbg(dev, "HW FIFO is full. q_free_slots=%d total_seq_len=%d\n", + req_mgr_h->q_free_slots, total_seq_len); + } + /* No room in the HW queue try again later */ + dev_dbg(dev, "HW FIFO full, timeout. req_queue_head=%d sw_fifo_len=%d q_free_slots=%d total_seq_len=%d\n", + req_mgr_h->req_queue_head, MAX_REQUEST_QUEUE_SIZE, + req_mgr_h->q_free_slots, total_seq_len); + return -ENOSPC; +} + +/*! + * Enqueue caller request to crypto hardware. + * Need to be called with HW lock held and PM running + * + * \param drvdata + * \param cc_req The request to enqueue + * \param desc The crypto sequence + * \param len The crypto sequence length + * \param add_comp If "true": add an artificial dout DMA to mark completion + * + * \return int Returns -EINPROGRESS or error code + */ +static int cc_do_send_request(struct cc_drvdata *drvdata, + struct cc_crypto_req *cc_req, + struct cc_hw_desc *desc, unsigned int len, + bool add_comp, bool ivgen) +{ + struct cc_req_mgr_handle *req_mgr_h = drvdata->request_mgr_handle; + unsigned int used_sw_slots; + unsigned int iv_seq_len = 0; + unsigned int total_seq_len = len; /*initial sequence length*/ + struct cc_hw_desc iv_seq[CC_IVPOOL_SEQ_LEN]; + struct device *dev = drvdata_to_dev(drvdata); + int rc; + + if (ivgen) { + dev_dbg(dev, "Acquire IV from pool into %d DMA addresses %pad, %pad, %pad, IV-size=%u\n", + cc_req->ivgen_dma_addr_len, + &cc_req->ivgen_dma_addr[0], + &cc_req->ivgen_dma_addr[1], + &cc_req->ivgen_dma_addr[2], + cc_req->ivgen_size); + + /* Acquire IV from pool */ + rc = cc_get_iv(drvdata, cc_req->ivgen_dma_addr, + cc_req->ivgen_dma_addr_len, + cc_req->ivgen_size, iv_seq, &iv_seq_len); + + if (rc) { + dev_err(dev, "Failed to generate IV (rc=%d)\n", rc); + return rc; + } + + total_seq_len += iv_seq_len; + } + + used_sw_slots = ((req_mgr_h->req_queue_head - + req_mgr_h->req_queue_tail) & + (MAX_REQUEST_QUEUE_SIZE - 1)); + if (used_sw_slots > req_mgr_h->max_used_sw_slots) + req_mgr_h->max_used_sw_slots = used_sw_slots; + + /* Enqueue request - must be locked with HW lock*/ + req_mgr_h->req_queue[req_mgr_h->req_queue_head] = *cc_req; + req_mgr_h->req_queue_head = (req_mgr_h->req_queue_head + 1) & + (MAX_REQUEST_QUEUE_SIZE - 1); + /* TODO: Use circ_buf.h ? */ + + dev_dbg(dev, "Enqueue request head=%u\n", req_mgr_h->req_queue_head); + + /* + * We are about to push command to the HW via the command registers + * that may refernece hsot memory. We need to issue a memory barrier + * to make sure there are no outstnading memory writes + */ + wmb(); + + /* STAT_PHASE_4: Push sequence */ + if (ivgen) + enqueue_seq(drvdata, iv_seq, iv_seq_len); + + enqueue_seq(drvdata, desc, len); + + if (add_comp) { + enqueue_seq(drvdata, &req_mgr_h->compl_desc, 1); + total_seq_len++; + } + + if (req_mgr_h->q_free_slots < total_seq_len) { + /* This situation should never occur. Maybe indicating problem + * with resuming power. Set the free slot count to 0 and hope + * for the best. + */ + dev_err(dev, "HW free slot count mismatch."); + req_mgr_h->q_free_slots = 0; + } else { + /* Update the free slots in HW queue */ + req_mgr_h->q_free_slots -= total_seq_len; + } + + /* Operation still in process */ + return -EINPROGRESS; +} + +static void cc_enqueue_backlog(struct cc_drvdata *drvdata, + struct cc_bl_item *bli) +{ + struct cc_req_mgr_handle *mgr = drvdata->request_mgr_handle; + + spin_lock_bh(&mgr->bl_lock); + list_add_tail(&bli->list, &mgr->backlog); + ++mgr->bl_len; + spin_unlock_bh(&mgr->bl_lock); + tasklet_schedule(&mgr->comptask); +} + +static void cc_proc_backlog(struct cc_drvdata *drvdata) +{ + struct cc_req_mgr_handle *mgr = drvdata->request_mgr_handle; + struct cc_bl_item *bli; + struct cc_crypto_req *creq; + struct crypto_async_request *req; + bool ivgen; + unsigned int total_len; + struct device *dev = drvdata_to_dev(drvdata); + int rc; + + spin_lock(&mgr->bl_lock); + + while (mgr->bl_len) { + bli = list_first_entry(&mgr->backlog, struct cc_bl_item, list); + spin_unlock(&mgr->bl_lock); + + creq = &bli->creq; + req = (struct crypto_async_request *)creq->user_arg; + + /* + * Notify the request we're moving out of the backlog + * but only if we haven't done so already. + */ + if (!bli->notif) { + req->complete(req, -EINPROGRESS); + bli->notif = true; + } + + ivgen = !!creq->ivgen_dma_addr_len; + total_len = bli->len + (ivgen ? CC_IVPOOL_SEQ_LEN : 0); + + spin_lock(&mgr->hw_lock); + + rc = cc_queues_status(drvdata, mgr, total_len); + if (rc) { + /* + * There is still not room in the FIFO for + * this request. Bail out. We'll return here + * on the next completion irq. + */ + spin_unlock(&mgr->hw_lock); + return; + } + + rc = cc_do_send_request(drvdata, &bli->creq, bli->desc, + bli->len, false, ivgen); + + spin_unlock(&mgr->hw_lock); + + if (rc != -EINPROGRESS) { + cc_pm_put_suspend(dev); + creq->user_cb(dev, req, rc); + } + + /* Remove ourselves from the backlog list */ + spin_lock(&mgr->bl_lock); + list_del(&bli->list); + --mgr->bl_len; + } + + spin_unlock(&mgr->bl_lock); +} + +int cc_send_request(struct cc_drvdata *drvdata, struct cc_crypto_req *cc_req, + struct cc_hw_desc *desc, unsigned int len, + struct crypto_async_request *req) +{ + int rc; + struct cc_req_mgr_handle *mgr = drvdata->request_mgr_handle; + bool ivgen = !!cc_req->ivgen_dma_addr_len; + unsigned int total_len = len + (ivgen ? CC_IVPOOL_SEQ_LEN : 0); + struct device *dev = drvdata_to_dev(drvdata); + bool backlog_ok = req->flags & CRYPTO_TFM_REQ_MAY_BACKLOG; + gfp_t flags = cc_gfp_flags(req); + struct cc_bl_item *bli; + + rc = cc_pm_get(dev); + if (rc) { + dev_err(dev, "ssi_power_mgr_runtime_get returned %x\n", rc); + return rc; + } + + spin_lock_bh(&mgr->hw_lock); + rc = cc_queues_status(drvdata, mgr, total_len); + +#ifdef CC_DEBUG_FORCE_BACKLOG + if (backlog_ok) + rc = -ENOSPC; +#endif /* CC_DEBUG_FORCE_BACKLOG */ + + if (rc == -ENOSPC && backlog_ok) { + spin_unlock_bh(&mgr->hw_lock); + + bli = kmalloc(sizeof(*bli), flags); + if (!bli) { + cc_pm_put_suspend(dev); + return -ENOMEM; + } + + memcpy(&bli->creq, cc_req, sizeof(*cc_req)); + memcpy(&bli->desc, desc, len * sizeof(*desc)); + bli->len = len; + bli->notif = false; + cc_enqueue_backlog(drvdata, bli); + return -EBUSY; + } + + if (!rc) + rc = cc_do_send_request(drvdata, cc_req, desc, len, false, + ivgen); + + spin_unlock_bh(&mgr->hw_lock); + return rc; +} + +int cc_send_sync_request(struct cc_drvdata *drvdata, + struct cc_crypto_req *cc_req, struct cc_hw_desc *desc, + unsigned int len) +{ + int rc; + struct device *dev = drvdata_to_dev(drvdata); + struct cc_req_mgr_handle *mgr = drvdata->request_mgr_handle; + + init_completion(&cc_req->seq_compl); + cc_req->user_cb = request_mgr_complete; + cc_req->user_arg = &cc_req->seq_compl; + + rc = cc_pm_get(dev); + if (rc) { + dev_err(dev, "ssi_power_mgr_runtime_get returned %x\n", rc); + return rc; + } + + while (true) { + spin_lock_bh(&mgr->hw_lock); + rc = cc_queues_status(drvdata, mgr, len + 1); + + if (!rc) + break; + + spin_unlock_bh(&mgr->hw_lock); + if (rc != -EAGAIN) { + cc_pm_put_suspend(dev); + return rc; + } + wait_for_completion_interruptible(&drvdata->hw_queue_avail); + reinit_completion(&drvdata->hw_queue_avail); + } + + rc = cc_do_send_request(drvdata, cc_req, desc, len, true, false); + spin_unlock_bh(&mgr->hw_lock); + + if (rc != -EINPROGRESS) { + cc_pm_put_suspend(dev); + return rc; + } + + wait_for_completion(&cc_req->seq_compl); + return 0; +} + +/*! + * Enqueue caller request to crypto hardware during init process. + * assume this function is not called in middle of a flow, + * since we set QUEUE_LAST_IND flag in the last descriptor. + * + * \param drvdata + * \param desc The crypto sequence + * \param len The crypto sequence length + * + * \return int Returns "0" upon success + */ +int send_request_init(struct cc_drvdata *drvdata, struct cc_hw_desc *desc, + unsigned int len) +{ + struct cc_req_mgr_handle *req_mgr_h = drvdata->request_mgr_handle; + unsigned int total_seq_len = len; /*initial sequence length*/ + int rc = 0; + + /* Wait for space in HW and SW FIFO. Poll for as much as FIFO_TIMEOUT. + */ + rc = cc_queues_status(drvdata, req_mgr_h, total_seq_len); + if (rc) + return rc; + + set_queue_last_ind(&desc[(len - 1)]); + + /* + * We are about to push command to the HW via the command registers + * that may refernece hsot memory. We need to issue a memory barrier + * to make sure there are no outstnading memory writes + */ + wmb(); + enqueue_seq(drvdata, desc, len); + + /* Update the free slots in HW queue */ + req_mgr_h->q_free_slots = + cc_ioread(drvdata, CC_REG(DSCRPTR_QUEUE_CONTENT)); + + return 0; +} + +void complete_request(struct cc_drvdata *drvdata) +{ + struct cc_req_mgr_handle *request_mgr_handle = + drvdata->request_mgr_handle; + + complete(&drvdata->hw_queue_avail); +#ifdef COMP_IN_WQ + queue_delayed_work(request_mgr_handle->workq, + &request_mgr_handle->compwork, 0); +#else + tasklet_schedule(&request_mgr_handle->comptask); +#endif +} + +#ifdef COMP_IN_WQ +static void comp_work_handler(struct work_struct *work) +{ + struct cc_drvdata *drvdata = + container_of(work, struct cc_drvdata, compwork.work); + + comp_handler((unsigned long)drvdata); +} +#endif + +static void proc_completions(struct cc_drvdata *drvdata) +{ + struct cc_crypto_req *cc_req; + struct device *dev = drvdata_to_dev(drvdata); + struct cc_req_mgr_handle *request_mgr_handle = + drvdata->request_mgr_handle; + unsigned int *tail = &request_mgr_handle->req_queue_tail; + unsigned int *head = &request_mgr_handle->req_queue_head; + + while (request_mgr_handle->axi_completed) { + request_mgr_handle->axi_completed--; + + /* Dequeue request */ + if (*head == *tail) { + /* We are supposed to handle a completion but our + * queue is empty. This is not normal. Return and + * hope for the best. + */ + dev_err(dev, "Request queue is empty head == tail %u\n", + *head); + break; + } + + cc_req = &request_mgr_handle->req_queue[*tail]; + + if (cc_req->user_cb) + cc_req->user_cb(dev, cc_req->user_arg, 0); + *tail = (*tail + 1) & (MAX_REQUEST_QUEUE_SIZE - 1); + dev_dbg(dev, "Dequeue request tail=%u\n", *tail); + dev_dbg(dev, "Request completed. axi_completed=%d\n", + request_mgr_handle->axi_completed); + cc_pm_put_suspend(dev); + } +} + +static inline u32 cc_axi_comp_count(struct cc_drvdata *drvdata) +{ + return FIELD_GET(AXIM_MON_COMP_VALUE, + cc_ioread(drvdata, CC_REG(AXIM_MON_COMP))); +} + +/* Deferred service handler, run as interrupt-fired tasklet */ +static void comp_handler(unsigned long devarg) +{ + struct cc_drvdata *drvdata = (struct cc_drvdata *)devarg; + struct cc_req_mgr_handle *request_mgr_handle = + drvdata->request_mgr_handle; + + u32 irq; + + irq = (drvdata->irq & CC_COMP_IRQ_MASK); + + if (irq & CC_COMP_IRQ_MASK) { + /* To avoid the interrupt from firing as we unmask it, + * we clear it now + */ + cc_iowrite(drvdata, CC_REG(HOST_ICR), CC_COMP_IRQ_MASK); + + /* Avoid race with above clear: Test completion counter + * once more + */ + request_mgr_handle->axi_completed += + cc_axi_comp_count(drvdata); + + while (request_mgr_handle->axi_completed) { + do { + proc_completions(drvdata); + /* At this point (after proc_completions()), + * request_mgr_handle->axi_completed is 0. + */ + request_mgr_handle->axi_completed = + cc_axi_comp_count(drvdata); + } while (request_mgr_handle->axi_completed > 0); + + cc_iowrite(drvdata, CC_REG(HOST_ICR), + CC_COMP_IRQ_MASK); + + request_mgr_handle->axi_completed += + cc_axi_comp_count(drvdata); + } + } + /* after verifing that there is nothing to do, + * unmask AXI completion interrupt + */ + cc_iowrite(drvdata, CC_REG(HOST_IMR), + cc_ioread(drvdata, CC_REG(HOST_IMR)) & ~irq); + + cc_proc_backlog(drvdata); +} + +/* + * resume the queue configuration - no need to take the lock as this happens + * inside the spin lock protection + */ +#if defined(CONFIG_PM) +int cc_resume_req_queue(struct cc_drvdata *drvdata) +{ + struct cc_req_mgr_handle *request_mgr_handle = + drvdata->request_mgr_handle; + + spin_lock_bh(&request_mgr_handle->hw_lock); + request_mgr_handle->is_runtime_suspended = false; + spin_unlock_bh(&request_mgr_handle->hw_lock); + + return 0; +} + +/* + * suspend the queue configuration. Since it is used for the runtime suspend + * only verify that the queue can be suspended. + */ +int cc_suspend_req_queue(struct cc_drvdata *drvdata) +{ + struct cc_req_mgr_handle *request_mgr_handle = + drvdata->request_mgr_handle; + + /* lock the send_request */ + spin_lock_bh(&request_mgr_handle->hw_lock); + if (request_mgr_handle->req_queue_head != + request_mgr_handle->req_queue_tail) { + spin_unlock_bh(&request_mgr_handle->hw_lock); + return -EBUSY; + } + request_mgr_handle->is_runtime_suspended = true; + spin_unlock_bh(&request_mgr_handle->hw_lock); + + return 0; +} + +bool cc_req_queue_suspended(struct cc_drvdata *drvdata) +{ + struct cc_req_mgr_handle *request_mgr_handle = + drvdata->request_mgr_handle; + + return request_mgr_handle->is_runtime_suspended; +} + +#endif + diff --git a/drivers/staging/ccree/cc_request_mgr.h b/drivers/staging/ccree/cc_request_mgr.h new file mode 100644 index 000000000000..573cb97af085 --- /dev/null +++ b/drivers/staging/ccree/cc_request_mgr.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ + +/* \file cc_request_mgr.h + * Request Manager + */ + +#ifndef __REQUEST_MGR_H__ +#define __REQUEST_MGR_H__ + +#include "cc_hw_queue_defs.h" + +int cc_req_mgr_init(struct cc_drvdata *drvdata); + +/*! + * Enqueue caller request to crypto hardware. + * + * \param drvdata + * \param cc_req The request to enqueue + * \param desc The crypto sequence + * \param len The crypto sequence length + * \param is_dout If "true": completion is handled by the caller + * If "false": this function adds a dummy descriptor completion + * and waits upon completion signal. + * + * \return int Returns -EINPROGRESS or error + */ +int cc_send_request(struct cc_drvdata *drvdata, struct cc_crypto_req *cc_req, + struct cc_hw_desc *desc, unsigned int len, + struct crypto_async_request *req); + +int cc_send_sync_request(struct cc_drvdata *drvdata, + struct cc_crypto_req *cc_req, struct cc_hw_desc *desc, + unsigned int len); + +int send_request_init(struct cc_drvdata *drvdata, struct cc_hw_desc *desc, + unsigned int len); + +void complete_request(struct cc_drvdata *drvdata); + +void cc_req_mgr_fini(struct cc_drvdata *drvdata); + +#if defined(CONFIG_PM) +int cc_resume_req_queue(struct cc_drvdata *drvdata); + +int cc_suspend_req_queue(struct cc_drvdata *drvdata); + +bool cc_req_queue_suspended(struct cc_drvdata *drvdata); +#endif + +#endif /*__REQUEST_MGR_H__*/ diff --git a/drivers/staging/ccree/ssi_sram_mgr.c b/drivers/staging/ccree/cc_sram_mgr.c index 07260d168c91..d1f8a9cc1c0f 100644 --- a/drivers/staging/ccree/ssi_sram_mgr.c +++ b/drivers/staging/ccree/cc_sram_mgr.c @@ -1,62 +1,47 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ -#include "ssi_driver.h" -#include "ssi_sram_mgr.h" +#include "cc_driver.h" +#include "cc_sram_mgr.h" /** - * struct ssi_sram_mgr_ctx -Internal RAM context manager + * struct cc_sram_ctx -Internal RAM context manager * @sram_free_offset: the offset to the non-allocated area */ -struct ssi_sram_mgr_ctx { - ssi_sram_addr_t sram_free_offset; +struct cc_sram_ctx { + cc_sram_addr_t sram_free_offset; }; /** - * ssi_sram_mgr_fini() - Cleanup SRAM pool. + * cc_sram_mgr_fini() - Cleanup SRAM pool. * * @drvdata: Associated device driver context */ -void ssi_sram_mgr_fini(struct ssi_drvdata *drvdata) +void cc_sram_mgr_fini(struct cc_drvdata *drvdata) { - struct ssi_sram_mgr_ctx *smgr_ctx = drvdata->sram_mgr_handle; - /* Free "this" context */ - if (smgr_ctx) { - memset(smgr_ctx, 0, sizeof(struct ssi_sram_mgr_ctx)); - kfree(smgr_ctx); - } + kfree(drvdata->sram_mgr_handle); } /** - * ssi_sram_mgr_init() - Initializes SRAM pool. + * cc_sram_mgr_init() - Initializes SRAM pool. * The pool starts right at the beginning of SRAM. * Returns zero for success, negative value otherwise. * * @drvdata: Associated device driver context */ -int ssi_sram_mgr_init(struct ssi_drvdata *drvdata) +int cc_sram_mgr_init(struct cc_drvdata *drvdata) { + struct cc_sram_ctx *ctx; + /* Allocate "this" context */ - drvdata->sram_mgr_handle = kzalloc(sizeof(struct ssi_sram_mgr_ctx), - GFP_KERNEL); + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); - if (!drvdata->sram_mgr_handle) + if (!ctx) return -ENOMEM; + drvdata->sram_mgr_handle = ctx; + return 0; } @@ -69,18 +54,18 @@ int ssi_sram_mgr_init(struct ssi_drvdata *drvdata) * \param drvdata * \param size The requested bytes to allocate */ -ssi_sram_addr_t ssi_sram_mgr_alloc(struct ssi_drvdata *drvdata, u32 size) +cc_sram_addr_t cc_sram_alloc(struct cc_drvdata *drvdata, u32 size) { - struct ssi_sram_mgr_ctx *smgr_ctx = drvdata->sram_mgr_handle; + struct cc_sram_ctx *smgr_ctx = drvdata->sram_mgr_handle; struct device *dev = drvdata_to_dev(drvdata); - ssi_sram_addr_t p; + cc_sram_addr_t p; - if (unlikely((size & 0x3) != 0)) { + if ((size & 0x3)) { dev_err(dev, "Requested buffer size (%u) is not multiple of 4", size); return NULL_SRAM_ADDR; } - if (unlikely(size > (SSI_CC_SRAM_SIZE - smgr_ctx->sram_free_offset))) { + if (size > (CC_CC_SRAM_SIZE - smgr_ctx->sram_free_offset)) { dev_err(dev, "Not enough space to allocate %u B (at offset %llu)\n", size, smgr_ctx->sram_free_offset); return NULL_SRAM_ADDR; @@ -93,7 +78,7 @@ ssi_sram_addr_t ssi_sram_mgr_alloc(struct ssi_drvdata *drvdata, u32 size) } /** - * ssi_sram_mgr_const2sram_desc() - Create const descriptors sequence to + * cc_set_sram_desc() - Create const descriptors sequence to * set values in given array into SRAM. * Note: each const value can't exceed word size. * @@ -103,10 +88,9 @@ ssi_sram_addr_t ssi_sram_mgr_alloc(struct ssi_drvdata *drvdata, u32 size) * @seq: A pointer to the given IN/OUT descriptor sequence * @seq_len: A pointer to the given IN/OUT sequence length */ -void ssi_sram_mgr_const2sram_desc( - const u32 *src, ssi_sram_addr_t dst, - unsigned int nelement, - struct cc_hw_desc *seq, unsigned int *seq_len) +void cc_set_sram_desc(const u32 *src, cc_sram_addr_t dst, + unsigned int nelement, struct cc_hw_desc *seq, + unsigned int *seq_len) { u32 i; unsigned int idx = *seq_len; diff --git a/drivers/staging/ccree/cc_sram_mgr.h b/drivers/staging/ccree/cc_sram_mgr.h new file mode 100644 index 000000000000..d48649fb3323 --- /dev/null +++ b/drivers/staging/ccree/cc_sram_mgr.h @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2012-2018 ARM Limited or its affiliates. */ + +#ifndef __CC_SRAM_MGR_H__ +#define __CC_SRAM_MGR_H__ + +#ifndef CC_CC_SRAM_SIZE +#define CC_CC_SRAM_SIZE 4096 +#endif + +struct cc_drvdata; + +/** + * Address (offset) within CC internal SRAM + */ + +typedef u64 cc_sram_addr_t; + +#define NULL_SRAM_ADDR ((cc_sram_addr_t)-1) + +/*! + * Initializes SRAM pool. + * The first X bytes of SRAM are reserved for ROM usage, hence, pool + * starts right after X bytes. + * + * \param drvdata + * + * \return int Zero for success, negative value otherwise. + */ +int cc_sram_mgr_init(struct cc_drvdata *drvdata); + +/*! + * Uninits SRAM pool. + * + * \param drvdata + */ +void cc_sram_mgr_fini(struct cc_drvdata *drvdata); + +/*! + * Allocated buffer from SRAM pool. + * Note: Caller is responsible to free the LAST allocated buffer. + * This function does not taking care of any fragmentation may occur + * by the order of calls to alloc/free. + * + * \param drvdata + * \param size The requested bytes to allocate + */ +cc_sram_addr_t cc_sram_alloc(struct cc_drvdata *drvdata, u32 size); + +/** + * cc_set_sram_desc() - Create const descriptors sequence to + * set values in given array into SRAM. + * Note: each const value can't exceed word size. + * + * @src: A pointer to array of words to set as consts. + * @dst: The target SRAM buffer to set into + * @nelements: The number of words in "src" array + * @seq: A pointer to the given IN/OUT descriptor sequence + * @seq_len: A pointer to the given IN/OUT sequence length + */ +void cc_set_sram_desc(const u32 *src, cc_sram_addr_t dst, + unsigned int nelement, struct cc_hw_desc *seq, + unsigned int *seq_len); + +#endif /*__CC_SRAM_MGR_H__*/ diff --git a/drivers/staging/ccree/dx_crys_kernel.h b/drivers/staging/ccree/dx_crys_kernel.h deleted file mode 100644 index 219603030344..000000000000 --- a/drivers/staging/ccree/dx_crys_kernel.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef __DX_CRYS_KERNEL_H__ -#define __DX_CRYS_KERNEL_H__ - -// -------------------------------------- -// BLOCK: DSCRPTR -// -------------------------------------- -#define DX_DSCRPTR_COMPLETION_COUNTER_REG_OFFSET 0xE00UL -#define DX_DSCRPTR_COMPLETION_COUNTER_COMPLETION_COUNTER_BIT_SHIFT 0x0UL -#define DX_DSCRPTR_COMPLETION_COUNTER_COMPLETION_COUNTER_BIT_SIZE 0x6UL -#define DX_DSCRPTR_COMPLETION_COUNTER_OVERFLOW_COUNTER_BIT_SHIFT 0x6UL -#define DX_DSCRPTR_COMPLETION_COUNTER_OVERFLOW_COUNTER_BIT_SIZE 0x1UL -#define DX_DSCRPTR_SW_RESET_REG_OFFSET 0xE40UL -#define DX_DSCRPTR_SW_RESET_VALUE_BIT_SHIFT 0x0UL -#define DX_DSCRPTR_SW_RESET_VALUE_BIT_SIZE 0x1UL -#define DX_DSCRPTR_QUEUE_SRAM_SIZE_REG_OFFSET 0xE60UL -#define DX_DSCRPTR_QUEUE_SRAM_SIZE_NUM_OF_DSCRPTR_BIT_SHIFT 0x0UL -#define DX_DSCRPTR_QUEUE_SRAM_SIZE_NUM_OF_DSCRPTR_BIT_SIZE 0xAUL -#define DX_DSCRPTR_QUEUE_SRAM_SIZE_DSCRPTR_SRAM_SIZE_BIT_SHIFT 0xAUL -#define DX_DSCRPTR_QUEUE_SRAM_SIZE_DSCRPTR_SRAM_SIZE_BIT_SIZE 0xCUL -#define DX_DSCRPTR_QUEUE_SRAM_SIZE_SRAM_SIZE_BIT_SHIFT 0x16UL -#define DX_DSCRPTR_QUEUE_SRAM_SIZE_SRAM_SIZE_BIT_SIZE 0x3UL -#define DX_DSCRPTR_SINGLE_ADDR_EN_REG_OFFSET 0xE64UL -#define DX_DSCRPTR_SINGLE_ADDR_EN_VALUE_BIT_SHIFT 0x0UL -#define DX_DSCRPTR_SINGLE_ADDR_EN_VALUE_BIT_SIZE 0x1UL -#define DX_DSCRPTR_MEASURE_CNTR_REG_OFFSET 0xE68UL -#define DX_DSCRPTR_MEASURE_CNTR_VALUE_BIT_SHIFT 0x0UL -#define DX_DSCRPTR_MEASURE_CNTR_VALUE_BIT_SIZE 0x20UL -#define DX_DSCRPTR_QUEUE_WORD0_REG_OFFSET 0xE80UL -#define DX_DSCRPTR_QUEUE_WORD0_VALUE_BIT_SHIFT 0x0UL -#define DX_DSCRPTR_QUEUE_WORD0_VALUE_BIT_SIZE 0x20UL -#define DX_DSCRPTR_QUEUE_WORD1_REG_OFFSET 0xE84UL -#define DX_DSCRPTR_QUEUE_WORD1_DIN_DMA_MODE_BIT_SHIFT 0x0UL -#define DX_DSCRPTR_QUEUE_WORD1_DIN_DMA_MODE_BIT_SIZE 0x2UL -#define DX_DSCRPTR_QUEUE_WORD1_DIN_SIZE_BIT_SHIFT 0x2UL -#define DX_DSCRPTR_QUEUE_WORD1_DIN_SIZE_BIT_SIZE 0x18UL -#define DX_DSCRPTR_QUEUE_WORD1_NS_BIT_BIT_SHIFT 0x1AUL -#define DX_DSCRPTR_QUEUE_WORD1_NS_BIT_BIT_SIZE 0x1UL -#define DX_DSCRPTR_QUEUE_WORD1_DIN_CONST_VALUE_BIT_SHIFT 0x1BUL -#define DX_DSCRPTR_QUEUE_WORD1_DIN_CONST_VALUE_BIT_SIZE 0x1UL -#define DX_DSCRPTR_QUEUE_WORD1_NOT_LAST_BIT_SHIFT 0x1CUL -#define DX_DSCRPTR_QUEUE_WORD1_NOT_LAST_BIT_SIZE 0x1UL -#define DX_DSCRPTR_QUEUE_WORD1_LOCK_QUEUE_BIT_SHIFT 0x1DUL -#define DX_DSCRPTR_QUEUE_WORD1_LOCK_QUEUE_BIT_SIZE 0x1UL -#define DX_DSCRPTR_QUEUE_WORD1_NOT_USED_BIT_SHIFT 0x1EUL -#define DX_DSCRPTR_QUEUE_WORD1_NOT_USED_BIT_SIZE 0x2UL -#define DX_DSCRPTR_QUEUE_WORD2_REG_OFFSET 0xE88UL -#define DX_DSCRPTR_QUEUE_WORD2_VALUE_BIT_SHIFT 0x0UL -#define DX_DSCRPTR_QUEUE_WORD2_VALUE_BIT_SIZE 0x20UL -#define DX_DSCRPTR_QUEUE_WORD3_REG_OFFSET 0xE8CUL -#define DX_DSCRPTR_QUEUE_WORD3_DOUT_DMA_MODE_BIT_SHIFT 0x0UL -#define DX_DSCRPTR_QUEUE_WORD3_DOUT_DMA_MODE_BIT_SIZE 0x2UL -#define DX_DSCRPTR_QUEUE_WORD3_DOUT_SIZE_BIT_SHIFT 0x2UL -#define DX_DSCRPTR_QUEUE_WORD3_DOUT_SIZE_BIT_SIZE 0x18UL -#define DX_DSCRPTR_QUEUE_WORD3_NS_BIT_BIT_SHIFT 0x1AUL -#define DX_DSCRPTR_QUEUE_WORD3_NS_BIT_BIT_SIZE 0x1UL -#define DX_DSCRPTR_QUEUE_WORD3_DOUT_LAST_IND_BIT_SHIFT 0x1BUL -#define DX_DSCRPTR_QUEUE_WORD3_DOUT_LAST_IND_BIT_SIZE 0x1UL -#define DX_DSCRPTR_QUEUE_WORD3_HASH_XOR_BIT_BIT_SHIFT 0x1DUL -#define DX_DSCRPTR_QUEUE_WORD3_HASH_XOR_BIT_BIT_SIZE 0x1UL -#define DX_DSCRPTR_QUEUE_WORD3_NOT_USED_BIT_SHIFT 0x1EUL -#define DX_DSCRPTR_QUEUE_WORD3_NOT_USED_BIT_SIZE 0x1UL -#define DX_DSCRPTR_QUEUE_WORD3_QUEUE_LAST_IND_BIT_SHIFT 0x1FUL -#define DX_DSCRPTR_QUEUE_WORD3_QUEUE_LAST_IND_BIT_SIZE 0x1UL -#define DX_DSCRPTR_QUEUE_WORD4_REG_OFFSET 0xE90UL -#define DX_DSCRPTR_QUEUE_WORD4_DATA_FLOW_MODE_BIT_SHIFT 0x0UL -#define DX_DSCRPTR_QUEUE_WORD4_DATA_FLOW_MODE_BIT_SIZE 0x6UL -#define DX_DSCRPTR_QUEUE_WORD4_AES_SEL_N_HASH_BIT_SHIFT 0x6UL -#define DX_DSCRPTR_QUEUE_WORD4_AES_SEL_N_HASH_BIT_SIZE 0x1UL -#define DX_DSCRPTR_QUEUE_WORD4_AES_XOR_CRYPTO_KEY_BIT_SHIFT 0x7UL -#define DX_DSCRPTR_QUEUE_WORD4_AES_XOR_CRYPTO_KEY_BIT_SIZE 0x1UL -#define DX_DSCRPTR_QUEUE_WORD4_ACK_NEEDED_BIT_SHIFT 0x8UL -#define DX_DSCRPTR_QUEUE_WORD4_ACK_NEEDED_BIT_SIZE 0x2UL -#define DX_DSCRPTR_QUEUE_WORD4_CIPHER_MODE_BIT_SHIFT 0xAUL -#define DX_DSCRPTR_QUEUE_WORD4_CIPHER_MODE_BIT_SIZE 0x4UL -#define DX_DSCRPTR_QUEUE_WORD4_CMAC_SIZE0_BIT_SHIFT 0xEUL -#define DX_DSCRPTR_QUEUE_WORD4_CMAC_SIZE0_BIT_SIZE 0x1UL -#define DX_DSCRPTR_QUEUE_WORD4_CIPHER_DO_BIT_SHIFT 0xFUL -#define DX_DSCRPTR_QUEUE_WORD4_CIPHER_DO_BIT_SIZE 0x2UL -#define DX_DSCRPTR_QUEUE_WORD4_CIPHER_CONF0_BIT_SHIFT 0x11UL -#define DX_DSCRPTR_QUEUE_WORD4_CIPHER_CONF0_BIT_SIZE 0x2UL -#define DX_DSCRPTR_QUEUE_WORD4_CIPHER_CONF1_BIT_SHIFT 0x13UL -#define DX_DSCRPTR_QUEUE_WORD4_CIPHER_CONF1_BIT_SIZE 0x1UL -#define DX_DSCRPTR_QUEUE_WORD4_CIPHER_CONF2_BIT_SHIFT 0x14UL -#define DX_DSCRPTR_QUEUE_WORD4_CIPHER_CONF2_BIT_SIZE 0x2UL -#define DX_DSCRPTR_QUEUE_WORD4_KEY_SIZE_BIT_SHIFT 0x16UL -#define DX_DSCRPTR_QUEUE_WORD4_KEY_SIZE_BIT_SIZE 0x2UL -#define DX_DSCRPTR_QUEUE_WORD4_SETUP_OPERATION_BIT_SHIFT 0x18UL -#define DX_DSCRPTR_QUEUE_WORD4_SETUP_OPERATION_BIT_SIZE 0x4UL -#define DX_DSCRPTR_QUEUE_WORD4_DIN_SRAM_ENDIANNESS_BIT_SHIFT 0x1CUL -#define DX_DSCRPTR_QUEUE_WORD4_DIN_SRAM_ENDIANNESS_BIT_SIZE 0x1UL -#define DX_DSCRPTR_QUEUE_WORD4_DOUT_SRAM_ENDIANNESS_BIT_SHIFT 0x1DUL -#define DX_DSCRPTR_QUEUE_WORD4_DOUT_SRAM_ENDIANNESS_BIT_SIZE 0x1UL -#define DX_DSCRPTR_QUEUE_WORD4_WORD_SWAP_BIT_SHIFT 0x1EUL -#define DX_DSCRPTR_QUEUE_WORD4_WORD_SWAP_BIT_SIZE 0x1UL -#define DX_DSCRPTR_QUEUE_WORD4_BYTES_SWAP_BIT_SHIFT 0x1FUL -#define DX_DSCRPTR_QUEUE_WORD4_BYTES_SWAP_BIT_SIZE 0x1UL -#define DX_DSCRPTR_QUEUE_WORD5_REG_OFFSET 0xE94UL -#define DX_DSCRPTR_QUEUE_WORD5_DIN_ADDR_HIGH_BIT_SHIFT 0x0UL -#define DX_DSCRPTR_QUEUE_WORD5_DIN_ADDR_HIGH_BIT_SIZE 0x10UL -#define DX_DSCRPTR_QUEUE_WORD5_DOUT_ADDR_HIGH_BIT_SHIFT 0x10UL -#define DX_DSCRPTR_QUEUE_WORD5_DOUT_ADDR_HIGH_BIT_SIZE 0x10UL -#define DX_DSCRPTR_QUEUE_WATERMARK_REG_OFFSET 0xE98UL -#define DX_DSCRPTR_QUEUE_WATERMARK_VALUE_BIT_SHIFT 0x0UL -#define DX_DSCRPTR_QUEUE_WATERMARK_VALUE_BIT_SIZE 0xAUL -#define DX_DSCRPTR_QUEUE_CONTENT_REG_OFFSET 0xE9CUL -#define DX_DSCRPTR_QUEUE_CONTENT_VALUE_BIT_SHIFT 0x0UL -#define DX_DSCRPTR_QUEUE_CONTENT_VALUE_BIT_SIZE 0xAUL -// -------------------------------------- -// BLOCK: AXI_P -// -------------------------------------- -#define DX_AXIM_MON_INFLIGHT_REG_OFFSET 0xB00UL -#define DX_AXIM_MON_INFLIGHT_VALUE_BIT_SHIFT 0x0UL -#define DX_AXIM_MON_INFLIGHT_VALUE_BIT_SIZE 0x8UL -#define DX_AXIM_MON_INFLIGHTLAST_REG_OFFSET 0xB40UL -#define DX_AXIM_MON_INFLIGHTLAST_VALUE_BIT_SHIFT 0x0UL -#define DX_AXIM_MON_INFLIGHTLAST_VALUE_BIT_SIZE 0x8UL -#define DX_AXIM_MON_COMP_REG_OFFSET 0xB80UL -#define DX_AXIM_MON_COMP_VALUE_BIT_SHIFT 0x0UL -#define DX_AXIM_MON_COMP_VALUE_BIT_SIZE 0x10UL -#define DX_AXIM_MON_ERR_REG_OFFSET 0xBC4UL -#define DX_AXIM_MON_ERR_BRESP_BIT_SHIFT 0x0UL -#define DX_AXIM_MON_ERR_BRESP_BIT_SIZE 0x2UL -#define DX_AXIM_MON_ERR_BID_BIT_SHIFT 0x2UL -#define DX_AXIM_MON_ERR_BID_BIT_SIZE 0x4UL -#define DX_AXIM_MON_ERR_RRESP_BIT_SHIFT 0x10UL -#define DX_AXIM_MON_ERR_RRESP_BIT_SIZE 0x2UL -#define DX_AXIM_MON_ERR_RID_BIT_SHIFT 0x12UL -#define DX_AXIM_MON_ERR_RID_BIT_SIZE 0x4UL -#define DX_AXIM_CFG_REG_OFFSET 0xBE8UL -#define DX_AXIM_CFG_BRESPMASK_BIT_SHIFT 0x4UL -#define DX_AXIM_CFG_BRESPMASK_BIT_SIZE 0x1UL -#define DX_AXIM_CFG_RRESPMASK_BIT_SHIFT 0x5UL -#define DX_AXIM_CFG_RRESPMASK_BIT_SIZE 0x1UL -#define DX_AXIM_CFG_INFLTMASK_BIT_SHIFT 0x6UL -#define DX_AXIM_CFG_INFLTMASK_BIT_SIZE 0x1UL -#define DX_AXIM_CFG_COMPMASK_BIT_SHIFT 0x7UL -#define DX_AXIM_CFG_COMPMASK_BIT_SIZE 0x1UL -#define DX_AXIM_ACE_CONST_REG_OFFSET 0xBECUL -#define DX_AXIM_ACE_CONST_ARDOMAIN_BIT_SHIFT 0x0UL -#define DX_AXIM_ACE_CONST_ARDOMAIN_BIT_SIZE 0x2UL -#define DX_AXIM_ACE_CONST_AWDOMAIN_BIT_SHIFT 0x2UL -#define DX_AXIM_ACE_CONST_AWDOMAIN_BIT_SIZE 0x2UL -#define DX_AXIM_ACE_CONST_ARBAR_BIT_SHIFT 0x4UL -#define DX_AXIM_ACE_CONST_ARBAR_BIT_SIZE 0x2UL -#define DX_AXIM_ACE_CONST_AWBAR_BIT_SHIFT 0x6UL -#define DX_AXIM_ACE_CONST_AWBAR_BIT_SIZE 0x2UL -#define DX_AXIM_ACE_CONST_ARSNOOP_BIT_SHIFT 0x8UL -#define DX_AXIM_ACE_CONST_ARSNOOP_BIT_SIZE 0x4UL -#define DX_AXIM_ACE_CONST_AWSNOOP_NOT_ALIGNED_BIT_SHIFT 0xCUL -#define DX_AXIM_ACE_CONST_AWSNOOP_NOT_ALIGNED_BIT_SIZE 0x3UL -#define DX_AXIM_ACE_CONST_AWSNOOP_ALIGNED_BIT_SHIFT 0xFUL -#define DX_AXIM_ACE_CONST_AWSNOOP_ALIGNED_BIT_SIZE 0x3UL -#define DX_AXIM_ACE_CONST_AWADDR_NOT_MASKED_BIT_SHIFT 0x12UL -#define DX_AXIM_ACE_CONST_AWADDR_NOT_MASKED_BIT_SIZE 0x7UL -#define DX_AXIM_ACE_CONST_AWLEN_VAL_BIT_SHIFT 0x19UL -#define DX_AXIM_ACE_CONST_AWLEN_VAL_BIT_SIZE 0x4UL -#define DX_AXIM_CACHE_PARAMS_REG_OFFSET 0xBF0UL -#define DX_AXIM_CACHE_PARAMS_AWCACHE_LAST_BIT_SHIFT 0x0UL -#define DX_AXIM_CACHE_PARAMS_AWCACHE_LAST_BIT_SIZE 0x4UL -#define DX_AXIM_CACHE_PARAMS_AWCACHE_BIT_SHIFT 0x4UL -#define DX_AXIM_CACHE_PARAMS_AWCACHE_BIT_SIZE 0x4UL -#define DX_AXIM_CACHE_PARAMS_ARCACHE_BIT_SHIFT 0x8UL -#define DX_AXIM_CACHE_PARAMS_ARCACHE_BIT_SIZE 0x4UL -#endif // __DX_CRYS_KERNEL_H__ diff --git a/drivers/staging/ccree/dx_host.h b/drivers/staging/ccree/dx_host.h deleted file mode 100644 index 863c2670d826..000000000000 --- a/drivers/staging/ccree/dx_host.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef __DX_HOST_H__ -#define __DX_HOST_H__ - -// -------------------------------------- -// BLOCK: HOST_P -// -------------------------------------- -#define DX_HOST_IRR_REG_OFFSET 0xA00UL -#define DX_HOST_IRR_DSCRPTR_COMPLETION_LOW_INT_BIT_SHIFT 0x2UL -#define DX_HOST_IRR_DSCRPTR_COMPLETION_LOW_INT_BIT_SIZE 0x1UL -#define DX_HOST_IRR_AXI_ERR_INT_BIT_SHIFT 0x8UL -#define DX_HOST_IRR_AXI_ERR_INT_BIT_SIZE 0x1UL -#define DX_HOST_IRR_GPR0_BIT_SHIFT 0xBUL -#define DX_HOST_IRR_GPR0_BIT_SIZE 0x1UL -#define DX_HOST_IRR_DSCRPTR_WATERMARK_INT_BIT_SHIFT 0x13UL -#define DX_HOST_IRR_DSCRPTR_WATERMARK_INT_BIT_SIZE 0x1UL -#define DX_HOST_IRR_AXIM_COMP_INT_BIT_SHIFT 0x17UL -#define DX_HOST_IRR_AXIM_COMP_INT_BIT_SIZE 0x1UL -#define DX_HOST_IMR_REG_OFFSET 0xA04UL -#define DX_HOST_IMR_NOT_USED_MASK_BIT_SHIFT 0x1UL -#define DX_HOST_IMR_NOT_USED_MASK_BIT_SIZE 0x1UL -#define DX_HOST_IMR_DSCRPTR_COMPLETION_MASK_BIT_SHIFT 0x2UL -#define DX_HOST_IMR_DSCRPTR_COMPLETION_MASK_BIT_SIZE 0x1UL -#define DX_HOST_IMR_AXI_ERR_MASK_BIT_SHIFT 0x8UL -#define DX_HOST_IMR_AXI_ERR_MASK_BIT_SIZE 0x1UL -#define DX_HOST_IMR_GPR0_BIT_SHIFT 0xBUL -#define DX_HOST_IMR_GPR0_BIT_SIZE 0x1UL -#define DX_HOST_IMR_DSCRPTR_WATERMARK_MASK0_BIT_SHIFT 0x13UL -#define DX_HOST_IMR_DSCRPTR_WATERMARK_MASK0_BIT_SIZE 0x1UL -#define DX_HOST_IMR_AXIM_COMP_INT_MASK_BIT_SHIFT 0x17UL -#define DX_HOST_IMR_AXIM_COMP_INT_MASK_BIT_SIZE 0x1UL -#define DX_HOST_ICR_REG_OFFSET 0xA08UL -#define DX_HOST_ICR_DSCRPTR_COMPLETION_BIT_SHIFT 0x2UL -#define DX_HOST_ICR_DSCRPTR_COMPLETION_BIT_SIZE 0x1UL -#define DX_HOST_ICR_AXI_ERR_CLEAR_BIT_SHIFT 0x8UL -#define DX_HOST_ICR_AXI_ERR_CLEAR_BIT_SIZE 0x1UL -#define DX_HOST_ICR_GPR_INT_CLEAR_BIT_SHIFT 0xBUL -#define DX_HOST_ICR_GPR_INT_CLEAR_BIT_SIZE 0x1UL -#define DX_HOST_ICR_DSCRPTR_WATERMARK_QUEUE0_CLEAR_BIT_SHIFT 0x13UL -#define DX_HOST_ICR_DSCRPTR_WATERMARK_QUEUE0_CLEAR_BIT_SIZE 0x1UL -#define DX_HOST_ICR_AXIM_COMP_INT_CLEAR_BIT_SHIFT 0x17UL -#define DX_HOST_ICR_AXIM_COMP_INT_CLEAR_BIT_SIZE 0x1UL -#define DX_HOST_SIGNATURE_REG_OFFSET 0xA24UL -#define DX_HOST_SIGNATURE_VALUE_BIT_SHIFT 0x0UL -#define DX_HOST_SIGNATURE_VALUE_BIT_SIZE 0x20UL -#define DX_HOST_BOOT_REG_OFFSET 0xA28UL -#define DX_HOST_BOOT_SYNTHESIS_CONFIG_BIT_SHIFT 0x0UL -#define DX_HOST_BOOT_SYNTHESIS_CONFIG_BIT_SIZE 0x1UL -#define DX_HOST_BOOT_LARGE_RKEK_LOCAL_BIT_SHIFT 0x1UL -#define DX_HOST_BOOT_LARGE_RKEK_LOCAL_BIT_SIZE 0x1UL -#define DX_HOST_BOOT_HASH_IN_FUSES_LOCAL_BIT_SHIFT 0x2UL -#define DX_HOST_BOOT_HASH_IN_FUSES_LOCAL_BIT_SIZE 0x1UL -#define DX_HOST_BOOT_EXT_MEM_SECURED_LOCAL_BIT_SHIFT 0x3UL -#define DX_HOST_BOOT_EXT_MEM_SECURED_LOCAL_BIT_SIZE 0x1UL -#define DX_HOST_BOOT_RKEK_ECC_EXISTS_LOCAL_N_BIT_SHIFT 0x5UL -#define DX_HOST_BOOT_RKEK_ECC_EXISTS_LOCAL_N_BIT_SIZE 0x1UL -#define DX_HOST_BOOT_SRAM_SIZE_LOCAL_BIT_SHIFT 0x6UL -#define DX_HOST_BOOT_SRAM_SIZE_LOCAL_BIT_SIZE 0x3UL -#define DX_HOST_BOOT_DSCRPTR_EXISTS_LOCAL_BIT_SHIFT 0x9UL -#define DX_HOST_BOOT_DSCRPTR_EXISTS_LOCAL_BIT_SIZE 0x1UL -#define DX_HOST_BOOT_PAU_EXISTS_LOCAL_BIT_SHIFT 0xAUL -#define DX_HOST_BOOT_PAU_EXISTS_LOCAL_BIT_SIZE 0x1UL -#define DX_HOST_BOOT_RNG_EXISTS_LOCAL_BIT_SHIFT 0xBUL -#define DX_HOST_BOOT_RNG_EXISTS_LOCAL_BIT_SIZE 0x1UL -#define DX_HOST_BOOT_PKA_EXISTS_LOCAL_BIT_SHIFT 0xCUL -#define DX_HOST_BOOT_PKA_EXISTS_LOCAL_BIT_SIZE 0x1UL -#define DX_HOST_BOOT_RC4_EXISTS_LOCAL_BIT_SHIFT 0xDUL -#define DX_HOST_BOOT_RC4_EXISTS_LOCAL_BIT_SIZE 0x1UL -#define DX_HOST_BOOT_SHA_512_PRSNT_LOCAL_BIT_SHIFT 0xEUL -#define DX_HOST_BOOT_SHA_512_PRSNT_LOCAL_BIT_SIZE 0x1UL -#define DX_HOST_BOOT_SHA_256_PRSNT_LOCAL_BIT_SHIFT 0xFUL -#define DX_HOST_BOOT_SHA_256_PRSNT_LOCAL_BIT_SIZE 0x1UL -#define DX_HOST_BOOT_MD5_PRSNT_LOCAL_BIT_SHIFT 0x10UL -#define DX_HOST_BOOT_MD5_PRSNT_LOCAL_BIT_SIZE 0x1UL -#define DX_HOST_BOOT_HASH_EXISTS_LOCAL_BIT_SHIFT 0x11UL -#define DX_HOST_BOOT_HASH_EXISTS_LOCAL_BIT_SIZE 0x1UL -#define DX_HOST_BOOT_C2_EXISTS_LOCAL_BIT_SHIFT 0x12UL -#define DX_HOST_BOOT_C2_EXISTS_LOCAL_BIT_SIZE 0x1UL -#define DX_HOST_BOOT_DES_EXISTS_LOCAL_BIT_SHIFT 0x13UL -#define DX_HOST_BOOT_DES_EXISTS_LOCAL_BIT_SIZE 0x1UL -#define DX_HOST_BOOT_AES_XCBC_MAC_EXISTS_LOCAL_BIT_SHIFT 0x14UL -#define DX_HOST_BOOT_AES_XCBC_MAC_EXISTS_LOCAL_BIT_SIZE 0x1UL -#define DX_HOST_BOOT_AES_CMAC_EXISTS_LOCAL_BIT_SHIFT 0x15UL -#define DX_HOST_BOOT_AES_CMAC_EXISTS_LOCAL_BIT_SIZE 0x1UL -#define DX_HOST_BOOT_AES_CCM_EXISTS_LOCAL_BIT_SHIFT 0x16UL -#define DX_HOST_BOOT_AES_CCM_EXISTS_LOCAL_BIT_SIZE 0x1UL -#define DX_HOST_BOOT_AES_XEX_HW_T_CALC_LOCAL_BIT_SHIFT 0x17UL -#define DX_HOST_BOOT_AES_XEX_HW_T_CALC_LOCAL_BIT_SIZE 0x1UL -#define DX_HOST_BOOT_AES_XEX_EXISTS_LOCAL_BIT_SHIFT 0x18UL -#define DX_HOST_BOOT_AES_XEX_EXISTS_LOCAL_BIT_SIZE 0x1UL -#define DX_HOST_BOOT_CTR_EXISTS_LOCAL_BIT_SHIFT 0x19UL -#define DX_HOST_BOOT_CTR_EXISTS_LOCAL_BIT_SIZE 0x1UL -#define DX_HOST_BOOT_AES_DIN_BYTE_RESOLUTION_LOCAL_BIT_SHIFT 0x1AUL -#define DX_HOST_BOOT_AES_DIN_BYTE_RESOLUTION_LOCAL_BIT_SIZE 0x1UL -#define DX_HOST_BOOT_TUNNELING_ENB_LOCAL_BIT_SHIFT 0x1BUL -#define DX_HOST_BOOT_TUNNELING_ENB_LOCAL_BIT_SIZE 0x1UL -#define DX_HOST_BOOT_SUPPORT_256_192_KEY_LOCAL_BIT_SHIFT 0x1CUL -#define DX_HOST_BOOT_SUPPORT_256_192_KEY_LOCAL_BIT_SIZE 0x1UL -#define DX_HOST_BOOT_ONLY_ENCRYPT_LOCAL_BIT_SHIFT 0x1DUL -#define DX_HOST_BOOT_ONLY_ENCRYPT_LOCAL_BIT_SIZE 0x1UL -#define DX_HOST_BOOT_AES_EXISTS_LOCAL_BIT_SHIFT 0x1EUL -#define DX_HOST_BOOT_AES_EXISTS_LOCAL_BIT_SIZE 0x1UL -#define DX_HOST_VERSION_REG_OFFSET 0xA40UL -#define DX_HOST_VERSION_VALUE_BIT_SHIFT 0x0UL -#define DX_HOST_VERSION_VALUE_BIT_SIZE 0x20UL -#define DX_HOST_KFDE0_VALID_REG_OFFSET 0xA60UL -#define DX_HOST_KFDE0_VALID_VALUE_BIT_SHIFT 0x0UL -#define DX_HOST_KFDE0_VALID_VALUE_BIT_SIZE 0x1UL -#define DX_HOST_KFDE1_VALID_REG_OFFSET 0xA64UL -#define DX_HOST_KFDE1_VALID_VALUE_BIT_SHIFT 0x0UL -#define DX_HOST_KFDE1_VALID_VALUE_BIT_SIZE 0x1UL -#define DX_HOST_KFDE2_VALID_REG_OFFSET 0xA68UL -#define DX_HOST_KFDE2_VALID_VALUE_BIT_SHIFT 0x0UL -#define DX_HOST_KFDE2_VALID_VALUE_BIT_SIZE 0x1UL -#define DX_HOST_KFDE3_VALID_REG_OFFSET 0xA6CUL -#define DX_HOST_KFDE3_VALID_VALUE_BIT_SHIFT 0x0UL -#define DX_HOST_KFDE3_VALID_VALUE_BIT_SIZE 0x1UL -#define DX_HOST_GPR0_REG_OFFSET 0xA70UL -#define DX_HOST_GPR0_VALUE_BIT_SHIFT 0x0UL -#define DX_HOST_GPR0_VALUE_BIT_SIZE 0x20UL -#define DX_GPR_HOST_REG_OFFSET 0xA74UL -#define DX_GPR_HOST_VALUE_BIT_SHIFT 0x0UL -#define DX_GPR_HOST_VALUE_BIT_SIZE 0x20UL -#define DX_HOST_POWER_DOWN_EN_REG_OFFSET 0xA78UL -#define DX_HOST_POWER_DOWN_EN_VALUE_BIT_SHIFT 0x0UL -#define DX_HOST_POWER_DOWN_EN_VALUE_BIT_SIZE 0x1UL -// -------------------------------------- -// BLOCK: HOST_SRAM -// -------------------------------------- -#define DX_SRAM_DATA_REG_OFFSET 0xF00UL -#define DX_SRAM_DATA_VALUE_BIT_SHIFT 0x0UL -#define DX_SRAM_DATA_VALUE_BIT_SIZE 0x20UL -#define DX_SRAM_ADDR_REG_OFFSET 0xF04UL -#define DX_SRAM_ADDR_VALUE_BIT_SHIFT 0x0UL -#define DX_SRAM_ADDR_VALUE_BIT_SIZE 0xFUL -#define DX_SRAM_DATA_READY_REG_OFFSET 0xF08UL -#define DX_SRAM_DATA_READY_VALUE_BIT_SHIFT 0x0UL -#define DX_SRAM_DATA_READY_VALUE_BIT_SIZE 0x1UL - -#endif //__DX_HOST_H__ diff --git a/drivers/staging/ccree/dx_reg_common.h b/drivers/staging/ccree/dx_reg_common.h deleted file mode 100644 index d5132ffaf6e6..000000000000 --- a/drivers/staging/ccree/dx_reg_common.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef __DX_REG_COMMON_H__ -#define __DX_REG_COMMON_H__ - -#define DX_DEV_SIGNATURE 0xDCC71200UL - -#define CC_HW_VERSION 0xef840015UL - -#define DX_DEV_SHA_MAX 512 - -#endif /*__DX_REG_COMMON_H__*/ diff --git a/drivers/staging/ccree/hash_defs.h b/drivers/staging/ccree/hash_defs.h deleted file mode 100644 index f52656f5a3ea..000000000000 --- a/drivers/staging/ccree/hash_defs.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _HASH_DEFS_H_ -#define _HASH_DEFS_H_ - -#include "cc_crypto_ctx.h" - -enum cc_hash_conf_pad { - HASH_PADDING_DISABLED = 0, - HASH_PADDING_ENABLED = 1, - HASH_DIGEST_RESULT_LITTLE_ENDIAN = 2, - HASH_CONFIG1_PADDING_RESERVE32 = S32_MAX, -}; - -enum cc_hash_cipher_pad { - DO_NOT_PAD = 0, - DO_PAD = 1, - HASH_CIPHER_DO_PADDING_RESERVE32 = S32_MAX, -}; - -#endif /*_HASH_DEFS_H_*/ - diff --git a/drivers/staging/ccree/ssi_buffer_mgr.h b/drivers/staging/ccree/ssi_buffer_mgr.h deleted file mode 100644 index 1032f25edcab..000000000000 --- a/drivers/staging/ccree/ssi_buffer_mgr.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -/* \file buffer_mgr.h - * Buffer Manager - */ - -#ifndef __SSI_BUFFER_MGR_H__ -#define __SSI_BUFFER_MGR_H__ - -#include <crypto/algapi.h> - -#include "ssi_config.h" -#include "ssi_driver.h" - -enum ssi_req_dma_buf_type { - SSI_DMA_BUF_NULL = 0, - SSI_DMA_BUF_DLLI, - SSI_DMA_BUF_MLLI -}; - -enum ssi_sg_cpy_direct { - SSI_SG_TO_BUF = 0, - SSI_SG_FROM_BUF = 1 -}; - -struct ssi_mlli { - ssi_sram_addr_t sram_addr; - unsigned int nents; //sg nents - unsigned int mlli_nents; //mlli nents might be different than the above -}; - -struct mlli_params { - struct dma_pool *curr_pool; - u8 *mlli_virt_addr; - dma_addr_t mlli_dma_addr; - u32 mlli_len; -}; - -int ssi_buffer_mgr_init(struct ssi_drvdata *drvdata); - -int ssi_buffer_mgr_fini(struct ssi_drvdata *drvdata); - -int ssi_buffer_mgr_map_blkcipher_request( - struct ssi_drvdata *drvdata, - void *ctx, - unsigned int ivsize, - unsigned int nbytes, - void *info, - struct scatterlist *src, - struct scatterlist *dst); - -void ssi_buffer_mgr_unmap_blkcipher_request( - struct device *dev, - void *ctx, - unsigned int ivsize, - struct scatterlist *src, - struct scatterlist *dst); - -int ssi_buffer_mgr_map_aead_request(struct ssi_drvdata *drvdata, struct aead_request *req); - -void ssi_buffer_mgr_unmap_aead_request(struct device *dev, struct aead_request *req); - -int ssi_buffer_mgr_map_hash_request_final(struct ssi_drvdata *drvdata, void *ctx, struct scatterlist *src, unsigned int nbytes, bool do_update); - -int ssi_buffer_mgr_map_hash_request_update(struct ssi_drvdata *drvdata, void *ctx, struct scatterlist *src, unsigned int nbytes, unsigned int block_size); - -void ssi_buffer_mgr_unmap_hash_request(struct device *dev, void *ctx, struct scatterlist *src, bool do_revert); - -void ssi_buffer_mgr_copy_scatterlist_portion(struct device *dev, u8 *dest, - struct scatterlist *sg, - u32 to_skip, u32 end, - enum ssi_sg_cpy_direct direct); - -void ssi_buffer_mgr_zero_sgl(struct scatterlist *sgl, u32 data_len); - -#endif /*__BUFFER_MGR_H__*/ - diff --git a/drivers/staging/ccree/ssi_cipher.h b/drivers/staging/ccree/ssi_cipher.h deleted file mode 100644 index 25e6335c0d94..000000000000 --- a/drivers/staging/ccree/ssi_cipher.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -/* \file ssi_cipher.h - * ARM CryptoCell Cipher Crypto API - */ - -#ifndef __SSI_CIPHER_H__ -#define __SSI_CIPHER_H__ - -#include <linux/kernel.h> -#include <crypto/algapi.h> -#include "ssi_driver.h" -#include "ssi_buffer_mgr.h" - -/* Crypto cipher flags */ -#define CC_CRYPTO_CIPHER_KEY_KFDE0 BIT(0) -#define CC_CRYPTO_CIPHER_KEY_KFDE1 BIT(1) -#define CC_CRYPTO_CIPHER_KEY_KFDE2 BIT(2) -#define CC_CRYPTO_CIPHER_KEY_KFDE3 BIT(3) -#define CC_CRYPTO_CIPHER_DU_SIZE_512B BIT(4) - -#define CC_CRYPTO_CIPHER_KEY_KFDE_MASK (CC_CRYPTO_CIPHER_KEY_KFDE0 | CC_CRYPTO_CIPHER_KEY_KFDE1 | CC_CRYPTO_CIPHER_KEY_KFDE2 | CC_CRYPTO_CIPHER_KEY_KFDE3) - -struct blkcipher_req_ctx { - struct async_gen_req_ctx gen_ctx; - enum ssi_req_dma_buf_type dma_buf_type; - u32 in_nents; - u32 in_mlli_nents; - u32 out_nents; - u32 out_mlli_nents; - u8 *backup_info; /*store iv for generated IV flow*/ - u8 *iv; - bool is_giv; - struct mlli_params mlli_params; -}; - -int ssi_ablkcipher_alloc(struct ssi_drvdata *drvdata); - -int ssi_ablkcipher_free(struct ssi_drvdata *drvdata); - -#ifndef CRYPTO_ALG_BULK_MASK - -#define CRYPTO_ALG_BULK_DU_512 0x00002000 -#define CRYPTO_ALG_BULK_DU_4096 0x00004000 -#define CRYPTO_ALG_BULK_MASK (CRYPTO_ALG_BULK_DU_512 |\ - CRYPTO_ALG_BULK_DU_4096) -#endif /* CRYPTO_ALG_BULK_MASK */ - -#ifdef CRYPTO_TFM_REQ_HW_KEY - -static inline bool ssi_is_hw_key(struct crypto_tfm *tfm) -{ - return (crypto_tfm_get_flags(tfm) & CRYPTO_TFM_REQ_HW_KEY); -} - -#else - -struct arm_hw_key_info { - int hw_key1; - int hw_key2; -}; - -static inline bool ssi_is_hw_key(struct crypto_tfm *tfm) -{ - return false; -} - -#endif /* CRYPTO_TFM_REQ_HW_KEY */ - -#endif /*__SSI_CIPHER_H__*/ diff --git a/drivers/staging/ccree/ssi_config.h b/drivers/staging/ccree/ssi_config.h deleted file mode 100644 index ff7597c2d77e..000000000000 --- a/drivers/staging/ccree/ssi_config.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -/* \file ssi_config.h - * Definitions for ARM CryptoCell Linux Crypto Driver - */ - -#ifndef __SSI_CONFIG_H__ -#define __SSI_CONFIG_H__ - -#include <linux/version.h> - -//#define FLUSH_CACHE_ALL -//#define COMPLETION_DELAY -//#define DX_DUMP_DESCS -// #define DX_DUMP_BYTES -// #define CC_DEBUG -#define ENABLE_CC_SYSFS /* Enable sysfs interface for debugging REE driver */ -//#define DX_IRQ_DELAY 100000 -#define DMA_BIT_MASK_LEN 48 /* was 32 bit, but for juno's sake it was enlarged to 48 bit */ - -#endif /*__DX_CONFIG_H__*/ - diff --git a/drivers/staging/ccree/ssi_driver.h b/drivers/staging/ccree/ssi_driver.h deleted file mode 100644 index 94c755cafb47..000000000000 --- a/drivers/staging/ccree/ssi_driver.h +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -/* \file ssi_driver.h - * ARM CryptoCell Linux Crypto Driver - */ - -#ifndef __SSI_DRIVER_H__ -#define __SSI_DRIVER_H__ - -#include "ssi_config.h" -#ifdef COMP_IN_WQ -#include <linux/workqueue.h> -#else -#include <linux/interrupt.h> -#endif -#include <linux/dma-mapping.h> -#include <crypto/algapi.h> -#include <crypto/internal/skcipher.h> -#include <crypto/aes.h> -#include <crypto/sha.h> -#include <crypto/aead.h> -#include <crypto/authenc.h> -#include <crypto/hash.h> -#include <linux/version.h> -#include <linux/clk.h> -#include <linux/platform_device.h> - -/* Registers definitions from shared/hw/ree_include */ -#include "dx_host.h" -#include "dx_reg_common.h" -#define CC_SUPPORT_SHA DX_DEV_SHA_MAX -#include "cc_crypto_ctx.h" -#include "ssi_sysfs.h" -#include "hash_defs.h" -#include "cc_hw_queue_defs.h" -#include "ssi_sram_mgr.h" - -#define DRV_MODULE_VERSION "3.0" - -#define SSI_DEV_NAME_STR "cc715ree" -#define CC_COHERENT_CACHE_PARAMS 0xEEE - -#define SSI_CC_HAS_AES_CCM 1 -#define SSI_CC_HAS_AES_GCM 1 -#define SSI_CC_HAS_AES_XTS 1 -#define SSI_CC_HAS_AES_ESSIV 1 -#define SSI_CC_HAS_AES_BITLOCKER 1 -#define SSI_CC_HAS_AES_CTS 1 -#define SSI_CC_HAS_MULTI2 0 -#define SSI_CC_HAS_CMAC 1 - -#define SSI_AXI_IRQ_MASK ((1 << DX_AXIM_CFG_BRESPMASK_BIT_SHIFT) | (1 << DX_AXIM_CFG_RRESPMASK_BIT_SHIFT) | \ - (1 << DX_AXIM_CFG_INFLTMASK_BIT_SHIFT) | (1 << DX_AXIM_CFG_COMPMASK_BIT_SHIFT)) - -#define SSI_AXI_ERR_IRQ_MASK BIT(DX_HOST_IRR_AXI_ERR_INT_BIT_SHIFT) - -#define SSI_COMP_IRQ_MASK BIT(DX_HOST_IRR_AXIM_COMP_INT_BIT_SHIFT) - -#define AXIM_MON_COMP_VALUE GENMASK(DX_AXIM_MON_COMP_VALUE_BIT_SIZE + \ - DX_AXIM_MON_COMP_VALUE_BIT_SHIFT, \ - DX_AXIM_MON_COMP_VALUE_BIT_SHIFT) - -/* Register name mangling macro */ -#define CC_REG(reg_name) DX_ ## reg_name ## _REG_OFFSET - -/* TEE FIPS status interrupt */ -#define SSI_GPR0_IRQ_MASK BIT(DX_HOST_IRR_GPR0_BIT_SHIFT) - -#define SSI_CRA_PRIO 3000 - -#define MIN_HW_QUEUE_SIZE 50 /* Minimum size required for proper function */ - -#define MAX_REQUEST_QUEUE_SIZE 4096 -#define MAX_MLLI_BUFF_SIZE 2080 -#define MAX_ICV_NENTS_SUPPORTED 2 - -/* Definitions for HW descriptors DIN/DOUT fields */ -#define NS_BIT 1 -#define AXI_ID 0 -/* AXI_ID is not actually the AXI ID of the transaction but the value of AXI_ID - * field in the HW descriptor. The DMA engine +8 that value. - */ - -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) - -#define SSI_MAX_IVGEN_DMA_ADDRESSES 3 -struct ssi_crypto_req { - void (*user_cb)(struct device *dev, void *req, void __iomem *cc_base); - void *user_arg; - dma_addr_t ivgen_dma_addr[SSI_MAX_IVGEN_DMA_ADDRESSES]; - /* For the first 'ivgen_dma_addr_len' addresses of this array, - * generated IV would be placed in it by send_request(). - * Same generated IV for all addresses! - */ - unsigned int ivgen_dma_addr_len; /* Amount of 'ivgen_dma_addr' elements to be filled. */ - unsigned int ivgen_size; /* The generated IV size required, 8/16 B allowed. */ - struct completion seq_compl; /* request completion */ -}; - -/** - * struct ssi_drvdata - driver private data context - * @cc_base: virt address of the CC registers - * @irq: device IRQ number - * @irq_mask: Interrupt mask shadow (1 for masked interrupts) - * @fw_ver: SeP loaded firmware version - */ -struct ssi_drvdata { - void __iomem *cc_base; - int irq; - u32 irq_mask; - u32 fw_ver; - /* Calibration time of start/stop - * monitor descriptors - */ - u32 monitor_null_cycles; - struct platform_device *plat_dev; - ssi_sram_addr_t mlli_sram_addr; - void *buff_mgr_handle; - void *hash_handle; - void *aead_handle; - void *blkcipher_handle; - void *request_mgr_handle; - void *fips_handle; - void *ivgen_handle; - void *sram_mgr_handle; - struct clk *clk; - bool coherent; -}; - -struct ssi_crypto_alg { - struct list_head entry; - int cipher_mode; - int flow_mode; /* Note: currently, refers to the cipher mode only. */ - int auth_mode; - struct ssi_drvdata *drvdata; - struct crypto_alg crypto_alg; - struct aead_alg aead_alg; -}; - -struct ssi_alg_template { - char name[CRYPTO_MAX_ALG_NAME]; - char driver_name[CRYPTO_MAX_ALG_NAME]; - unsigned int blocksize; - u32 type; - union { - struct ablkcipher_alg ablkcipher; - struct aead_alg aead; - struct blkcipher_alg blkcipher; - struct cipher_alg cipher; - struct compress_alg compress; - } template_u; - int cipher_mode; - int flow_mode; /* Note: currently, refers to the cipher mode only. */ - int auth_mode; - struct ssi_drvdata *drvdata; -}; - -struct async_gen_req_ctx { - dma_addr_t iv_dma_addr; - enum drv_crypto_direction op_type; -}; - -static inline struct device *drvdata_to_dev(struct ssi_drvdata *drvdata) -{ - return &drvdata->plat_dev->dev; -} - -#ifdef DX_DUMP_BYTES -void dump_byte_array(const char *name, const u8 *the_array, unsigned long size); -#else -static inline void dump_byte_array(const char *name, const u8 *the_array, - unsigned long size) {}; -#endif - -int init_cc_regs(struct ssi_drvdata *drvdata, bool is_probe); -void fini_cc_regs(struct ssi_drvdata *drvdata); -int cc_clk_on(struct ssi_drvdata *drvdata); -void cc_clk_off(struct ssi_drvdata *drvdata); - -static inline void cc_iowrite(struct ssi_drvdata *drvdata, u32 reg, u32 val) -{ - iowrite32(val, (drvdata->cc_base + reg)); -} - -static inline u32 cc_ioread(struct ssi_drvdata *drvdata, u32 reg) -{ - return ioread32(drvdata->cc_base + reg); -} - -#endif /*__SSI_DRIVER_H__*/ - diff --git a/drivers/staging/ccree/ssi_fips.h b/drivers/staging/ccree/ssi_fips.h deleted file mode 100644 index 63bcca7f3af9..000000000000 --- a/drivers/staging/ccree/ssi_fips.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef __SSI_FIPS_H__ -#define __SSI_FIPS_H__ - -#ifdef CONFIG_CRYPTO_FIPS - -enum cc_fips_status { - CC_FIPS_SYNC_MODULE_OK = 0x0, - CC_FIPS_SYNC_MODULE_ERROR = 0x1, - CC_FIPS_SYNC_REE_STATUS = 0x4, - CC_FIPS_SYNC_TEE_STATUS = 0x8, - CC_FIPS_SYNC_STATUS_RESERVE32B = S32_MAX -}; - -int ssi_fips_init(struct ssi_drvdata *p_drvdata); -void ssi_fips_fini(struct ssi_drvdata *drvdata); -void fips_handler(struct ssi_drvdata *drvdata); -void cc_set_ree_fips_status(struct ssi_drvdata *drvdata, bool ok); - -#else /* CONFIG_CRYPTO_FIPS */ - -static inline int ssi_fips_init(struct ssi_drvdata *p_drvdata) -{ - return 0; -} - -static inline void ssi_fips_fini(struct ssi_drvdata *drvdata) {} -static inline void cc_set_ree_fips_status(struct ssi_drvdata *drvdata, bool ok) {} -static inline void fips_handler(struct ssi_drvdata *drvdata) {} - -#endif /* CONFIG_CRYPTO_FIPS */ - -#endif /*__SSI_FIPS_H__*/ - diff --git a/drivers/staging/ccree/ssi_hash.h b/drivers/staging/ccree/ssi_hash.h deleted file mode 100644 index 2400e389d65a..000000000000 --- a/drivers/staging/ccree/ssi_hash.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -/* \file ssi_hash.h - * ARM CryptoCell Hash Crypto API - */ - -#ifndef __SSI_HASH_H__ -#define __SSI_HASH_H__ - -#include "ssi_buffer_mgr.h" - -#define HMAC_IPAD_CONST 0x36363636 -#define HMAC_OPAD_CONST 0x5C5C5C5C -#if (DX_DEV_SHA_MAX > 256) -#define HASH_LEN_SIZE 16 -#define SSI_MAX_HASH_DIGEST_SIZE SHA512_DIGEST_SIZE -#define SSI_MAX_HASH_BLCK_SIZE SHA512_BLOCK_SIZE -#else -#define HASH_LEN_SIZE 8 -#define SSI_MAX_HASH_DIGEST_SIZE SHA256_DIGEST_SIZE -#define SSI_MAX_HASH_BLCK_SIZE SHA256_BLOCK_SIZE -#endif - -#define XCBC_MAC_K1_OFFSET 0 -#define XCBC_MAC_K2_OFFSET 16 -#define XCBC_MAC_K3_OFFSET 32 - -#define CC_EXPORT_MAGIC 0xC2EE1070U - -// this struct was taken from drivers/crypto/nx/nx-aes-xcbc.c and it is used for xcbc/cmac statesize -struct aeshash_state { - u8 state[AES_BLOCK_SIZE]; - unsigned int count; - u8 buffer[AES_BLOCK_SIZE]; -}; - -/* ahash state */ -struct ahash_req_ctx { - u8 *buff0; - u8 *buff1; - u8 *digest_result_buff; - struct async_gen_req_ctx gen_ctx; - enum ssi_req_dma_buf_type data_dma_buf_type; - u8 *digest_buff; - u8 *opad_digest_buff; - u8 *digest_bytes_len; - dma_addr_t opad_digest_dma_addr; - dma_addr_t digest_buff_dma_addr; - dma_addr_t digest_bytes_len_dma_addr; - dma_addr_t digest_result_dma_addr; - u32 buff0_cnt; - u32 buff1_cnt; - u32 buff_index; - u32 xcbc_count; /* count xcbc update operatations */ - struct scatterlist buff_sg[2]; - struct scatterlist *curr_sg; - u32 in_nents; - u32 mlli_nents; - struct mlli_params mlli_params; -}; - -int ssi_hash_alloc(struct ssi_drvdata *drvdata); -int ssi_hash_init_sram_digest_consts(struct ssi_drvdata *drvdata); -int ssi_hash_free(struct ssi_drvdata *drvdata); - -/*! - * Gets the initial digest length - * - * \param drvdata - * \param mode The Hash mode. Supported modes: MD5/SHA1/SHA224/SHA256/SHA384/SHA512 - * - * \return u32 returns the address of the initial digest length in SRAM - */ -ssi_sram_addr_t -ssi_ahash_get_initial_digest_len_sram_addr(void *drvdata, u32 mode); - -/*! - * Gets the address of the initial digest in SRAM - * according to the given hash mode - * - * \param drvdata - * \param mode The Hash mode. Supported modes: MD5/SHA1/SHA224/SHA256/SHA384/SHA512 - * - * \return u32 The address of the inital digest in SRAM - */ -ssi_sram_addr_t ssi_ahash_get_larval_digest_sram_addr(void *drvdata, u32 mode); - -#endif /*__SSI_HASH_H__*/ - diff --git a/drivers/staging/ccree/ssi_ivgen.h b/drivers/staging/ccree/ssi_ivgen.h deleted file mode 100644 index 961aea411cb3..000000000000 --- a/drivers/staging/ccree/ssi_ivgen.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef __SSI_IVGEN_H__ -#define __SSI_IVGEN_H__ - -#include "cc_hw_queue_defs.h" - -#define SSI_IVPOOL_SEQ_LEN 8 - -/*! - * Allocates iv-pool and maps resources. - * This function generates the first IV pool. - * - * \param drvdata Driver's private context - * - * \return int Zero for success, negative value otherwise. - */ -int ssi_ivgen_init(struct ssi_drvdata *drvdata); - -/*! - * Free iv-pool and ivgen context. - * - * \param drvdata - */ -void ssi_ivgen_fini(struct ssi_drvdata *drvdata); - -/*! - * Generates the initial pool in SRAM. - * This function should be invoked when resuming DX driver. - * - * \param drvdata - * - * \return int Zero for success, negative value otherwise. - */ -int ssi_ivgen_init_sram_pool(struct ssi_drvdata *drvdata); - -/*! - * Acquires 16 Bytes IV from the iv-pool - * - * \param drvdata Driver private context - * \param iv_out_dma Array of physical IV out addresses - * \param iv_out_dma_len Length of iv_out_dma array (additional elements of iv_out_dma array are ignore) - * \param iv_out_size May be 8 or 16 bytes long - * \param iv_seq IN/OUT array to the descriptors sequence - * \param iv_seq_len IN/OUT pointer to the sequence length - * - * \return int Zero for success, negative value otherwise. - */ -int ssi_ivgen_getiv( - struct ssi_drvdata *drvdata, - dma_addr_t iv_out_dma[], - unsigned int iv_out_dma_len, - unsigned int iv_out_size, - struct cc_hw_desc iv_seq[], - unsigned int *iv_seq_len); - -#endif /*__SSI_IVGEN_H__*/ diff --git a/drivers/staging/ccree/ssi_pm.c b/drivers/staging/ccree/ssi_pm.c deleted file mode 100644 index 36a498098a70..000000000000 --- a/drivers/staging/ccree/ssi_pm.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#include "ssi_config.h" -#include <linux/kernel.h> -#include <linux/platform_device.h> -#include <linux/interrupt.h> -#include <crypto/ctr.h> -#include <linux/pm_runtime.h> -#include "ssi_driver.h" -#include "ssi_buffer_mgr.h" -#include "ssi_request_mgr.h" -#include "ssi_sram_mgr.h" -#include "ssi_sysfs.h" -#include "ssi_ivgen.h" -#include "ssi_hash.h" -#include "ssi_pm.h" - -#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP) - -#define POWER_DOWN_ENABLE 0x01 -#define POWER_DOWN_DISABLE 0x00 - -int ssi_power_mgr_runtime_suspend(struct device *dev) -{ - struct ssi_drvdata *drvdata = - (struct ssi_drvdata *)dev_get_drvdata(dev); - int rc; - - dev_dbg(dev, "set HOST_POWER_DOWN_EN\n"); - cc_iowrite(drvdata, CC_REG(HOST_POWER_DOWN_EN), POWER_DOWN_ENABLE); - rc = ssi_request_mgr_runtime_suspend_queue(drvdata); - if (rc != 0) { - dev_err(dev, "ssi_request_mgr_runtime_suspend_queue (%x)\n", - rc); - return rc; - } - fini_cc_regs(drvdata); - cc_clk_off(drvdata); - return 0; -} - -int ssi_power_mgr_runtime_resume(struct device *dev) -{ - int rc; - struct ssi_drvdata *drvdata = - (struct ssi_drvdata *)dev_get_drvdata(dev); - - dev_dbg(dev, "unset HOST_POWER_DOWN_EN\n"); - cc_iowrite(drvdata, CC_REG(HOST_POWER_DOWN_EN), POWER_DOWN_DISABLE); - - rc = cc_clk_on(drvdata); - if (rc) { - dev_err(dev, "failed getting clock back on. We're toast.\n"); - return rc; - } - - rc = init_cc_regs(drvdata, false); - if (rc != 0) { - dev_err(dev, "init_cc_regs (%x)\n", rc); - return rc; - } - - rc = ssi_request_mgr_runtime_resume_queue(drvdata); - if (rc != 0) { - dev_err(dev, "ssi_request_mgr_runtime_resume_queue (%x)\n", rc); - return rc; - } - - /* must be after the queue resuming as it uses the HW queue*/ - ssi_hash_init_sram_digest_consts(drvdata); - - ssi_ivgen_init_sram_pool(drvdata); - return 0; -} - -int ssi_power_mgr_runtime_get(struct device *dev) -{ - int rc = 0; - - if (ssi_request_mgr_is_queue_runtime_suspend( - (struct ssi_drvdata *)dev_get_drvdata(dev))) { - rc = pm_runtime_get_sync(dev); - } else { - pm_runtime_get_noresume(dev); - } - return rc; -} - -int ssi_power_mgr_runtime_put_suspend(struct device *dev) -{ - int rc = 0; - - if (!ssi_request_mgr_is_queue_runtime_suspend( - (struct ssi_drvdata *)dev_get_drvdata(dev))) { - pm_runtime_mark_last_busy(dev); - rc = pm_runtime_put_autosuspend(dev); - } else { - /* Something wrong happens*/ - dev_err(dev, "request to suspend already suspended queue"); - rc = -EBUSY; - } - return rc; -} - -#endif - -int ssi_power_mgr_init(struct ssi_drvdata *drvdata) -{ - int rc = 0; -#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP) - struct device *dev = drvdata_to_dev(drvdata); - - /* must be before the enabling to avoid resdundent suspending */ - pm_runtime_set_autosuspend_delay(dev, SSI_SUSPEND_TIMEOUT); - pm_runtime_use_autosuspend(dev); - /* activate the PM module */ - rc = pm_runtime_set_active(dev); - if (rc != 0) - return rc; - /* enable the PM module*/ - pm_runtime_enable(dev); -#endif - return rc; -} - -void ssi_power_mgr_fini(struct ssi_drvdata *drvdata) -{ -#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP) - pm_runtime_disable(drvdata_to_dev(drvdata)); -#endif -} diff --git a/drivers/staging/ccree/ssi_pm.h b/drivers/staging/ccree/ssi_pm.h deleted file mode 100644 index 63673f60d2d8..000000000000 --- a/drivers/staging/ccree/ssi_pm.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -/* \file ssi_pm.h - */ - -#ifndef __SSI_POWER_MGR_H__ -#define __SSI_POWER_MGR_H__ - -#include "ssi_config.h" -#include "ssi_driver.h" - -#define SSI_SUSPEND_TIMEOUT 3000 - -int ssi_power_mgr_init(struct ssi_drvdata *drvdata); - -void ssi_power_mgr_fini(struct ssi_drvdata *drvdata); - -#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP) -int ssi_power_mgr_runtime_suspend(struct device *dev); - -int ssi_power_mgr_runtime_resume(struct device *dev); - -int ssi_power_mgr_runtime_get(struct device *dev); - -int ssi_power_mgr_runtime_put_suspend(struct device *dev); -#endif - -#endif /*__POWER_MGR_H__*/ - diff --git a/drivers/staging/ccree/ssi_request_mgr.c b/drivers/staging/ccree/ssi_request_mgr.c deleted file mode 100644 index a8a7dc672d4c..000000000000 --- a/drivers/staging/ccree/ssi_request_mgr.c +++ /dev/null @@ -1,610 +0,0 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#include "ssi_config.h" -#include <linux/kernel.h> -#include <linux/platform_device.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <crypto/ctr.h> -#ifdef FLUSH_CACHE_ALL -#include <asm/cacheflush.h> -#endif -#include <linux/pm_runtime.h> -#include "ssi_driver.h" -#include "ssi_buffer_mgr.h" -#include "ssi_request_mgr.h" -#include "ssi_sysfs.h" -#include "ssi_ivgen.h" -#include "ssi_pm.h" - -#define SSI_MAX_POLL_ITER 10 - -struct ssi_request_mgr_handle { - /* Request manager resources */ - unsigned int hw_queue_size; /* HW capability */ - unsigned int min_free_hw_slots; - unsigned int max_used_sw_slots; - struct ssi_crypto_req req_queue[MAX_REQUEST_QUEUE_SIZE]; - u32 req_queue_head; - u32 req_queue_tail; - u32 axi_completed; - u32 q_free_slots; - spinlock_t hw_lock; - struct cc_hw_desc compl_desc; - u8 *dummy_comp_buff; - dma_addr_t dummy_comp_buff_dma; - struct cc_hw_desc monitor_desc; - -#ifdef COMP_IN_WQ - struct workqueue_struct *workq; - struct delayed_work compwork; -#else - struct tasklet_struct comptask; -#endif -#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP) - bool is_runtime_suspended; -#endif -}; - -static void comp_handler(unsigned long devarg); -#ifdef COMP_IN_WQ -static void comp_work_handler(struct work_struct *work); -#endif - -void request_mgr_fini(struct ssi_drvdata *drvdata) -{ - struct ssi_request_mgr_handle *req_mgr_h = drvdata->request_mgr_handle; - struct device *dev = drvdata_to_dev(drvdata); - - if (!req_mgr_h) - return; /* Not allocated */ - - if (req_mgr_h->dummy_comp_buff_dma != 0) { - dma_free_coherent(dev, sizeof(u32), req_mgr_h->dummy_comp_buff, - req_mgr_h->dummy_comp_buff_dma); - } - - dev_dbg(dev, "max_used_hw_slots=%d\n", (req_mgr_h->hw_queue_size - - req_mgr_h->min_free_hw_slots)); - dev_dbg(dev, "max_used_sw_slots=%d\n", req_mgr_h->max_used_sw_slots); - -#ifdef COMP_IN_WQ - flush_workqueue(req_mgr_h->workq); - destroy_workqueue(req_mgr_h->workq); -#else - /* Kill tasklet */ - tasklet_kill(&req_mgr_h->comptask); -#endif - memset(req_mgr_h, 0, sizeof(struct ssi_request_mgr_handle)); - kfree(req_mgr_h); - drvdata->request_mgr_handle = NULL; -} - -int request_mgr_init(struct ssi_drvdata *drvdata) -{ - struct ssi_request_mgr_handle *req_mgr_h; - struct device *dev = drvdata_to_dev(drvdata); - int rc = 0; - - req_mgr_h = kzalloc(sizeof(*req_mgr_h), GFP_KERNEL); - if (!req_mgr_h) { - rc = -ENOMEM; - goto req_mgr_init_err; - } - - drvdata->request_mgr_handle = req_mgr_h; - - spin_lock_init(&req_mgr_h->hw_lock); -#ifdef COMP_IN_WQ - dev_dbg(dev, "Initializing completion workqueue\n"); - req_mgr_h->workq = create_singlethread_workqueue("arm_cc7x_wq"); - if (unlikely(!req_mgr_h->workq)) { - dev_err(dev, "Failed creating work queue\n"); - rc = -ENOMEM; - goto req_mgr_init_err; - } - INIT_DELAYED_WORK(&req_mgr_h->compwork, comp_work_handler); -#else - dev_dbg(dev, "Initializing completion tasklet\n"); - tasklet_init(&req_mgr_h->comptask, comp_handler, (unsigned long)drvdata); -#endif - req_mgr_h->hw_queue_size = cc_ioread(drvdata, - CC_REG(DSCRPTR_QUEUE_SRAM_SIZE)); - dev_dbg(dev, "hw_queue_size=0x%08X\n", req_mgr_h->hw_queue_size); - if (req_mgr_h->hw_queue_size < MIN_HW_QUEUE_SIZE) { - dev_err(dev, "Invalid HW queue size = %u (Min. required is %u)\n", - req_mgr_h->hw_queue_size, MIN_HW_QUEUE_SIZE); - rc = -ENOMEM; - goto req_mgr_init_err; - } - req_mgr_h->min_free_hw_slots = req_mgr_h->hw_queue_size; - req_mgr_h->max_used_sw_slots = 0; - - /* Allocate DMA word for "dummy" completion descriptor use */ - req_mgr_h->dummy_comp_buff = dma_alloc_coherent(dev, sizeof(u32), - &req_mgr_h->dummy_comp_buff_dma, - GFP_KERNEL); - if (!req_mgr_h->dummy_comp_buff) { - dev_err(dev, "Not enough memory to allocate DMA (%zu) dropped buffer\n", - sizeof(u32)); - rc = -ENOMEM; - goto req_mgr_init_err; - } - - /* Init. "dummy" completion descriptor */ - hw_desc_init(&req_mgr_h->compl_desc); - set_din_const(&req_mgr_h->compl_desc, 0, sizeof(u32)); - set_dout_dlli(&req_mgr_h->compl_desc, req_mgr_h->dummy_comp_buff_dma, - sizeof(u32), NS_BIT, 1); - set_flow_mode(&req_mgr_h->compl_desc, BYPASS); - set_queue_last_ind(&req_mgr_h->compl_desc); - - return 0; - -req_mgr_init_err: - request_mgr_fini(drvdata); - return rc; -} - -static inline void enqueue_seq( - void __iomem *cc_base, - struct cc_hw_desc seq[], unsigned int seq_len) -{ - int i; - - for (i = 0; i < seq_len; i++) { - writel_relaxed(seq[i].word[0], (volatile void __iomem *)(cc_base + CC_REG(DSCRPTR_QUEUE_WORD0))); - writel_relaxed(seq[i].word[1], (volatile void __iomem *)(cc_base + CC_REG(DSCRPTR_QUEUE_WORD0))); - writel_relaxed(seq[i].word[2], (volatile void __iomem *)(cc_base + CC_REG(DSCRPTR_QUEUE_WORD0))); - writel_relaxed(seq[i].word[3], (volatile void __iomem *)(cc_base + CC_REG(DSCRPTR_QUEUE_WORD0))); - writel_relaxed(seq[i].word[4], (volatile void __iomem *)(cc_base + CC_REG(DSCRPTR_QUEUE_WORD0))); - wmb(); - writel_relaxed(seq[i].word[5], (volatile void __iomem *)(cc_base + CC_REG(DSCRPTR_QUEUE_WORD0))); -#ifdef DX_DUMP_DESCS - dev_dbg(dev, "desc[%02d]: 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n", - i, seq[i].word[0], seq[i].word[1], seq[i].word[2], - seq[i].word[3], seq[i].word[4], seq[i].word[5]); -#endif - } -} - -/*! - * Completion will take place if and only if user requested completion - * by setting "is_dout = 0" in send_request(). - * - * \param dev - * \param dx_compl_h The completion event to signal - */ -static void request_mgr_complete(struct device *dev, void *dx_compl_h, void __iomem *cc_base) -{ - struct completion *this_compl = dx_compl_h; - - complete(this_compl); -} - -static inline int request_mgr_queues_status_check( - struct ssi_drvdata *drvdata, - struct ssi_request_mgr_handle *req_mgr_h, - unsigned int total_seq_len) -{ - unsigned long poll_queue; - struct device *dev = drvdata_to_dev(drvdata); - - /* SW queue is checked only once as it will not - * be chaned during the poll becasue the spinlock_bh - * is held by the thread - */ - if (unlikely(((req_mgr_h->req_queue_head + 1) & - (MAX_REQUEST_QUEUE_SIZE - 1)) == - req_mgr_h->req_queue_tail)) { - dev_err(dev, "SW FIFO is full. req_queue_head=%d sw_fifo_len=%d\n", - req_mgr_h->req_queue_head, MAX_REQUEST_QUEUE_SIZE); - return -EBUSY; - } - - if ((likely(req_mgr_h->q_free_slots >= total_seq_len))) - return 0; - - /* Wait for space in HW queue. Poll constant num of iterations. */ - for (poll_queue = 0; poll_queue < SSI_MAX_POLL_ITER ; poll_queue++) { - req_mgr_h->q_free_slots = - cc_ioread(drvdata, CC_REG(DSCRPTR_QUEUE_CONTENT)); - if (unlikely(req_mgr_h->q_free_slots < - req_mgr_h->min_free_hw_slots)) { - req_mgr_h->min_free_hw_slots = req_mgr_h->q_free_slots; - } - - if (likely(req_mgr_h->q_free_slots >= total_seq_len)) { - /* If there is enough place return */ - return 0; - } - - dev_dbg(dev, "HW FIFO is full. q_free_slots=%d total_seq_len=%d\n", - req_mgr_h->q_free_slots, total_seq_len); - } - /* No room in the HW queue try again later */ - dev_dbg(dev, "HW FIFO full, timeout. req_queue_head=%d sw_fifo_len=%d q_free_slots=%d total_seq_len=%d\n", - req_mgr_h->req_queue_head, MAX_REQUEST_QUEUE_SIZE, - req_mgr_h->q_free_slots, total_seq_len); - return -EAGAIN; -} - -/*! - * Enqueue caller request to crypto hardware. - * - * \param drvdata - * \param ssi_req The request to enqueue - * \param desc The crypto sequence - * \param len The crypto sequence length - * \param is_dout If "true": completion is handled by the caller - * If "false": this function adds a dummy descriptor completion - * and waits upon completion signal. - * - * \return int Returns -EINPROGRESS if "is_dout=true"; "0" if "is_dout=false" - */ -int send_request( - struct ssi_drvdata *drvdata, struct ssi_crypto_req *ssi_req, - struct cc_hw_desc *desc, unsigned int len, bool is_dout) -{ - void __iomem *cc_base = drvdata->cc_base; - struct ssi_request_mgr_handle *req_mgr_h = drvdata->request_mgr_handle; - unsigned int used_sw_slots; - unsigned int iv_seq_len = 0; - unsigned int total_seq_len = len; /*initial sequence length*/ - struct cc_hw_desc iv_seq[SSI_IVPOOL_SEQ_LEN]; - struct device *dev = drvdata_to_dev(drvdata); - int rc; - unsigned int max_required_seq_len = (total_seq_len + - ((ssi_req->ivgen_dma_addr_len == 0) ? 0 : - SSI_IVPOOL_SEQ_LEN) + - (!is_dout ? 1 : 0)); - -#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP) - rc = ssi_power_mgr_runtime_get(dev); - if (rc != 0) { - dev_err(dev, "ssi_power_mgr_runtime_get returned %x\n", rc); - return rc; - } -#endif - - do { - spin_lock_bh(&req_mgr_h->hw_lock); - - /* Check if there is enough place in the SW/HW queues - * in case iv gen add the max size and in case of no dout add 1 - * for the internal completion descriptor - */ - rc = request_mgr_queues_status_check(drvdata, req_mgr_h, - max_required_seq_len); - if (likely(rc == 0)) - /* There is enough place in the queue */ - break; - /* something wrong release the spinlock*/ - spin_unlock_bh(&req_mgr_h->hw_lock); - - if (rc != -EAGAIN) { - /* Any error other than HW queue full - * (SW queue is full) - */ -#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP) - ssi_power_mgr_runtime_put_suspend(dev); -#endif - return rc; - } - - /* HW queue is full - short sleep */ - msleep(1); - } while (1); - - /* Additional completion descriptor is needed incase caller did not - * enabled any DLLI/MLLI DOUT bit in the given sequence - */ - if (!is_dout) { - init_completion(&ssi_req->seq_compl); - ssi_req->user_cb = request_mgr_complete; - ssi_req->user_arg = &ssi_req->seq_compl; - total_seq_len++; - } - - if (ssi_req->ivgen_dma_addr_len > 0) { - dev_dbg(dev, "Acquire IV from pool into %d DMA addresses %pad, %pad, %pad, IV-size=%u\n", - ssi_req->ivgen_dma_addr_len, - &ssi_req->ivgen_dma_addr[0], - &ssi_req->ivgen_dma_addr[1], - &ssi_req->ivgen_dma_addr[2], - ssi_req->ivgen_size); - - /* Acquire IV from pool */ - rc = ssi_ivgen_getiv(drvdata, ssi_req->ivgen_dma_addr, - ssi_req->ivgen_dma_addr_len, - ssi_req->ivgen_size, iv_seq, &iv_seq_len); - - if (unlikely(rc != 0)) { - dev_err(dev, "Failed to generate IV (rc=%d)\n", rc); - spin_unlock_bh(&req_mgr_h->hw_lock); -#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP) - ssi_power_mgr_runtime_put_suspend(dev); -#endif - return rc; - } - - total_seq_len += iv_seq_len; - } - - used_sw_slots = ((req_mgr_h->req_queue_head - req_mgr_h->req_queue_tail) & (MAX_REQUEST_QUEUE_SIZE - 1)); - if (unlikely(used_sw_slots > req_mgr_h->max_used_sw_slots)) - req_mgr_h->max_used_sw_slots = used_sw_slots; - - /* Enqueue request - must be locked with HW lock*/ - req_mgr_h->req_queue[req_mgr_h->req_queue_head] = *ssi_req; - req_mgr_h->req_queue_head = (req_mgr_h->req_queue_head + 1) & (MAX_REQUEST_QUEUE_SIZE - 1); - /* TODO: Use circ_buf.h ? */ - - dev_dbg(dev, "Enqueue request head=%u\n", req_mgr_h->req_queue_head); - -#ifdef FLUSH_CACHE_ALL - flush_cache_all(); -#endif - - /* STAT_PHASE_4: Push sequence */ - enqueue_seq(cc_base, iv_seq, iv_seq_len); - enqueue_seq(cc_base, desc, len); - enqueue_seq(cc_base, &req_mgr_h->compl_desc, (is_dout ? 0 : 1)); - - if (unlikely(req_mgr_h->q_free_slots < total_seq_len)) { - /* This situation should never occur. Maybe indicating problem - * with resuming power. Set the free slot count to 0 and hope - * for the best. - */ - dev_err(dev, "HW free slot count mismatch."); - req_mgr_h->q_free_slots = 0; - } else { - /* Update the free slots in HW queue */ - req_mgr_h->q_free_slots -= total_seq_len; - } - - spin_unlock_bh(&req_mgr_h->hw_lock); - - if (!is_dout) { - /* Wait upon sequence completion. - * Return "0" -Operation done successfully. - */ - wait_for_completion(&ssi_req->seq_compl); - return 0; - } - /* Operation still in process */ - return -EINPROGRESS; -} - -/*! - * Enqueue caller request to crypto hardware during init process. - * assume this function is not called in middle of a flow, - * since we set QUEUE_LAST_IND flag in the last descriptor. - * - * \param drvdata - * \param desc The crypto sequence - * \param len The crypto sequence length - * - * \return int Returns "0" upon success - */ -int send_request_init( - struct ssi_drvdata *drvdata, struct cc_hw_desc *desc, unsigned int len) -{ - void __iomem *cc_base = drvdata->cc_base; - struct ssi_request_mgr_handle *req_mgr_h = drvdata->request_mgr_handle; - unsigned int total_seq_len = len; /*initial sequence length*/ - int rc = 0; - - /* Wait for space in HW and SW FIFO. Poll for as much as FIFO_TIMEOUT. */ - rc = request_mgr_queues_status_check(drvdata, req_mgr_h, - total_seq_len); - if (unlikely(rc != 0)) - return rc; - - set_queue_last_ind(&desc[(len - 1)]); - - enqueue_seq(cc_base, desc, len); - - /* Update the free slots in HW queue */ - req_mgr_h->q_free_slots = - cc_ioread(drvdata, CC_REG(DSCRPTR_QUEUE_CONTENT)); - - return 0; -} - -void complete_request(struct ssi_drvdata *drvdata) -{ - struct ssi_request_mgr_handle *request_mgr_handle = - drvdata->request_mgr_handle; -#ifdef COMP_IN_WQ - queue_delayed_work(request_mgr_handle->workq, &request_mgr_handle->compwork, 0); -#else - tasklet_schedule(&request_mgr_handle->comptask); -#endif -} - -#ifdef COMP_IN_WQ -static void comp_work_handler(struct work_struct *work) -{ - struct ssi_drvdata *drvdata = - container_of(work, struct ssi_drvdata, compwork.work); - - comp_handler((unsigned long)drvdata); -} -#endif - -static void proc_completions(struct ssi_drvdata *drvdata) -{ - struct ssi_crypto_req *ssi_req; - struct device *dev = drvdata_to_dev(drvdata); - struct ssi_request_mgr_handle *request_mgr_handle = - drvdata->request_mgr_handle; -#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP) - int rc = 0; -#endif - - while (request_mgr_handle->axi_completed) { - request_mgr_handle->axi_completed--; - - /* Dequeue request */ - if (unlikely(request_mgr_handle->req_queue_head == request_mgr_handle->req_queue_tail)) { - /* We are supposed to handle a completion but our - * queue is empty. This is not normal. Return and - * hope for the best. - */ - dev_err(dev, "Request queue is empty head == tail %u\n", - request_mgr_handle->req_queue_head); - break; - } - - ssi_req = &request_mgr_handle->req_queue[request_mgr_handle->req_queue_tail]; - -#ifdef FLUSH_CACHE_ALL - flush_cache_all(); -#endif - -#ifdef COMPLETION_DELAY - /* Delay */ - { - u32 axi_err; - int i; - - dev_info(dev, "Delay\n"); - for (i = 0; i < 1000000; i++) - axi_err = cc_ioread(drvdata, - CC_REG(AXIM_MON_ERR)); - } -#endif /* COMPLETION_DELAY */ - - if (likely(ssi_req->user_cb)) - ssi_req->user_cb(dev, ssi_req->user_arg, - drvdata->cc_base); - request_mgr_handle->req_queue_tail = (request_mgr_handle->req_queue_tail + 1) & (MAX_REQUEST_QUEUE_SIZE - 1); - dev_dbg(dev, "Dequeue request tail=%u\n", - request_mgr_handle->req_queue_tail); - dev_dbg(dev, "Request completed. axi_completed=%d\n", - request_mgr_handle->axi_completed); -#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP) - rc = ssi_power_mgr_runtime_put_suspend(dev); - if (rc != 0) - dev_err(dev, "Failed to set runtime suspension %d\n", - rc); -#endif - } -} - -static inline u32 cc_axi_comp_count(struct ssi_drvdata *drvdata) -{ - return FIELD_GET(AXIM_MON_COMP_VALUE, - cc_ioread(drvdata, CC_REG(AXIM_MON_COMP))); -} - -/* Deferred service handler, run as interrupt-fired tasklet */ -static void comp_handler(unsigned long devarg) -{ - struct ssi_drvdata *drvdata = (struct ssi_drvdata *)devarg; - struct ssi_request_mgr_handle *request_mgr_handle = - drvdata->request_mgr_handle; - - u32 irq; - - irq = (drvdata->irq & SSI_COMP_IRQ_MASK); - - if (irq & SSI_COMP_IRQ_MASK) { - /* To avoid the interrupt from firing as we unmask it, - * we clear it now - */ - cc_iowrite(drvdata, CC_REG(HOST_ICR), SSI_COMP_IRQ_MASK); - - /* Avoid race with above clear: Test completion counter - * once more - */ - request_mgr_handle->axi_completed += - cc_axi_comp_count(drvdata); - - while (request_mgr_handle->axi_completed) { - do { - proc_completions(drvdata); - /* At this point (after proc_completions()), - * request_mgr_handle->axi_completed is 0. - */ - request_mgr_handle->axi_completed = - cc_axi_comp_count(drvdata); - } while (request_mgr_handle->axi_completed > 0); - - cc_iowrite(drvdata, CC_REG(HOST_ICR), - SSI_COMP_IRQ_MASK); - - request_mgr_handle->axi_completed += - cc_axi_comp_count(drvdata); - } - } - /* after verifing that there is nothing to do, - * unmask AXI completion interrupt - */ - cc_iowrite(drvdata, CC_REG(HOST_IMR), - cc_ioread(drvdata, CC_REG(HOST_IMR)) & ~irq); -} - -/* - * resume the queue configuration - no need to take the lock as this happens inside - * the spin lock protection - */ -#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP) -int ssi_request_mgr_runtime_resume_queue(struct ssi_drvdata *drvdata) -{ - struct ssi_request_mgr_handle *request_mgr_handle = drvdata->request_mgr_handle; - - spin_lock_bh(&request_mgr_handle->hw_lock); - request_mgr_handle->is_runtime_suspended = false; - spin_unlock_bh(&request_mgr_handle->hw_lock); - - return 0; -} - -/* - * suspend the queue configuration. Since it is used for the runtime suspend - * only verify that the queue can be suspended. - */ -int ssi_request_mgr_runtime_suspend_queue(struct ssi_drvdata *drvdata) -{ - struct ssi_request_mgr_handle *request_mgr_handle = - drvdata->request_mgr_handle; - - /* lock the send_request */ - spin_lock_bh(&request_mgr_handle->hw_lock); - if (request_mgr_handle->req_queue_head != - request_mgr_handle->req_queue_tail) { - spin_unlock_bh(&request_mgr_handle->hw_lock); - return -EBUSY; - } - request_mgr_handle->is_runtime_suspended = true; - spin_unlock_bh(&request_mgr_handle->hw_lock); - - return 0; -} - -bool ssi_request_mgr_is_queue_runtime_suspend(struct ssi_drvdata *drvdata) -{ - struct ssi_request_mgr_handle *request_mgr_handle = - drvdata->request_mgr_handle; - - return request_mgr_handle->is_runtime_suspended; -} - -#endif - diff --git a/drivers/staging/ccree/ssi_request_mgr.h b/drivers/staging/ccree/ssi_request_mgr.h deleted file mode 100644 index bdbbf89e5367..000000000000 --- a/drivers/staging/ccree/ssi_request_mgr.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -/* \file request_mgr.h - * Request Manager - */ - -#ifndef __REQUEST_MGR_H__ -#define __REQUEST_MGR_H__ - -#include "cc_hw_queue_defs.h" - -int request_mgr_init(struct ssi_drvdata *drvdata); - -/*! - * Enqueue caller request to crypto hardware. - * - * \param drvdata - * \param ssi_req The request to enqueue - * \param desc The crypto sequence - * \param len The crypto sequence length - * \param is_dout If "true": completion is handled by the caller - * If "false": this function adds a dummy descriptor completion - * and waits upon completion signal. - * - * \return int Returns -EINPROGRESS if "is_dout=ture"; "0" if "is_dout=false" - */ -int send_request( - struct ssi_drvdata *drvdata, struct ssi_crypto_req *ssi_req, - struct cc_hw_desc *desc, unsigned int len, bool is_dout); - -int send_request_init( - struct ssi_drvdata *drvdata, struct cc_hw_desc *desc, unsigned int len); - -void complete_request(struct ssi_drvdata *drvdata); - -void request_mgr_fini(struct ssi_drvdata *drvdata); - -#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP) -int ssi_request_mgr_runtime_resume_queue(struct ssi_drvdata *drvdata); - -int ssi_request_mgr_runtime_suspend_queue(struct ssi_drvdata *drvdata); - -bool ssi_request_mgr_is_queue_runtime_suspend(struct ssi_drvdata *drvdata); -#endif - -#endif /*__REQUEST_MGR_H__*/ diff --git a/drivers/staging/ccree/ssi_sram_mgr.h b/drivers/staging/ccree/ssi_sram_mgr.h deleted file mode 100644 index 9ba1d59a0bae..000000000000 --- a/drivers/staging/ccree/ssi_sram_mgr.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef __SSI_SRAM_MGR_H__ -#define __SSI_SRAM_MGR_H__ - -#ifndef SSI_CC_SRAM_SIZE -#define SSI_CC_SRAM_SIZE 4096 -#endif - -struct ssi_drvdata; - -/** - * Address (offset) within CC internal SRAM - */ - -typedef u64 ssi_sram_addr_t; - -#define NULL_SRAM_ADDR ((ssi_sram_addr_t)-1) - -/*! - * Initializes SRAM pool. - * The first X bytes of SRAM are reserved for ROM usage, hence, pool - * starts right after X bytes. - * - * \param drvdata - * - * \return int Zero for success, negative value otherwise. - */ -int ssi_sram_mgr_init(struct ssi_drvdata *drvdata); - -/*! - * Uninits SRAM pool. - * - * \param drvdata - */ -void ssi_sram_mgr_fini(struct ssi_drvdata *drvdata); - -/*! - * Allocated buffer from SRAM pool. - * Note: Caller is responsible to free the LAST allocated buffer. - * This function does not taking care of any fragmentation may occur - * by the order of calls to alloc/free. - * - * \param drvdata - * \param size The requested bytes to allocate - */ -ssi_sram_addr_t ssi_sram_mgr_alloc(struct ssi_drvdata *drvdata, u32 size); - -/** - * ssi_sram_mgr_const2sram_desc() - Create const descriptors sequence to - * set values in given array into SRAM. - * Note: each const value can't exceed word size. - * - * @src: A pointer to array of words to set as consts. - * @dst: The target SRAM buffer to set into - * @nelements: The number of words in "src" array - * @seq: A pointer to the given IN/OUT descriptor sequence - * @seq_len: A pointer to the given IN/OUT sequence length - */ -void ssi_sram_mgr_const2sram_desc( - const u32 *src, ssi_sram_addr_t dst, - unsigned int nelement, - struct cc_hw_desc *seq, unsigned int *seq_len); - -#endif /*__SSI_SRAM_MGR_H__*/ diff --git a/drivers/staging/ccree/ssi_sysfs.c b/drivers/staging/ccree/ssi_sysfs.c deleted file mode 100644 index 5d39f15cdb59..000000000000 --- a/drivers/staging/ccree/ssi_sysfs.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#include <linux/kernel.h> -#include "ssi_config.h" -#include "ssi_driver.h" -#include "cc_crypto_ctx.h" -#include "ssi_sysfs.h" - -#ifdef ENABLE_CC_SYSFS - -static struct ssi_drvdata *sys_get_drvdata(void); - -static ssize_t ssi_sys_regdump_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - struct ssi_drvdata *drvdata = sys_get_drvdata(); - u32 register_value; - int offset = 0; - - register_value = cc_ioread(drvdata, CC_REG(HOST_SIGNATURE)); - offset += scnprintf(buf + offset, PAGE_SIZE - offset, "%s \t(0x%lX)\t 0x%08X\n", "HOST_SIGNATURE ", DX_HOST_SIGNATURE_REG_OFFSET, register_value); - register_value = cc_ioread(drvdata, CC_REG(HOST_IRR)); - offset += scnprintf(buf + offset, PAGE_SIZE - offset, "%s \t(0x%lX)\t 0x%08X\n", "HOST_IRR ", DX_HOST_IRR_REG_OFFSET, register_value); - register_value = cc_ioread(drvdata, CC_REG(HOST_POWER_DOWN_EN)); - offset += scnprintf(buf + offset, PAGE_SIZE - offset, "%s \t(0x%lX)\t 0x%08X\n", "HOST_POWER_DOWN_EN ", DX_HOST_POWER_DOWN_EN_REG_OFFSET, register_value); - register_value = cc_ioread(drvdata, CC_REG(AXIM_MON_ERR)); - offset += scnprintf(buf + offset, PAGE_SIZE - offset, "%s \t(0x%lX)\t 0x%08X\n", "AXIM_MON_ERR ", DX_AXIM_MON_ERR_REG_OFFSET, register_value); - register_value = cc_ioread(drvdata, CC_REG(DSCRPTR_QUEUE_CONTENT)); - offset += scnprintf(buf + offset, PAGE_SIZE - offset, "%s \t(0x%lX)\t 0x%08X\n", "DSCRPTR_QUEUE_CONTENT", DX_DSCRPTR_QUEUE_CONTENT_REG_OFFSET, register_value); - return offset; -} - -static ssize_t ssi_sys_help_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - char *help_str[] = { - "cat reg_dump ", "Print several of CC register values", - }; - int i = 0, offset = 0; - - offset += scnprintf(buf + offset, PAGE_SIZE - offset, "Usage:\n"); - for (i = 0; i < ARRAY_SIZE(help_str); i += 2) - offset += scnprintf(buf + offset, PAGE_SIZE - offset, "%s\t\t%s\n", help_str[i], help_str[i + 1]); - - return offset; -} - -/******************************************************** - * SYSFS objects * - ********************************************************/ -/* - * Structure used to create a directory - * and its attributes in sysfs. - */ -struct sys_dir { - struct kobject *sys_dir_kobj; - struct attribute_group sys_dir_attr_group; - struct attribute **sys_dir_attr_list; - u32 num_of_attrs; - struct ssi_drvdata *drvdata; /* Associated driver context */ -}; - -/* top level directory structures */ -static struct sys_dir sys_top_dir; - -/* TOP LEVEL ATTRIBUTES */ -static struct kobj_attribute ssi_sys_top_level_attrs[] = { - __ATTR(dump_regs, 0444, ssi_sys_regdump_show, NULL), - __ATTR(help, 0444, ssi_sys_help_show, NULL), -#if defined CC_CYCLE_COUNT - __ATTR(stats_host, 0664, ssi_sys_stat_host_db_show, ssi_sys_stats_host_db_clear), - __ATTR(stats_cc, 0664, ssi_sys_stat_cc_db_show, ssi_sys_stats_cc_db_clear), -#endif - -}; - -static struct ssi_drvdata *sys_get_drvdata(void) -{ - /* TODO: supporting multiple SeP devices would require avoiding - * global "top_dir" and finding associated "top_dir" by traversing - * up the tree to the kobject which matches one of the top_dir's - */ - return sys_top_dir.drvdata; -} - -static int sys_init_dir(struct sys_dir *sys_dir, struct ssi_drvdata *drvdata, - struct kobject *parent_dir_kobj, const char *dir_name, - struct kobj_attribute *attrs, u32 num_of_attrs) -{ - int i; - - memset(sys_dir, 0, sizeof(struct sys_dir)); - - sys_dir->drvdata = drvdata; - - /* initialize directory kobject */ - sys_dir->sys_dir_kobj = - kobject_create_and_add(dir_name, parent_dir_kobj); - - if (!(sys_dir->sys_dir_kobj)) - return -ENOMEM; - /* allocate memory for directory's attributes list */ - sys_dir->sys_dir_attr_list = - kcalloc(num_of_attrs + 1, sizeof(struct attribute *), - GFP_KERNEL); - - if (!(sys_dir->sys_dir_attr_list)) { - kobject_put(sys_dir->sys_dir_kobj); - return -ENOMEM; - } - - sys_dir->num_of_attrs = num_of_attrs; - - /* initialize attributes list */ - for (i = 0; i < num_of_attrs; ++i) - sys_dir->sys_dir_attr_list[i] = &attrs[i].attr; - - /* last list entry should be NULL */ - sys_dir->sys_dir_attr_list[num_of_attrs] = NULL; - - sys_dir->sys_dir_attr_group.attrs = sys_dir->sys_dir_attr_list; - - return sysfs_create_group(sys_dir->sys_dir_kobj, - &sys_dir->sys_dir_attr_group); -} - -static void sys_free_dir(struct sys_dir *sys_dir) -{ - if (!sys_dir) - return; - - kfree(sys_dir->sys_dir_attr_list); - - if (sys_dir->sys_dir_kobj) - kobject_put(sys_dir->sys_dir_kobj); -} - -int ssi_sysfs_init(struct kobject *sys_dev_obj, struct ssi_drvdata *drvdata) -{ - int retval; - struct device *dev = drvdata_to_dev(drvdata); - - dev_info(dev, "setup sysfs under %s\n", sys_dev_obj->name); - - /* Initialize top directory */ - retval = sys_init_dir(&sys_top_dir, drvdata, sys_dev_obj, "cc_info", - ssi_sys_top_level_attrs, - ARRAY_SIZE(ssi_sys_top_level_attrs)); - return retval; -} - -void ssi_sysfs_fini(void) -{ - sys_free_dir(&sys_top_dir); -} - -#endif /*ENABLE_CC_SYSFS*/ - diff --git a/drivers/staging/ccree/ssi_sysfs.h b/drivers/staging/ccree/ssi_sysfs.h deleted file mode 100644 index 44ae3d4c40b3..000000000000 --- a/drivers/staging/ccree/ssi_sysfs.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2012-2017 ARM Limited or its affiliates. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -/* \file ssi_sysfs.h - * ARM CryptoCell sysfs APIs - */ - -#ifndef __SSI_SYSFS_H__ -#define __SSI_SYSFS_H__ - -#include <asm/timex.h> - -/* forward declaration */ -struct ssi_drvdata; - -enum stat_phase { - STAT_PHASE_0 = 0, - STAT_PHASE_1, - STAT_PHASE_2, - STAT_PHASE_3, - STAT_PHASE_4, - STAT_PHASE_5, - STAT_PHASE_6, - MAX_STAT_PHASES, -}; - -enum stat_op { - STAT_OP_TYPE_NULL = 0, - STAT_OP_TYPE_ENCODE, - STAT_OP_TYPE_DECODE, - STAT_OP_TYPE_SETKEY, - STAT_OP_TYPE_GENERIC, - MAX_STAT_OP_TYPES, -}; - -int ssi_sysfs_init(struct kobject *sys_dev_obj, struct ssi_drvdata *drvdata); -void ssi_sysfs_fini(void); -void update_host_stat(unsigned int op_type, unsigned int phase, cycles_t result); -void update_cc_stat(unsigned int op_type, unsigned int phase, unsigned int elapsed_cycles); -void display_all_stat_db(void); - -#endif /*__SSI_SYSFS_H__*/ diff --git a/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c b/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c index bf3fe7c61be5..cae7e6e695b0 100644 --- a/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c +++ b/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c @@ -1,21 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Xilinx 'Clocking Wizard' driver * * Copyright (C) 2013 - 2014 Xilinx * * Sören Brinkmann <soren.brinkmann@xilinx.com> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License v2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <linux/platform_device.h> diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h index a1c1081906c5..c0bc413f7fe0 100644 --- a/drivers/staging/comedi/comedi.h +++ b/drivers/staging/comedi/comedi.h @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: LGPL-2.0+ /* * comedi.h * header file for COMEDI user API * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1998-2001 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _COMEDI_H diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index b455ff6714eb..f693c2c0bec3 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi_buf.c * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org> * Copyright (C) 2002 Frank Mori Hess <fmhess@users.sourceforge.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/vmalloc.h> diff --git a/drivers/staging/comedi/comedi_compat32.c b/drivers/staging/comedi/comedi_compat32.c index f356386d833a..97fb9388bc22 100644 --- a/drivers/staging/comedi/comedi_compat32.c +++ b/drivers/staging/comedi/comedi_compat32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/comedi_compat32.c * 32-bit ioctl compatibility for 64-bit comedi kernel module. @@ -7,16 +8,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-2007 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/uaccess.h> diff --git a/drivers/staging/comedi/comedi_compat32.h b/drivers/staging/comedi/comedi_compat32.h index 0127c1f98bbf..3980e6e1bd0d 100644 --- a/drivers/staging/comedi/comedi_compat32.h +++ b/drivers/staging/comedi/comedi_compat32.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/comedi_compat32.h * 32-bit ioctl compatibility for 64-bit comedi kernel module. @@ -7,16 +8,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-2007 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _COMEDI_COMPAT32_H diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 491b54d986eb..ef733847eebe 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/comedi_fops.c * comedi kernel module * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt diff --git a/drivers/staging/comedi/comedi_pci.c b/drivers/staging/comedi/comedi_pci.c index 51e023a1c0ee..126048b03f43 100644 --- a/drivers/staging/comedi/comedi_pci.c +++ b/drivers/staging/comedi/comedi_pci.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi_pci.c * Comedi PCI driver specific functions. * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/comedi/comedi_pci.h b/drivers/staging/comedi/comedi_pci.h index 7dfd892c74b0..647a72441b8a 100644 --- a/drivers/staging/comedi/comedi_pci.h +++ b/drivers/staging/comedi/comedi_pci.h @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi_pci.h * header file for Comedi PCI drivers * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _COMEDI_PCI_H diff --git a/drivers/staging/comedi/comedi_pcmcia.c b/drivers/staging/comedi/comedi_pcmcia.c index cd4742851c08..e16f35eae343 100644 --- a/drivers/staging/comedi/comedi_pcmcia.c +++ b/drivers/staging/comedi/comedi_pcmcia.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi_pcmcia.c * Comedi PCMCIA driver specific functions. * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/comedi/comedi_pcmcia.h b/drivers/staging/comedi/comedi_pcmcia.h index 9e45c7c93278..c7d37b38e730 100644 --- a/drivers/staging/comedi/comedi_pcmcia.h +++ b/drivers/staging/comedi/comedi_pcmcia.h @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi_pcmcia.h * header file for Comedi PCMCIA drivers * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _COMEDI_PCMCIA_H diff --git a/drivers/staging/comedi/comedi_usb.c b/drivers/staging/comedi/comedi_usb.c index 9c946d40b894..c632c2bae722 100644 --- a/drivers/staging/comedi/comedi_usb.c +++ b/drivers/staging/comedi/comedi_usb.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi_usb.c * Comedi USB driver specific functions. * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/comedi/comedi_usb.h b/drivers/staging/comedi/comedi_usb.h index 132154ec792f..50287de7a239 100644 --- a/drivers/staging/comedi/comedi_usb.h +++ b/drivers/staging/comedi/comedi_usb.h @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi_usb.h * header file for USB Comedi drivers * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _COMEDI_USB_H diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 1bb9986f865e..f3474a4ba69e 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedidev.h * header file for kernel-only structures, variables, and constants * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _COMEDIDEV_H @@ -186,23 +177,27 @@ struct comedi_subdevice { unsigned int *chanlist; /* driver-owned chanlist (not used) */ - int (*insn_read)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*insn_write)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*insn_bits)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - int (*insn_config)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_insn *, unsigned int *); - - int (*do_cmd)(struct comedi_device *, struct comedi_subdevice *); - int (*do_cmdtest)(struct comedi_device *, struct comedi_subdevice *, - struct comedi_cmd *); - int (*poll)(struct comedi_device *, struct comedi_subdevice *); - int (*cancel)(struct comedi_device *, struct comedi_subdevice *); + int (*insn_read)(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data); + int (*insn_write)(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data); + int (*insn_bits)(struct comedi_device *dev, struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data); + int (*insn_config)(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data); + + int (*do_cmd)(struct comedi_device *dev, struct comedi_subdevice *s); + int (*do_cmdtest)(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_cmd *cmd); + int (*poll)(struct comedi_device *dev, struct comedi_subdevice *s); + int (*cancel)(struct comedi_device *dev, struct comedi_subdevice *s); /* called when the buffer changes */ - int (*buf_change)(struct comedi_device *, struct comedi_subdevice *); + int (*buf_change)(struct comedi_device *dev, + struct comedi_subdevice *s); void (*munge)(struct comedi_device *dev, struct comedi_subdevice *s, void *data, unsigned int num_bytes, @@ -445,9 +440,9 @@ struct comedi_driver { /* public: */ const char *driver_name; struct module *module; - int (*attach)(struct comedi_device *, struct comedi_devconfig *); - void (*detach)(struct comedi_device *); - int (*auto_attach)(struct comedi_device *, unsigned long); + int (*attach)(struct comedi_device *dev, struct comedi_devconfig *it); + void (*detach)(struct comedi_device *dev); + int (*auto_attach)(struct comedi_device *dev, unsigned long context); unsigned int num_names; const char *const *board_name; int offset; diff --git a/drivers/staging/comedi/comedilib.h b/drivers/staging/comedi/comedilib.h index f9b56396e161..e98cb9752dbc 100644 --- a/drivers/staging/comedi/comedilib.h +++ b/drivers/staging/comedi/comedilib.h @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedilib.h * Header file for kcomedilib * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1998-2001 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _LINUX_COMEDILIB_H diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 0b43db6371c6..e618a87521a3 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * module/drivers.c * functions for manipulating drivers @@ -5,16 +6,6 @@ * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org> * Copyright (C) 2002 Frank Mori Hess <fmhess@users.sourceforge.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/device.h> diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index b79d3764a8a0..3d6105b5a11b 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/8255.c * Driver for 8255 * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1998 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/8255.h b/drivers/staging/comedi/drivers/8255.h index 55a67af5152d..6cd1339ab83e 100644 --- a/drivers/staging/comedi/drivers/8255.h +++ b/drivers/staging/comedi/drivers/8255.h @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * module/8255.h * Header file for 8255 * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1998 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _8255_H diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index 38c05d1ec647..9ed05f962fdb 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * COMEDI driver for generic PCI based 8255 digital i/o boards * Copyright (C) 2012 H Hartley Sweeten <hsweeten@visionengravers.com> @@ -9,16 +10,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index ccd1a91290bf..560649be9d13 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * addi_apci_1032.c * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. @@ -10,16 +11,6 @@ * Fax: +49(0)7223/9493-92 * http://www.addi-data.com * info@addi-data.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. */ /* diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index 63991c49ff23..45ad4ba92f94 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * addi_apci_1500.c * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. @@ -9,16 +10,6 @@ * Fax: +49(0)7223/9493-92 * http://www.addi-data.com * info@addi-data.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. */ #include <linux/module.h> diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index f1f8b1c422a7..6c8213ee1a74 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * addi_apci_1516.c * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. @@ -10,16 +11,6 @@ * Fax: +49(0)7223/9493-92 * http://www.addi-data.com * info@addi-data.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. */ #include <linux/module.h> diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index 9bfb79c2e5c8..10501fe6bb25 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * addi_apci_1564.c * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. @@ -9,16 +10,6 @@ * Fax: +49(0)7223/9493-92 * http://www.addi-data.com * info@addi-data.com - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. */ /* diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c index c63133a12a4e..050d0b4b3209 100644 --- a/drivers/staging/comedi/drivers/addi_apci_16xx.c +++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * addi_apci_16xx.c * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. @@ -10,16 +11,6 @@ * Fax: +49(0)7223/9493-92 * http://www.addi-data.com * info@addi-data.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. */ #include <linux/module.h> diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c index 50f9eb25d7cb..a122f3f3f5ec 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2032.c +++ b/drivers/staging/comedi/drivers/addi_apci_2032.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * addi_apci_2032.c * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. @@ -10,16 +11,6 @@ * Fax: +49(0)7223/9493-92 * http://www.addi-data.com * info@addi-data.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. */ #include <linux/module.h> diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c index 2b382a52d80d..140d1514a106 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2200.c +++ b/drivers/staging/comedi/drivers/addi_apci_2200.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * addi_apci_2200.c * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. @@ -10,16 +11,6 @@ * Fax: +49(0)7223/9493-92 * http://www.addi-data.com * info@addi-data.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. */ #include <linux/module.h> diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 3630d75e36e8..d2810fdd5e63 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * addi_apci_3120.c * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. @@ -9,16 +10,6 @@ * Fax: +49(0)7223/9493-92 * http://www.addi-data.com * info@addi-data.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. */ #include <linux/module.h> diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c index 1fdc0f8d7e1a..a38267928e5e 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3501.c +++ b/drivers/staging/comedi/drivers/addi_apci_3501.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * addi_apci_3501.c * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. @@ -10,16 +11,6 @@ * Fax: +49(0)7223/9493-92 * http://www.addi-data.com * info@addi-data.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. */ /* diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c index be1f6133ff1c..55784f24e2a7 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c +++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * addi_apci_3xxx.c * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. @@ -10,16 +11,6 @@ * Fax: +49(0)7223/9493-92 * http://www.addi-data.com * info@addi-data.com - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. */ #include <linux/module.h> diff --git a/drivers/staging/comedi/drivers/addi_watchdog.c b/drivers/staging/comedi/drivers/addi_watchdog.c index 9d9853fe54a0..69b323fb869f 100644 --- a/drivers/staging/comedi/drivers/addi_watchdog.c +++ b/drivers/staging/comedi/drivers/addi_watchdog.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * COMEDI driver for the watchdog subdevice found on some addi-data boards * Copyright (c) 2013 H Hartley Sweeten <hsweeten@visionengravers.com> @@ -6,16 +7,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1998 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index ad7e7c4a5232..d39b4eabce8d 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * adl_pci6208.c * Comedi driver for ADLink 6208 series cards * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/adl_pci7x3x.c b/drivers/staging/comedi/drivers/adl_pci7x3x.c index b0fc027cf485..d0081897fe47 100644 --- a/drivers/staging/comedi/drivers/adl_pci7x3x.c +++ b/drivers/staging/comedi/drivers/adl_pci7x3x.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * COMEDI driver for the ADLINK PCI-723x/743x series boards. * Copyright (C) 2012 H Hartley Sweeten <hsweeten@visionengravers.com> @@ -9,16 +10,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index da901c8dec0e..3022793b1bc5 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/adl_pci8164.c * * Hardware comedi driver for PCI-8164 Adlink card * Copyright (C) 2004 Michel Lachine <mike@mikelachaine.ca> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 01d2ee931b28..f4dba6271d0d 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * adl_pci9111.c * Hardware driver for PCI9111 ADLink cards: PCI-9111HR * Copyright (C) 2002-2005 Emmanuel Pacaud <emmanuel.pacaud@univ-poitiers.fr> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 1cc9b7ef1ff9..2528ca0ede6d 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * comedi/drivers/adl_pci9118.c * diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c index 315050454c26..5d431573bcca 100644 --- a/drivers/staging/comedi/drivers/adq12b.c +++ b/drivers/staging/comedi/drivers/adq12b.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * adq12b.c * Driver for MicroAxial ADQ12-B data acquisition and control card @@ -9,16 +10,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 2c1b6de30da8..6a93b04f1fdf 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * adv_pci1710.c * Comedi driver for Advantech PCI-1710 series boards diff --git a/drivers/staging/comedi/drivers/adv_pci1720.c b/drivers/staging/comedi/drivers/adv_pci1720.c index 4830a1c93d15..2fcd7e8e7d85 100644 --- a/drivers/staging/comedi/drivers/adv_pci1720.c +++ b/drivers/staging/comedi/drivers/adv_pci1720.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * COMEDI driver for Advantech PCI-1720U * Copyright (c) 2015 H Hartley Sweeten <hsweeten@visionengravers.com> @@ -7,16 +8,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index f82afd947310..771d61f87427 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * adv_pci1723.c * Comedi driver for the Advantech PCI-1723 card. * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/adv_pci1724.c b/drivers/staging/comedi/drivers/adv_pci1724.c index bf6a8f10118c..e8ab573c839f 100644 --- a/drivers/staging/comedi/drivers/adv_pci1724.c +++ b/drivers/staging/comedi/drivers/adv_pci1724.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * adv_pci1724.c * Comedi driver for the Advantech PCI-1724U card. @@ -7,16 +8,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/adv_pci1760.c b/drivers/staging/comedi/drivers/adv_pci1760.c index 9f525ff7290c..f460f21efb90 100644 --- a/drivers/staging/comedi/drivers/adv_pci1760.c +++ b/drivers/staging/comedi/drivers/adv_pci1760.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * COMEDI driver for the Advantech PCI-1760 * Copyright (C) 2015 H Hartley Sweeten <hsweeten@visionengravers.com> @@ -7,16 +8,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* @@ -69,7 +60,7 @@ #define PCI1760_CMD_SET_DO 0x01 /* Set output state */ #define PCI1760_CMD_GET_DO 0x02 /* Read output status */ #define PCI1760_CMD_GET_STATUS 0x03 /* Read current status */ -#define PCI1760_CMD_GET_FW_VER 0x0e /* Read firware version */ +#define PCI1760_CMD_GET_FW_VER 0x0e /* Read firmware version */ #define PCI1760_CMD_GET_HW_VER 0x0f /* Read hardware version */ #define PCI1760_CMD_SET_PWM_HI(x) (0x10 + (x) * 2) /* Set "hi" period */ #define PCI1760_CMD_SET_PWM_LO(x) (0x11 + (x) * 2) /* Set "lo" period */ diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index a8186687ca2c..5fef2aef7e03 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * comedi/drivers/adv_pci_dio.c * diff --git a/drivers/staging/comedi/drivers/aio_aio12_8.c b/drivers/staging/comedi/drivers/aio_aio12_8.c index 43a0ce5721d3..f4beda1ed640 100644 --- a/drivers/staging/comedi/drivers/aio_aio12_8.c +++ b/drivers/staging/comedi/drivers/aio_aio12_8.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * aio_aio12_8.c * Driver for Access I/O Products PC-104 AIO12-8 Analog I/O Board * Copyright (C) 2006 C&C Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c index 35b2f98f0de9..41c9c56816ef 100644 --- a/drivers/staging/comedi/drivers/aio_iiro_16.c +++ b/drivers/staging/comedi/drivers/aio_iiro_16.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * aio_iiro_16.c * Comedi driver for Access I/O Products 104-IIRO-16 board * Copyright (C) 2006 C&C Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index f5cfa71a90c6..26e63d64ffc6 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/amplc_dio200.c * @@ -7,16 +8,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/amplc_dio200.h b/drivers/staging/comedi/drivers/amplc_dio200.h index 53fb86d59fc3..88c1d1063d5d 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.h +++ b/drivers/staging/comedi/drivers/amplc_dio200.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/amplc_dio.h * @@ -8,16 +9,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef AMPLC_DIO200_H_INCLUDED diff --git a/drivers/staging/comedi/drivers/amplc_dio200_common.c b/drivers/staging/comedi/drivers/amplc_dio200_common.c index f6e4e984235d..82bd41d92509 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_common.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_common.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/amplc_dio200_common.c * @@ -7,16 +8,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/comedi/drivers/amplc_dio200_pci.c b/drivers/staging/comedi/drivers/amplc_dio200_pci.c index 2598e6e7d47d..30d239731e0b 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_pci.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_pci.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* comedi/drivers/amplc_dio200_pci.c * * Driver for Amplicon PCI215, PCI272, PCIe215, PCIe236, PCIe296. @@ -6,16 +7,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index 875cc19cb969..b7dd15f5ec63 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/amplc_pc236.c * Driver for Amplicon PC36AT DIO boards. @@ -6,16 +7,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* * Driver: amplc_pc236 diff --git a/drivers/staging/comedi/drivers/amplc_pc236.h b/drivers/staging/comedi/drivers/amplc_pc236.h index 91d6d9c065b5..4b67090aab54 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.h +++ b/drivers/staging/comedi/drivers/amplc_pc236.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/amplc_pc236.h * Header for "amplc_pc236", "amplc_pci236" and "amplc_pc236_common". @@ -6,16 +7,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef AMPLC_PC236_H_INCLUDED diff --git a/drivers/staging/comedi/drivers/amplc_pc236_common.c b/drivers/staging/comedi/drivers/amplc_pc236_common.c index 0c02d3245679..01b90e4eca8a 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236_common.c +++ b/drivers/staging/comedi/drivers/amplc_pc236_common.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/amplc_pc236_common.c * Common support code for "amplc_pc236" and "amplc_pci236". @@ -6,16 +7,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index 58b0b6b1a693..84c989f12faf 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Driver for Amplicon PC263 relay board. * @@ -5,16 +6,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 4e554944bc71..657b736ef46d 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/amplc_pci224.c * Driver for Amplicon PCI224 and PCI234 AO boards. @@ -6,16 +7,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 48c7890c3007..15fc7f19051a 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/amplc_pci230.c * Driver for Amplicon PCI230 and PCI260 Multifunction I/O boards. @@ -6,16 +7,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/amplc_pci236.c b/drivers/staging/comedi/drivers/amplc_pci236.c index 31cc38b4bcad..86ea876a11be 100644 --- a/drivers/staging/comedi/drivers/amplc_pci236.c +++ b/drivers/staging/comedi/drivers/amplc_pci236.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/amplc_pci236.c * Driver for Amplicon PCI236 DIO boards. @@ -6,16 +7,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* * Driver: amplc_pci236 diff --git a/drivers/staging/comedi/drivers/amplc_pci263.c b/drivers/staging/comedi/drivers/amplc_pci263.c index 8d4069bc5716..c3efe14020a8 100644 --- a/drivers/staging/comedi/drivers/amplc_pci263.c +++ b/drivers/staging/comedi/drivers/amplc_pci263.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Driver for Amplicon PCI263 relay board. * @@ -5,16 +6,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/c6xdigio.c b/drivers/staging/comedi/drivers/c6xdigio.c index 8ee732571588..41cc784320a9 100644 --- a/drivers/staging/comedi/drivers/c6xdigio.c +++ b/drivers/staging/comedi/drivers/c6xdigio.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * c6xdigio.c * Hardware driver for Mechatronic Systems Inc. C6x_DIGIO DSP daughter card. @@ -5,16 +6,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1999 Dan Block - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 78d098f9e1f2..a5d171e71c33 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * cb_das16_cs.c * Driver for Computer Boards PC-CARD DAS16/16. @@ -5,16 +6,6 @@ * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000, 2001, 2002 David A. Schleef <ds@schleef.org> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * PCMCIA support code for this driver is adapted from the dummy_cs.c * driver of the Linux PCMCIA Card Services package. * diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 3cd008acb657..8429d57087fd 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * cb_pcidas.c * Developed by Ivan Martinez and Frank Mori Hess, with valuable help from @@ -8,16 +9,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index b761f000c1dc..b657beedd5ff 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/cb_pcidas64.c * This is a driver for the ComputerBoards/MeasurementComputing PCI-DAS @@ -18,16 +19,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 987414741605..807a31e75883 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/cb_pcidda.c * Driver for the ComputerBoards / MeasurementComputing PCI-DDA series. @@ -7,16 +8,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index 47e38398921e..4e72a0778086 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/cb_pcimdas.c * Comedi driver for Computer Boards PCIM-DAS1602/16 and PCIe-DAS1602/16 * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index 84ef45457c60..b33203f6a990 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/cb_pcimdda.c * Computer Boards PCIM-DDA06-16 Comedi driver @@ -5,16 +6,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* * Driver: cb_pcimdda diff --git a/drivers/staging/comedi/drivers/comedi_8254.c b/drivers/staging/comedi/drivers/comedi_8254.c index 0d5d56b61f60..d1d509e9add9 100644 --- a/drivers/staging/comedi/drivers/comedi_8254.c +++ b/drivers/staging/comedi/drivers/comedi_8254.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi_8254.c * Generic 8254 timer/counter support @@ -7,16 +8,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/comedi_8254.h b/drivers/staging/comedi/drivers/comedi_8254.h index 326bd44b063e..7faa2185282e 100644 --- a/drivers/staging/comedi/drivers/comedi_8254.h +++ b/drivers/staging/comedi/drivers/comedi_8254.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi_8254.h * Generic 8254 timer/counter support @@ -5,16 +6,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _COMEDI_8254_H diff --git a/drivers/staging/comedi/drivers/comedi_8255.c b/drivers/staging/comedi/drivers/comedi_8255.c index b2441efc61cc..62baa0d79302 100644 --- a/drivers/staging/comedi/drivers/comedi_8255.c +++ b/drivers/staging/comedi/drivers/comedi_8255.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi_8255.c * Generic 8255 digital I/O support @@ -6,16 +7,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1998 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c index 64a5ea3810d4..4392b5927a99 100644 --- a/drivers/staging/comedi/drivers/comedi_bond.c +++ b/drivers/staging/comedi/drivers/comedi_bond.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi_bond.c * A Comedi driver to 'bond' or merge multiple drivers and devices as one. @@ -5,16 +6,6 @@ * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> * Copyright (C) 2005 Calin A. Culianu <calin@ajvar.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/comedi_isadma.c b/drivers/staging/comedi/drivers/comedi_isadma.c index 68ef9b1750be..b77dc8d5d3ff 100644 --- a/drivers/staging/comedi/drivers/comedi_isadma.c +++ b/drivers/staging/comedi/drivers/comedi_isadma.c @@ -1,16 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * COMEDI ISA DMA support functions * Copyright (c) 2014 H Hartley Sweeten <hsweeten@visionengravers.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/comedi/drivers/comedi_isadma.h b/drivers/staging/comedi/drivers/comedi_isadma.h index a193d3e8d185..ccef7c9c0a4d 100644 --- a/drivers/staging/comedi/drivers/comedi_isadma.h +++ b/drivers/staging/comedi/drivers/comedi_isadma.h @@ -1,16 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * COMEDI ISA DMA support functions * Copyright (c) 2014 H Hartley Sweeten <hsweeten@visionengravers.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _COMEDI_ISADMA_H diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c index 1bf8ddc6f07c..efaa57372aeb 100644 --- a/drivers/staging/comedi/drivers/comedi_parport.c +++ b/drivers/staging/comedi/drivers/comedi_parport.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi_parport.c * Comedi driver for standard parallel port @@ -7,16 +8,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1998,2001 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index c7e8194984e5..d437af721bd8 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/comedi_test.c * @@ -11,16 +12,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index 5f848396c2f7..49be795b4971 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/contec_pci_dio.c * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/dac02.c b/drivers/staging/comedi/drivers/dac02.c index a562df498b01..5ef8114c2c85 100644 --- a/drivers/staging/comedi/drivers/dac02.c +++ b/drivers/staging/comedi/drivers/dac02.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * dac02.c * Comedi driver for DAC02 compatible boards @@ -9,16 +10,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1998 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 32dd8a857b6b..03f98b0287c8 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/daqboard2000.c * hardware driver for IOtech DAQboard/2000 * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1999 Anders Blomdell <anders.blomdell@control.lth.se> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* * Driver: daqboard2000 diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 3d8fc6ad44df..327ecf9aea30 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/das08.c * comedi module for common DAS08 support (used by ISA/PCI/PCMCIA drivers) @@ -6,16 +7,6 @@ * Copyright (C) 2000 David A. Schleef <ds@schleef.org> * Copyright (C) 2001,2002,2003 Frank Mori Hess <fmhess@users.sourceforge.net> * Copyright (C) 2004 Salvador E. Tropea <set@users.sf.net> <set@ieee.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/comedi/drivers/das08.h b/drivers/staging/comedi/drivers/das08.h index d27044cb7158..235d32f7c817 100644 --- a/drivers/staging/comedi/drivers/das08.h +++ b/drivers/staging/comedi/drivers/das08.h @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * das08.h * * Header for common DAS08 support (used by ISA/PCI/PCMCIA drivers) * * Copyright (C) 2003 Frank Mori Hess <fmhess@users.sourceforge.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _DAS08_H diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c index 317a9b5e4a3b..223479f9ea3c 100644 --- a/drivers/staging/comedi/drivers/das08_cs.c +++ b/drivers/staging/comedi/drivers/das08_cs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Comedi driver for DAS008 PCMCIA boards * @@ -5,16 +6,6 @@ * Copyright (C) 2000 David A. Schleef <ds@schleef.org> * Copyright (C) 2001,2002,2003 Frank Mori Hess <fmhess@users.sourceforge.net> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * PCMCIA support code for this driver is adapted from the dummy_cs.c * driver of the Linux PCMCIA Card Services package. * diff --git a/drivers/staging/comedi/drivers/das08_isa.c b/drivers/staging/comedi/drivers/das08_isa.c index cdefc99b6db3..b22a45bd21d1 100644 --- a/drivers/staging/comedi/drivers/das08_isa.c +++ b/drivers/staging/comedi/drivers/das08_isa.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * das08_isa.c * comedi driver for DAS08 ISA/PC-104 boards @@ -6,16 +7,6 @@ * Copyright (C) 2000 David A. Schleef <ds@schleef.org> * Copyright (C) 2001,2002,2003 Frank Mori Hess <fmhess@users.sourceforge.net> * Copyright (C) 2004 Salvador E. Tropea <set@users.sf.net> <set@ieee.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/das08_pci.c b/drivers/staging/comedi/drivers/das08_pci.c index d8d27fa44491..7856fc13466a 100644 --- a/drivers/staging/comedi/drivers/das08_pci.c +++ b/drivers/staging/comedi/drivers/das08_pci.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * das08_pci.c * comedi driver for DAS08 PCI boards @@ -6,16 +7,6 @@ * Copyright (C) 2000 David A. Schleef <ds@schleef.org> * Copyright (C) 2001,2002,2003 Frank Mori Hess <fmhess@users.sourceforge.net> * Copyright (C) 2004 Salvador E. Tropea <set@users.sf.net> <set@ieee.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index ddd4aeab6365..74ff204b585d 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * das16.c * DAS16 driver @@ -6,16 +7,6 @@ * Copyright (C) 2000 David A. Schleef <ds@schleef.org> * Copyright (C) 2000 Chris R. Baugher <baugher@enteract.com> * Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c index bb8d6ec0632e..72f8ed2c5008 100644 --- a/drivers/staging/comedi/drivers/das16m1.c +++ b/drivers/staging/comedi/drivers/das16m1.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Comedi driver for CIO-DAS16/M1 * Author: Frank Mori Hess, based on code from the das16 driver. @@ -5,16 +6,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index e0a34c2687a8..f16aa7e9f4f3 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Comedi driver for Keithley DAS-1700/DAS-1800 series boards * Copyright (C) 2000 Frank Mori Hess <fmhess@users.sourceforge.net> * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c index 0fdf5e02182f..f99211ec46de 100644 --- a/drivers/staging/comedi/drivers/das6402.c +++ b/drivers/staging/comedi/drivers/das6402.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * das6402.c * Comedi driver for DAS6402 compatible boards @@ -5,16 +6,6 @@ * * Rewrite of an experimental driver by: * Copyright (C) 1999 Oystein Svendsen <svendsen@pvv.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c index fd4cb4911671..8cf09ef3012f 100644 --- a/drivers/staging/comedi/drivers/das800.c +++ b/drivers/staging/comedi/drivers/das800.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/das800.c * Driver for Keitley das800 series boards and compatibles @@ -5,16 +6,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* * Driver: das800 diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c index 771cceb71069..75693cdde313 100644 --- a/drivers/staging/comedi/drivers/dmm32at.c +++ b/drivers/staging/comedi/drivers/dmm32at.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * dmm32at.c * Diamond Systems Diamond-MM-32-AT Comedi driver * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c index 30805797a957..a29880981d81 100644 --- a/drivers/staging/comedi/drivers/dt2801.c +++ b/drivers/staging/comedi/drivers/dt2801.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * comedi/drivers/dt2801.c * Device Driver for DataTranslation DT2801 diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c index fcd85475e429..05207a519755 100644 --- a/drivers/staging/comedi/drivers/dt2811.c +++ b/drivers/staging/comedi/drivers/dt2811.c @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Comedi driver for Data Translation DT2811 * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* @@ -316,7 +307,7 @@ static int dt2811_ai_cmd(struct comedi_device *dev, static unsigned int dt2811_ns_to_timer(unsigned int *nanosec, unsigned int flags) { - unsigned long long ns = *nanosec; + unsigned long long ns; unsigned int ns_lo = COMEDI_MIN_SPEED; unsigned int ns_hi = 0; unsigned int divisor_hi = 0; diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c index 09984a66dba3..d2c715737361 100644 --- a/drivers/staging/comedi/drivers/dt2814.c +++ b/drivers/staging/comedi/drivers/dt2814.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/dt2814.c * Hardware driver for Data Translation DT2814 * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1998 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* * Driver: dt2814 diff --git a/drivers/staging/comedi/drivers/dt2815.c b/drivers/staging/comedi/drivers/dt2815.c index ce5571971194..83026ba63d1c 100644 --- a/drivers/staging/comedi/drivers/dt2815.c +++ b/drivers/staging/comedi/drivers/dt2815.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/dt2815.c * Hardware driver for Data Translation DT2815 * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1999 Anders Blomdell <anders.blomdell@control.lth.se> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* * Driver: dt2815 diff --git a/drivers/staging/comedi/drivers/dt2817.c b/drivers/staging/comedi/drivers/dt2817.c index 39d2566e49bf..9babb2a5196a 100644 --- a/drivers/staging/comedi/drivers/dt2817.c +++ b/drivers/staging/comedi/drivers/dt2817.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/dt2817.c * Hardware driver for Data Translation DT2817 * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1998 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* * Driver: dt2817 diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index 217a4b884689..3be927f1d3a9 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * dt282x.c * Comedi driver for Data Translation DT2821 series * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 19e0b7be8495..2edf3ee91300 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * dt3000.c * Data Translation DT3000 series driver * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1999 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c index 7ebca862ecaa..75cc9e8e5b94 100644 --- a/drivers/staging/comedi/drivers/dt9812.c +++ b/drivers/staging/comedi/drivers/dt9812.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/dt9812.c * COMEDI driver for DataTranslation DT9812 USB module @@ -5,16 +6,6 @@ * Copyright (C) 2005 Anders Blomdell <anders.blomdell@control.lth.se> * * COMEDI - Linux Control and Measurement Device Interface - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index bab7ac9e6237..e50536731d11 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -1,16 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/dyna_pci10xx.c * Copyright (C) 2011 Prashant Shah, pshah.mumbai@gmail.com - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/fl512.c b/drivers/staging/comedi/drivers/fl512.c index 0f278ffdad76..41c50c7a8f59 100644 --- a/drivers/staging/comedi/drivers/fl512.c +++ b/drivers/staging/comedi/drivers/fl512.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * fl512.c * Anders Gnistrup <ex18@kalman.iau.dtu.dk> * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index e5b948405fd9..4bdf44d82879 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * gsc_hpdi.c * Comedi driver the General Standards Corporation @@ -8,16 +9,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 28cf53e48b8d..b14aaed6b525 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * icp_multi.c * Comedi driver for Inova ICP_MULTI board * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-2002 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c index 77e1d891f232..3eaf7c59de75 100644 --- a/drivers/staging/comedi/drivers/ii_pci20kc.c +++ b/drivers/staging/comedi/drivers/ii_pci20kc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ii_pci20kc.c * Driver for Intelligent Instruments PCI-20001C carrier board and modules. diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index cbff3b41bb45..201f4f96c182 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/jr3_pci.c * hardware driver for JR3/PCI force sensor board * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2007 Anders Blomdell <anders.blomdell@control.lth.se> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* * Driver: jr3_pci diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c index 93198abf0ee5..e612cf605700 100644 --- a/drivers/staging/comedi/drivers/ke_counter.c +++ b/drivers/staging/comedi/drivers/ke_counter.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * ke_counter.c * Comedi driver for Kolter-Electronic PCI Counter 1 Card * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 15a53204a36a..ee53571a8969 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * me4000.c * Source code for the Meilhaus ME-4000 board family. * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index c0b7a300e428..169742be17b8 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/me_daq.c * Hardware driver for Meilhaus data acquisition cards: * ME-2000i, ME-2600i, ME-3000vm1 * * Copyright (C) 2002 Michael Hillmann <hillmann@syscongroup.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/mf6x4.c b/drivers/staging/comedi/drivers/mf6x4.c index fbdf181d8ccc..ea430237efa7 100644 --- a/drivers/staging/comedi/drivers/mf6x4.c +++ b/drivers/staging/comedi/drivers/mf6x4.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/mf6x4.c * Driver for Humusoft MF634 and MF624 Data acquisition cards * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* * Driver: mf6x4 diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c index 05126ba4ba51..61e03ad84123 100644 --- a/drivers/staging/comedi/drivers/mite.c +++ b/drivers/staging/comedi/drivers/mite.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/mite.c * Hardware driver for NI Mite PCI interface chip * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-2002 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/mite.h b/drivers/staging/comedi/drivers/mite.h index 02a627d3969d..d5e27ac25df8 100644 --- a/drivers/staging/comedi/drivers/mite.h +++ b/drivers/staging/comedi/drivers/mite.h @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * module/mite.h * Hardware driver for NI Mite PCI interface chip * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1999 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _MITE_H_ diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c index 9bda761433c2..bf3a3a08c7ab 100644 --- a/drivers/staging/comedi/drivers/mpc624.c +++ b/drivers/staging/comedi/drivers/mpc624.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * mpc624.c * Hardware driver for a Micro/sys inc. MPC-624 PC/104 board * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/multiq3.c b/drivers/staging/comedi/drivers/multiq3.c index b5a26f7b4332..c85c9ab3655f 100644 --- a/drivers/staging/comedi/drivers/multiq3.c +++ b/drivers/staging/comedi/drivers/multiq3.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * multiq3.c * Hardware driver for Quanser Consulting MultiQ-3 board * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1999 Anders Blomdell <anders.blomdell@control.lth.se> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 84c62e256094..4d1eccb5041d 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * ni_6527.c * Comedi driver for National Instruments PCI-6527 * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1999,2002,2003 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 07f38e385469..996074e471d3 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * ni_65xx.c * Comedi driver for National Instruments PCI-65xx static dio boards @@ -7,16 +8,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1999,2002,2003 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 6aa755ad3953..e521ed9d0887 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -1,15 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Hardware driver for NI 660x devices - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index 1d3ff60efcb8..4e4ae31c8d0b 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Comedi driver for NI 670x devices * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index c69cd676f357..76e8d047f71e 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Comedi driver for National Instruments AT-A2150 boards * Copyright (C) 2001, 2002 Frank Mori Hess <fmhess@users.sourceforge.net> * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/ni_at_ao.c b/drivers/staging/comedi/drivers/ni_at_ao.c index 158fa29374fc..aad0b295ee2b 100644 --- a/drivers/staging/comedi/drivers/ni_at_ao.c +++ b/drivers/staging/comedi/drivers/ni_at_ao.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * ni_at_ao.c * Driver for NI AT-AO-6/10 boards * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000,2002 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/ni_atmio.c b/drivers/staging/comedi/drivers/ni_atmio.c index ae6ed96d7874..b9e9ab548c4b 100644 --- a/drivers/staging/comedi/drivers/ni_atmio.c +++ b/drivers/staging/comedi/drivers/ni_atmio.c @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Comedi driver for NI AT-MIO E series cards * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c index fb59b0ffbba6..68ad9676f962 100644 --- a/drivers/staging/comedi/drivers/ni_atmio16d.c +++ b/drivers/staging/comedi/drivers/ni_atmio16d.c @@ -1,16 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Comedi driver for National Instruments AT-MIO16D board * Copyright (C) 2000 Chris R. Baugher <baugher@enteract.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 8f6396edd21c..b9e525b9beb9 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/ni_daq_700.c * Driver for DAQCard-700 DIO/AI @@ -5,16 +6,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1998 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c index 733d3fbafa4d..44fb65afc218 100644 --- a/drivers/staging/comedi/drivers/ni_daq_dio24.c +++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Comedi driver for National Instruments PCMCIA DAQ-Card DIO-24 * Copyright (C) 2002 Daniel Vecino Castel <dvecino@able.es> @@ -7,16 +8,6 @@ * The initial developer of the pcmcia dummy_cs.c code is David A. Hinds * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 51e5e942b442..c6cf37ccbc92 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/ni_labpc.c * Driver for National Instruments Lab-PC series boards and compatibles * Copyright (C) 2001-2003 Frank Mori Hess <fmhess@users.sourceforge.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/ni_labpc.h b/drivers/staging/comedi/drivers/ni_labpc.h index c2edadc7b3c6..f685047efb67 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.h +++ b/drivers/staging/comedi/drivers/ni_labpc.h @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Header for ni_labpc ISA/PCMCIA/PCI drivers * * Copyright (C) 2003 Frank Mori Hess <fmhess@users.sourceforge.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _NI_LABPC_H diff --git a/drivers/staging/comedi/drivers/ni_labpc_common.c b/drivers/staging/comedi/drivers/ni_labpc_common.c index b0dfb8eed16d..7fa2d39562db 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_common.c +++ b/drivers/staging/comedi/drivers/ni_labpc_common.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/ni_labpc_common.c * * Common support code for "ni_labpc", "ni_labpc_pci" and "ni_labpc_cs". * * Copyright (C) 2001-2003 Frank Mori Hess <fmhess@users.sourceforge.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c index 3d4d0b9ad4e1..4f7e2fe21254 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_cs.c +++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Driver for National Instruments daqcard-1200 boards * Copyright (C) 2001, 2002, 2003 Frank Mori Hess <fmhess@users.sourceforge.net> @@ -7,16 +8,6 @@ * The initial developer of the pcmcia dummy_cs.c code is David A. Hinds * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds * are Copyright (C) 1999 David A. Hinds. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/ni_labpc_isadma.c b/drivers/staging/comedi/drivers/ni_labpc_isadma.c index 29dbdf5ec25d..5657736a9408 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_isadma.c +++ b/drivers/staging/comedi/drivers/ni_labpc_isadma.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/ni_labpc_isadma.c * ISA DMA support for National Instruments Lab-PC series boards and @@ -5,16 +6,6 @@ * * Extracted from ni_labpc.c: * Copyright (C) 2001-2003 Frank Mori Hess <fmhess@users.sourceforge.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/comedi/drivers/ni_labpc_pci.c b/drivers/staging/comedi/drivers/ni_labpc_pci.c index cac089193121..d7d5a7973558 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_pci.c +++ b/drivers/staging/comedi/drivers/ni_labpc_pci.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/ni_labpc_pci.c * Driver for National Instruments Lab-PC PCI-1200 * Copyright (C) 2001, 2002, 2003 Frank Mori Hess <fmhess@users.sourceforge.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 398347fedc47..5d610af6799f 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Hardware driver for DAQ-STC based boards * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org> * Copyright (C) 2002-2006 Frank Mori Hess <fmhess@users.sourceforge.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c index 21f823179356..4f37b4e58f09 100644 --- a/drivers/staging/comedi/drivers/ni_mio_cs.c +++ b/drivers/staging/comedi/drivers/ni_mio_cs.c @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Comedi driver for NI PCMCIA MIO E series cards * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index b27345abebe1..6692af5ff79b 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Comedi driver for National Instruments PCI-DIO-32HS * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1999,2002 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index 3a96913c025e..f9e466d18b3f 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Comedi driver for NI PCI-MIO E series cards * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/ni_stc.h b/drivers/staging/comedi/drivers/ni_stc.h index 61138e86a455..cb9d4c3a1926 100644 --- a/drivers/staging/comedi/drivers/ni_stc.h +++ b/drivers/staging/comedi/drivers/ni_stc.h @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Register descriptions for NI DAQ-STC chip * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1998-9 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c index 15cb4088467b..ef919b21b7d9 100644 --- a/drivers/staging/comedi/drivers/ni_tio.c +++ b/drivers/staging/comedi/drivers/ni_tio.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Support for NI general purpose counters * * Copyright (C) 2006 Frank Mori Hess <fmhess@users.sourceforge.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/ni_tio.h b/drivers/staging/comedi/drivers/ni_tio.h index 2012033414d3..23221cead8ca 100644 --- a/drivers/staging/comedi/drivers/ni_tio.h +++ b/drivers/staging/comedi/drivers/ni_tio.h @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Header file for NI general purpose counter support code (ni_tio.c) * * COMEDI - Linux Control and Measurement Device Interface - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _COMEDI_NI_TIO_H diff --git a/drivers/staging/comedi/drivers/ni_tio_internal.h b/drivers/staging/comedi/drivers/ni_tio_internal.h index 4e024eb5656b..f4d99d78208a 100644 --- a/drivers/staging/comedi/drivers/ni_tio_internal.h +++ b/drivers/staging/comedi/drivers/ni_tio_internal.h @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Header file for NI general purpose counter support code (ni_tio.c and * ni_tiocmd.c) * * COMEDI - Linux Control and Measurement Device Interface - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _COMEDI_NI_TIO_INTERNAL_H diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c index 9007c57544bf..050bee0b9515 100644 --- a/drivers/staging/comedi/drivers/ni_tiocmd.c +++ b/drivers/staging/comedi/drivers/ni_tiocmd.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Command support for NI general purpose counters * * Copyright (C) 2006 Frank Mori Hess <fmhess@users.sourceforge.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/ni_usb6501.c b/drivers/staging/comedi/drivers/ni_usb6501.c index 9a0a96329a55..808ed92ed66f 100644 --- a/drivers/staging/comedi/drivers/ni_usb6501.c +++ b/drivers/staging/comedi/drivers/ni_usb6501.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/ni_usb6501.c * Comedi driver for National Instruments USB-6501 * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2014 Luca Ellero <luca.ellero@brickedbrain.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c index 3774daa9d661..a5937206bf1c 100644 --- a/drivers/staging/comedi/drivers/pcl711.c +++ b/drivers/staging/comedi/drivers/pcl711.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * pcl711.c * Comedi driver for PC-LabCard PCL-711 and AdSys ACL-8112 and compatibles @@ -7,16 +8,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1998 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/pcl724.c b/drivers/staging/comedi/drivers/pcl724.c index 74b07e1744c7..9c174f1f2fcf 100644 --- a/drivers/staging/comedi/drivers/pcl724.c +++ b/drivers/staging/comedi/drivers/pcl724.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * pcl724.c * Comedi driver for 8255 based ISA and PC/104 DIO boards diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c index 256850ccb6fa..0963d85873a9 100644 --- a/drivers/staging/comedi/drivers/pcl726.c +++ b/drivers/staging/comedi/drivers/pcl726.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * pcl726.c * Comedi driver for 6/12-Channel D/A Output and DIO cards * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1998 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/pcl730.c b/drivers/staging/comedi/drivers/pcl730.c index ce958eef2a61..3d1e9150e5b5 100644 --- a/drivers/staging/comedi/drivers/pcl730.c +++ b/drivers/staging/comedi/drivers/pcl730.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * comedi/drivers/pcl730.c * Driver for Advantech PCL-730 and clones diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index 9c75065dd26a..aefc1b849cf7 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * comedi/drivers/pcl812.c * diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index c00a71f538ef..d722079f3327 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * pcl816.c * Comedi driver for Advantech PCL-816 cards diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index 5b5df0596ad9..eebb49751713 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * comedi/drivers/pcl818.c * diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c index 588ae5ecec66..5779e005c0cb 100644 --- a/drivers/staging/comedi/drivers/pcm3724.c +++ b/drivers/staging/comedi/drivers/pcm3724.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * pcm3724.c * Comedi driver for Advantech PCM-3724 Digital I/O board diff --git a/drivers/staging/comedi/drivers/pcmad.c b/drivers/staging/comedi/drivers/pcmad.c index 12f94fe82f5b..fe5449bb1716 100644 --- a/drivers/staging/comedi/drivers/pcmad.c +++ b/drivers/staging/comedi/drivers/pcmad.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * pcmad.c * Hardware driver for Winsystems PCM-A/D12 and PCM-A/D16 * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000,2001 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/pcmda12.c b/drivers/staging/comedi/drivers/pcmda12.c index d86c5e2cd0c7..33e463b193a1 100644 --- a/drivers/staging/comedi/drivers/pcmda12.c +++ b/drivers/staging/comedi/drivers/pcmda12.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * pcmda12.c * Driver for Winsystems PC-104 based PCM-D/A-12 8-channel AO board. * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2006 Calin A. Culianu <calin@ajvar.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index 70ad497dd20b..72af1776f785 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * pcmmio.c * Driver for Winsystems PC-104 based multifunction IO board. * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2007 Calin A. Culianu <calin@ajvar.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index 8ad64f2625fe..743fb226e2e4 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * pcmuio.c * Comedi driver for Winsystems PC-104 based 48/96-channel DIO boards. * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2006 Calin A. Culianu <calin@ajvar.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/plx9052.h b/drivers/staging/comedi/drivers/plx9052.h index 2892e6528967..7950d1f57db6 100644 --- a/drivers/staging/comedi/drivers/plx9052.h +++ b/drivers/staging/comedi/drivers/plx9052.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Definitions for the PLX-9052 PCI interface chip * @@ -5,16 +6,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _PLX9052_H_ diff --git a/drivers/staging/comedi/drivers/plx9080.h b/drivers/staging/comedi/drivers/plx9080.h index e23e63a097b5..469a9573acdc 100644 --- a/drivers/staging/comedi/drivers/plx9080.h +++ b/drivers/staging/comedi/drivers/plx9080.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * plx9080.h * @@ -9,11 +10,6 @@ * Written by Krzysztof Halasa <khc@rgstudio.com.pl> * * Portions (C) SBE Inc., used by permission. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. */ #ifndef __COMEDI_PLX9080_H diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index e00e9c6268ae..bb400e08f0bc 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/rtd520.c * Comedi driver for Real Time Devices (RTD) PCI4520/DM7520 * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2001 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c index cd61d2645af4..f7c320c89ee6 100644 --- a/drivers/staging/comedi/drivers/rti800.c +++ b/drivers/staging/comedi/drivers/rti800.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/rti800.c * Hardware driver for Analog Devices RTI-800/815 board * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1998 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/rti802.c b/drivers/staging/comedi/drivers/rti802.c index 6db58fcfd496..c6cf92bfff73 100644 --- a/drivers/staging/comedi/drivers/rti802.c +++ b/drivers/staging/comedi/drivers/rti802.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * rti802.c * Comedi driver for Analog Devices RTI-802 board * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1999 Anders Blomdell <anders.blomdell@control.lth.se> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index e226275972c0..5d567ae78f28 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * s526.c * Sensoray s526 Comedi driver * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index c906c9a5d944..0b3cfe934e14 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/s626.c * Sensoray s626 Comedi driver @@ -7,16 +8,6 @@ * * Based on Sensoray Model 626 Linux driver Version 0.2 * Copyright (C) 2002-2004 Sensoray Co., Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* @@ -1385,8 +1376,7 @@ static void s626_reset_adc(struct comedi_device *dev, u8 *ppl) jmp_adrs = (u32)devpriv->rps_buf.physical_base + (u32)((unsigned long)rps - - (unsigned long)devpriv-> - rps_buf.logical_base); + (unsigned long)devpriv->rps_buf.logical_base); for (i = 0; i < (10 * S626_RPSCLK_PER_US / 2); i++) { jmp_adrs += 8; /* Repeat to implement time delay: */ /* Jump to next RPS instruction. */ @@ -1903,9 +1893,9 @@ static int s626_ai_cmdtest(struct comedi_device *dev, if (cmd->scan_begin_src == TRIG_TIMER) { arg = cmd->convert_arg * cmd->scan_end_arg; - err |= comedi_check_trigger_arg_min(&cmd-> - scan_begin_arg, - arg); + err |= comedi_check_trigger_arg_min( + &cmd->scan_begin_arg, + arg); } } diff --git a/drivers/staging/comedi/drivers/s626.h b/drivers/staging/comedi/drivers/s626.h index 4cef45263267..4bdc4fba736f 100644 --- a/drivers/staging/comedi/drivers/s626.h +++ b/drivers/staging/comedi/drivers/s626.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/drivers/s626.h * Sensoray s626 Comedi driver, header file @@ -7,16 +8,6 @@ * * Based on Sensoray Model 626 Linux driver Version 0.2 * Copyright (C) 2002-2004 Sensoray Co., Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef S626_H_INCLUDED diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c index a557be8a5076..ab69eeb2c1f1 100644 --- a/drivers/staging/comedi/drivers/serial2002.c +++ b/drivers/staging/comedi/drivers/serial2002.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * serial2002.c * Comedi driver for serial connected hardware * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2002 Anders Blomdell <anders.blomdell@control.lth.se> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* @@ -107,6 +98,7 @@ static long serial2002_tty_ioctl(struct file *f, unsigned int op, static int serial2002_tty_write(struct file *f, unsigned char *buf, int count) { loff_t pos = 0; + return kernel_write(f, buf, count, &pos); } diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c index f9f634fd53cf..0628060e42ca 100644 --- a/drivers/staging/comedi/drivers/ssv_dnp.c +++ b/drivers/staging/comedi/drivers/ssv_dnp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * ssv_dnp.c * generic comedi driver for SSV Embedded Systems' DIL/Net-PCs @@ -5,16 +6,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index f4f05d29d30d..de177418190f 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -1,16 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * usbdux.c * Copyright (C) 2003-2014 Bernd Porr, mail@berndporr.me.uk - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* @@ -809,7 +800,6 @@ static int usbdux_ao_insn_write(struct comedi_device *dev, { struct usbdux_private *devpriv = dev->private; unsigned int chan = CR_CHAN(insn->chanspec); - unsigned int val = s->readback[chan]; __le16 *p = (__le16 *)&devpriv->dux_commands[2]; int ret = -EBUSY; int i; @@ -825,7 +815,7 @@ static int usbdux_ao_insn_write(struct comedi_device *dev, devpriv->dux_commands[4] = chan << 6; for (i = 0; i < insn->n; i++) { - val = data[i]; + unsigned int val = data[i]; /* one 16 bit value */ *p = cpu_to_le16(val); diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 608403c7586b..e18c0723b760 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -1,15 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2004-2014 Bernd Porr, mail@berndporr.me.uk - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index 456e9f13becb..af5605a875e2 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -1,16 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * usbduxsigma.c * Copyright (C) 2011-2015 Bernd Porr, mail@berndporr.me.uk - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c index a004aed0147a..6234b649d887 100644 --- a/drivers/staging/comedi/drivers/vmk80xx.c +++ b/drivers/staging/comedi/drivers/vmk80xx.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * vmk80xx.c * Velleman USB Board Low-Level Driver @@ -6,16 +7,6 @@ * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c index 55d43c076b1c..df9bba1b69ed 100644 --- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c +++ b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * kcomedilib/kcomedilib.c * a comedlib interface for kernel modules * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/comedi/proc.c b/drivers/staging/comedi/proc.c index 2644dd4d6143..50d38938ac6f 100644 --- a/drivers/staging/comedi/proc.c +++ b/drivers/staging/comedi/proc.c @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * /proc interface for comedi * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1998 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ /* diff --git a/drivers/staging/comedi/range.c b/drivers/staging/comedi/range.c index ce3a58a7a171..89d599877445 100644 --- a/drivers/staging/comedi/range.c +++ b/drivers/staging/comedi/range.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * comedi/range.c * comedi routines for voltage ranges * * COMEDI - Linux Control and Measurement Device Interface * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/uaccess.h> diff --git a/drivers/staging/dgnc/Makefile b/drivers/staging/dgnc/Makefile index 40ff0d007695..49633042fcc9 100644 --- a/drivers/staging/dgnc/Makefile +++ b/drivers/staging/dgnc/Makefile @@ -1,5 +1,4 @@ obj-$(CONFIG_DGNC) += dgnc.o dgnc-objs := dgnc_cls.o dgnc_driver.o\ - dgnc_mgmt.o dgnc_neo.o\ - dgnc_tty.o dgnc_utils.o + dgnc_tty.o diff --git a/drivers/staging/dgnc/dgnc_cls.c b/drivers/staging/dgnc/dgnc_cls.c index 9639035fddd1..7e6cbfe4e4ee 100644 --- a/drivers/staging/dgnc/dgnc_cls.c +++ b/drivers/staging/dgnc/dgnc_cls.c @@ -1,16 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright 2003 Digi International (www.digi.com) * Scott H Kilau <Scott_Kilau at digi dot com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. */ #include <linux/kernel.h> @@ -397,7 +388,7 @@ static void cls_assert_modem_signals(struct channel_t *ch) writeb(out, &ch->ch_cls_uart->mcr); /* Give time for the UART to actually drop the signals */ - udelay(10); + usleep_range(10, 20); } static void cls_copy_data_from_queue_to_uart(struct channel_t *ch) @@ -1123,30 +1114,6 @@ static void cls_send_immediate_char(struct channel_t *ch, unsigned char c) writeb(c, &ch->ch_cls_uart->txrx); } -static void cls_vpd(struct dgnc_board *brd) -{ - ulong vpdbase; /* Start of io base of the card */ - u8 __iomem *re_map_vpdbase;/* Remapped memory of the card */ - int i = 0; - - vpdbase = pci_resource_start(brd->pdev, 3); - if (!vpdbase) - return; - - re_map_vpdbase = ioremap(vpdbase, 0x400); - - if (!re_map_vpdbase) - return; - - for (i = 0; i < 0x40; i++) { - brd->vpd[i] = readb(re_map_vpdbase + i); - pr_info("%x ", brd->vpd[i]); - } - pr_info("\n"); - - iounmap(re_map_vpdbase); -} - struct board_ops dgnc_cls_ops = { .tasklet = cls_tasklet, .intr = cls_intr, @@ -1154,7 +1121,6 @@ struct board_ops dgnc_cls_ops = { .uart_off = cls_uart_off, .drain = cls_drain, .param = cls_param, - .vpd = cls_vpd, .assert_modem_signals = cls_assert_modem_signals, .flush_uart_write = cls_flush_uart_write, .flush_uart_read = cls_flush_uart_read, diff --git a/drivers/staging/dgnc/dgnc_cls.h b/drivers/staging/dgnc/dgnc_cls.h index 9dfa9682a897..d31508542261 100644 --- a/drivers/staging/dgnc/dgnc_cls.h +++ b/drivers/staging/dgnc/dgnc_cls.h @@ -1,16 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright 2003 Digi International (www.digi.com) * Scott H Kilau <Scott_Kilau at digi dot com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. */ #ifndef _DGNC_CLS_H diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index d9bf5da1b8e5..5d8c2d995dcc 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -1,16 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright 2003 Digi International (www.digi.com) * Scott H Kilau <Scott_Kilau at digi dot com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. */ #include <linux/kernel.h> @@ -19,37 +10,34 @@ #include <linux/slab.h> #include <linux/sched.h> #include "dgnc_driver.h" -#include "dgnc_pci.h" -#include "dgnc_mgmt.h" #include "dgnc_tty.h" #include "dgnc_cls.h" -#include "dgnc_neo.h" MODULE_LICENSE("GPL"); MODULE_AUTHOR("Digi International, http://www.digi.com"); MODULE_DESCRIPTION("Driver for the Digi International Neo and Classic PCI based product line"); MODULE_SUPPORTED_DEVICE("dgnc"); -static const struct file_operations dgnc_board_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = dgnc_mgmt_ioctl, - .open = dgnc_mgmt_open, - .release = dgnc_mgmt_close -}; - -uint dgnc_num_boards; +static unsigned int dgnc_num_boards; struct dgnc_board *dgnc_board[MAXBOARDS]; -DEFINE_SPINLOCK(dgnc_global_lock); -DEFINE_SPINLOCK(dgnc_poll_lock); /* Poll scheduling lock */ -uint dgnc_major; -int dgnc_poll_tick = 20; /* Poll interval - 20 ms */ - -static struct class *dgnc_class; +static DEFINE_SPINLOCK(dgnc_poll_lock); /* Poll scheduling lock */ +static int dgnc_poll_tick = 20; /* Poll interval - 20 ms */ static ulong dgnc_poll_time; /* Time of next poll */ static uint dgnc_poll_stop; /* Used to tell poller to stop */ static struct timer_list dgnc_poll_timer; +#define DIGI_VID 0x114F +#define PCI_DEVICE_CLASSIC_4_DID 0x0028 +#define PCI_DEVICE_CLASSIC_8_DID 0x0029 +#define PCI_DEVICE_CLASSIC_4_422_DID 0x00D0 +#define PCI_DEVICE_CLASSIC_8_422_DID 0x00D1 + +#define PCI_DEVICE_CLASSIC_4_PCI_NAME "ClassicBoard 4 PCI" +#define PCI_DEVICE_CLASSIC_8_PCI_NAME "ClassicBoard 8 PCI" +#define PCI_DEVICE_CLASSIC_4_422_PCI_NAME "ClassicBoard 4 422 PCI" +#define PCI_DEVICE_CLASSIC_8_422_PCI_NAME "ClassicBoard 8 422 PCI" + static const struct pci_device_id dgnc_pci_tbl[] = { {PCI_DEVICE(DIGI_VID, PCI_DEVICE_CLASSIC_4_DID), .driver_data = 0}, {PCI_DEVICE(DIGI_VID, PCI_DEVICE_CLASSIC_4_422_DID), .driver_data = 1}, @@ -70,19 +58,6 @@ static const struct board_id dgnc_ids[] = { { PCI_DEVICE_CLASSIC_4_422_PCI_NAME, 4, 0 }, { PCI_DEVICE_CLASSIC_8_PCI_NAME, 8, 0 }, { PCI_DEVICE_CLASSIC_8_422_PCI_NAME, 8, 0 }, - { PCI_DEVICE_NEO_4_PCI_NAME, 4, 0 }, - { PCI_DEVICE_NEO_8_PCI_NAME, 8, 0 }, - { PCI_DEVICE_NEO_2DB9_PCI_NAME, 2, 0 }, - { PCI_DEVICE_NEO_2DB9PRI_PCI_NAME, 2, 0 }, - { PCI_DEVICE_NEO_2RJ45_PCI_NAME, 2, 0 }, - { PCI_DEVICE_NEO_2RJ45PRI_PCI_NAME, 2, 0 }, - { PCI_DEVICE_NEO_1_422_PCI_NAME, 1, 0 }, - { PCI_DEVICE_NEO_1_422_485_PCI_NAME, 1, 0 }, - { PCI_DEVICE_NEO_2_422_485_PCI_NAME, 2, 0 }, - { PCI_DEVICE_NEO_EXPRESS_8_PCI_NAME, 8, 1 }, - { PCI_DEVICE_NEO_EXPRESS_4_PCI_NAME, 4, 1 }, - { PCI_DEVICE_NEO_EXPRESS_4RJ45_PCI_NAME, 4, 1 }, - { PCI_DEVICE_NEO_EXPRESS_8RJ45_PCI_NAME, 8, 1 }, { NULL, 0, 0 } }; @@ -101,7 +76,6 @@ static struct dgnc_board *dgnc_found_board(struct pci_dev *pdev, int id) { struct dgnc_board *brd; unsigned int pci_irq; - int i = 0; int rc = 0; brd = kzalloc(sizeof(*brd), GFP_KERNEL); @@ -110,16 +84,10 @@ static struct dgnc_board *dgnc_found_board(struct pci_dev *pdev, int id) /* store the info for the board we've found */ brd->boardnum = dgnc_num_boards; - brd->vendor = dgnc_pci_tbl[id].vendor; brd->device = dgnc_pci_tbl[id].device; brd->pdev = pdev; - brd->pci_bus = pdev->bus->number; - brd->pci_slot = PCI_SLOT(pdev->devfn); brd->name = dgnc_ids[id].name; brd->maxports = dgnc_ids[id].maxports; - if (dgnc_ids[i].is_pci_express) - brd->bd_flags |= BD_IS_PCI_EXPRESS; - brd->dpastatus = BD_NOFEP; init_waitqueue_head(&brd->state_wait); spin_lock_init(&brd->bd_lock); @@ -127,11 +95,6 @@ static struct dgnc_board *dgnc_found_board(struct pci_dev *pdev, int id) brd->state = BOARD_FOUND; - /* store which card & revision we have */ - pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &brd->subvendor); - pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &brd->subdevice); - pci_read_config_byte(pdev, PCI_REVISION_ID, &brd->rev); - pci_irq = pdev->irq; brd->irq = pci_irq; @@ -140,9 +103,6 @@ static struct dgnc_board *dgnc_found_board(struct pci_dev *pdev, int id) case PCI_DEVICE_CLASSIC_8_DID: case PCI_DEVICE_CLASSIC_4_422_DID: case PCI_DEVICE_CLASSIC_8_422_DID: - - brd->dpatype = T_CLASSIC | T_PCIBUS; - /* * For PCI ClassicBoards * PCI Local Address (i.e. "resource" number) space @@ -182,9 +142,6 @@ static struct dgnc_board *dgnc_found_board(struct pci_dev *pdev, int id) if (rc < 0) goto failed; - /* Get and store the board VPD, if it exists */ - brd->bd_ops->vpd(brd); - /* * Enable Local Interrupt 1 (0x1), * Local Interrupt 1 Polarity Active high (0x2), @@ -194,55 +151,6 @@ static struct dgnc_board *dgnc_found_board(struct pci_dev *pdev, int id) break; - case PCI_DEVICE_NEO_4_DID: - case PCI_DEVICE_NEO_8_DID: - case PCI_DEVICE_NEO_2DB9_DID: - case PCI_DEVICE_NEO_2DB9PRI_DID: - case PCI_DEVICE_NEO_2RJ45_DID: - case PCI_DEVICE_NEO_2RJ45PRI_DID: - case PCI_DEVICE_NEO_1_422_DID: - case PCI_DEVICE_NEO_1_422_485_DID: - case PCI_DEVICE_NEO_2_422_485_DID: - case PCI_DEVICE_NEO_EXPRESS_8_DID: - case PCI_DEVICE_NEO_EXPRESS_4_DID: - case PCI_DEVICE_NEO_EXPRESS_4RJ45_DID: - case PCI_DEVICE_NEO_EXPRESS_8RJ45_DID: - - /* - * This chip is set up 100% when we get to it. - * No need to enable global interrupts or anything. - */ - if (brd->bd_flags & BD_IS_PCI_EXPRESS) - brd->dpatype = T_NEO_EXPRESS | T_PCIBUS; - else - brd->dpatype = T_NEO | T_PCIBUS; - - brd->membase = pci_resource_start(pdev, 0); - brd->membase_end = pci_resource_end(pdev, 0); - - if (brd->membase & 1) - brd->membase &= ~3; - else - brd->membase &= ~15; - - brd->bd_ops = &dgnc_neo_ops; - - brd->bd_uart_offset = 0x200; - brd->bd_dividend = 921600; - - rc = dgnc_do_remap(brd); - - if (rc < 0) - goto failed; - - /* Read and store the dvid after remapping */ - brd->dvid = readb(brd->re_map_membase + 0x8D); - - /* Get and store the board VPD, if it exists */ - brd->bd_ops->vpd(brd); - - break; - default: dev_err(&brd->pdev->dev, "Didn't find any compatible Neo/Classic PCI boards.\n"); @@ -273,7 +181,6 @@ static int dgnc_request_irq(struct dgnc_board *brd) dev_err(&brd->pdev->dev, "Failed to hook IRQ %d\n", brd->irq); brd->state = BOARD_FAILED; - brd->dpastatus = BD_NOFEP; return -ENODEV; } } @@ -364,7 +271,6 @@ static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) } brd->state = BOARD_READY; - brd->dpastatus = BD_RUNNING; dgnc_board[dgnc_num_boards++] = brd; @@ -388,32 +294,7 @@ static struct pci_driver dgnc_driver = { static int dgnc_start(void) { - int rc = 0; unsigned long flags; - struct device *dev; - - rc = register_chrdev(0, "dgnc", &dgnc_board_fops); - if (rc < 0) { - pr_err(DRVSTR ": Can't register dgnc driver device (%d)\n", rc); - return rc; - } - dgnc_major = rc; - - dgnc_class = class_create(THIS_MODULE, "dgnc_mgmt"); - if (IS_ERR(dgnc_class)) { - rc = PTR_ERR(dgnc_class); - pr_err(DRVSTR ": Can't create dgnc_mgmt class (%d)\n", rc); - goto failed_class; - } - - dev = device_create(dgnc_class, NULL, - MKDEV(dgnc_major, 0), - NULL, "dgnc_mgmt"); - if (IS_ERR(dev)) { - rc = PTR_ERR(dev); - pr_err(DRVSTR ": Can't create device (%d)\n", rc); - goto failed_device; - } /* Start the poller */ spin_lock_irqsave(&dgnc_poll_lock, flags); @@ -425,13 +306,6 @@ static int dgnc_start(void) add_timer(&dgnc_poll_timer); return 0; - -failed_device: - class_destroy(dgnc_class); -failed_class: - unregister_chrdev(dgnc_major, "dgnc"); - - return rc; } /* Free all the memory associated with a board */ @@ -495,10 +369,6 @@ static void cleanup(void) /* Turn off poller right away. */ del_timer_sync(&dgnc_poll_timer); - device_destroy(dgnc_class, MKDEV(dgnc_major, 0)); - class_destroy(dgnc_class); - unregister_chrdev(dgnc_major, "dgnc"); - for (i = 0; i < dgnc_num_boards; ++i) { dgnc_cleanup_tty(dgnc_board[i]); dgnc_cleanup_board(dgnc_board[i]); diff --git a/drivers/staging/dgnc/dgnc_driver.h b/drivers/staging/dgnc/dgnc_driver.h index efdb11a5e27f..b4d9f714c60a 100644 --- a/drivers/staging/dgnc/dgnc_driver.h +++ b/drivers/staging/dgnc/dgnc_driver.h @@ -1,16 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright 2003 Digi International (www.digi.com) * Scott H Kilau <Scott_Kilau at digi dot com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. */ #ifndef _DGNC_DRIVER_H @@ -82,42 +73,27 @@ struct board_ops { void (*uart_off)(struct channel_t *ch); int (*drain)(struct tty_struct *tty, uint seconds); void (*param)(struct tty_struct *tty); - void (*vpd)(struct dgnc_board *brd); void (*assert_modem_signals)(struct channel_t *ch); void (*flush_uart_write)(struct channel_t *ch); void (*flush_uart_read)(struct channel_t *ch); void (*disable_receiver)(struct channel_t *ch); void (*enable_receiver)(struct channel_t *ch); - void (*send_break)(struct channel_t *ch, int); + void (*send_break)(struct channel_t *ch, int msec); void (*send_start_character)(struct channel_t *ch); void (*send_stop_character)(struct channel_t *ch); void (*copy_data_from_queue_to_uart)(struct channel_t *ch); uint (*get_uart_bytes_left)(struct channel_t *ch); - void (*send_immediate_char)(struct channel_t *ch, unsigned char); + void (*send_immediate_char)(struct channel_t *ch, unsigned char c); }; -/* Device flag definitions for bd_flags. */ - -#define BD_IS_PCI_EXPRESS 0x0001 /* Is a PCI Express board */ - /** * struct dgnc_board - Per board information. * @boardnum: Board number (0 - 32). * * @name: Product name. * @pdev: Pointer to the pci_dev structure. - * @bd_flags: Board flags. - * @vendor: PCI vendor ID. * @device: PCI device ID. - * @subvendor: PCI subsystem vendor ID. - * @subdevice: PCI subsystem device ID. - * @rev: PCI revision ID. - * @pci_bus: PCI bus value. - * @pci_slot: PCI slot value. * @maxports: Maximum ports this board can handle. - * @dvid: Board specific device ID. - * @vpd: VPD of this board, if found. - * @serial_num: Serial number of this board, if found in VPD. * @bd_lock: Used to protect board. * @bd_intr_lock: Protect poller tasklet and interrupt routine from each other. * @state: State of the card. @@ -135,8 +111,6 @@ struct board_ops { * @serial_name: Serial driver name. * @print_dirver: Pointer to the print driver. * @print_name: Print driver name. - * @dpatype: Board type as defined by DPA. - * @dpastatus: Board status as defined by DPA. * @bd_dividend: Board/UART's specific dividend. * @bd_ops: Pointer to board operations structure. */ @@ -144,18 +118,8 @@ struct dgnc_board { int boardnum; char *name; struct pci_dev *pdev; - unsigned long bd_flags; - u16 vendor; u16 device; - u16 subvendor; - u16 subdevice; - unsigned char rev; - uint pci_bus; - uint pci_slot; uint maxports; - unsigned char dvid; - unsigned char vpd[128]; - unsigned char serial_num[20]; /* used to protect the board */ spinlock_t bd_lock; @@ -189,9 +153,6 @@ struct dgnc_board { struct tty_driver *print_driver; char print_name[200]; - u16 dpatype; - u16 dpastatus; - uint bd_dividend; struct board_ops *bd_ops; @@ -285,7 +246,6 @@ struct un_t { * @ch_wopen: Waiting for open process count. * @ch_mostat: FEP output modem status. * @ch_mistat: FEP input modem status. - * @chc_neo_uart: Pointer to the mapped neo UART struct * @ch_cls_uart: Pointer to the mapped cls UART struct * @ch_cached_lsr: Cached value of the LSR register. * @ch_rqueue: Read queue buffer, malloc'ed. @@ -344,7 +304,6 @@ struct channel_t { unsigned char ch_mostat; unsigned char ch_mistat; - struct neo_uart_struct __iomem *ch_neo_uart; struct cls_uart_struct __iomem *ch_cls_uart; unsigned char ch_cached_lsr; @@ -381,11 +340,6 @@ struct channel_t { ulong ch_xoff_sends; }; -extern uint dgnc_major; /* Our driver/mgmt major */ -extern int dgnc_poll_tick; /* Poll interval - 20 ms */ -extern spinlock_t dgnc_global_lock; /* Driver global spinlock */ -extern spinlock_t dgnc_poll_lock; /* Poll scheduling lock */ -extern uint dgnc_num_boards; /* Total number of boards */ extern struct dgnc_board *dgnc_board[MAXBOARDS];/* Array of boards */ #endif /* _DGNC_DRIVER_H */ diff --git a/drivers/staging/dgnc/dgnc_mgmt.c b/drivers/staging/dgnc/dgnc_mgmt.c deleted file mode 100644 index 3ca473b47daf..000000000000 --- a/drivers/staging/dgnc/dgnc_mgmt.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright 2003 Digi International (www.digi.com) - * Scott H Kilau <Scott_Kilau at digi dot com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - */ - -/* - * This file implements the mgmt functionality for the - * Neo and ClassicBoard based product lines. - */ - -#include <linux/kernel.h> -#include <linux/ctype.h> -#include <linux/sched.h> -#include <linux/interrupt.h> -#include <linux/serial_reg.h> -#include <linux/termios.h> -#include <linux/uaccess.h> - -#include "dgnc_driver.h" -#include "dgnc_pci.h" -#include "dgnc_mgmt.h" - -/* Our "in use" variables, to enforce 1 open only */ -static int dgnc_mgmt_in_use[MAXMGMTDEVICES]; - -/** - * dgnc_mgmt_open() - Open the mgmt/downld/dpa device. - */ -int dgnc_mgmt_open(struct inode *inode, struct file *file) -{ - unsigned long flags; - unsigned int minor = iminor(inode); - int rc = 0; - - spin_lock_irqsave(&dgnc_global_lock, flags); - - if (minor >= MAXMGMTDEVICES) { - rc = -ENXIO; - goto out; - } - /* Only allow 1 open at a time on mgmt device */ - if (dgnc_mgmt_in_use[minor]) { - rc = -EBUSY; - goto out; - } - dgnc_mgmt_in_use[minor]++; - -out: - spin_unlock_irqrestore(&dgnc_global_lock, flags); - - return rc; -} - -/** - * dgnc_mgmt_close() - Close the mgmt/dpa device - */ -int dgnc_mgmt_close(struct inode *inode, struct file *file) -{ - unsigned long flags; - unsigned int minor = iminor(inode); - int rc = 0; - - spin_lock_irqsave(&dgnc_global_lock, flags); - - if (minor >= MAXMGMTDEVICES) { - rc = -ENXIO; - goto out; - } - dgnc_mgmt_in_use[minor] = 0; - -out: - spin_unlock_irqrestore(&dgnc_global_lock, flags); - - return rc; -} - -/** - * dgnc_mgmt_ioctl() - Ioctl the mgmt/dpa device. - */ -long dgnc_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - unsigned long flags; - void __user *uarg = (void __user *)arg; - - switch (cmd) { - case DIGI_GETDD: - { - /* - * This returns the total number of boards - * in the system, as well as driver version - * and has space for a reserved entry - */ - struct digi_dinfo ddi; - - spin_lock_irqsave(&dgnc_global_lock, flags); - - memset(&ddi, 0, sizeof(ddi)); - ddi.dinfo_nboards = dgnc_num_boards; - sprintf(ddi.dinfo_version, "%s", DG_PART); - - spin_unlock_irqrestore(&dgnc_global_lock, flags); - - if (copy_to_user(uarg, &ddi, sizeof(ddi))) - return -EFAULT; - - break; - } - - case DIGI_GETBD: - { - int brd; - - struct digi_info di; - - if (copy_from_user(&brd, uarg, sizeof(int))) - return -EFAULT; - - if (brd < 0 || brd >= dgnc_num_boards) - return -ENODEV; - - memset(&di, 0, sizeof(di)); - - di.info_bdnum = brd; - - spin_lock_irqsave(&dgnc_board[brd]->bd_lock, flags); - - di.info_bdtype = dgnc_board[brd]->dpatype; - di.info_bdstate = dgnc_board[brd]->dpastatus; - di.info_ioport = 0; - di.info_physaddr = (ulong)dgnc_board[brd]->membase; - di.info_physsize = (ulong)dgnc_board[brd]->membase - - dgnc_board[brd]->membase_end; - if (dgnc_board[brd]->state != BOARD_FAILED) - di.info_nports = dgnc_board[brd]->nasync; - else - di.info_nports = 0; - - spin_unlock_irqrestore(&dgnc_board[brd]->bd_lock, flags); - - if (copy_to_user(uarg, &di, sizeof(di))) - return -EFAULT; - - break; - } - - case DIGI_GET_NI_INFO: - { - struct channel_t *ch; - struct ni_info ni; - unsigned char mstat = 0; - uint board = 0; - uint channel = 0; - - if (copy_from_user(&ni, uarg, sizeof(ni))) - return -EFAULT; - - board = ni.board; - channel = ni.channel; - - if (board >= dgnc_num_boards) - return -ENODEV; - - if (channel >= dgnc_board[board]->nasync) - return -ENODEV; - - ch = dgnc_board[board]->channels[channel]; - - if (!ch) - return -ENODEV; - - memset(&ni, 0, sizeof(ni)); - ni.board = board; - ni.channel = channel; - - spin_lock_irqsave(&ch->ch_lock, flags); - - mstat = ch->ch_mostat | ch->ch_mistat; - - if (mstat & UART_MCR_DTR) { - ni.mstat |= TIOCM_DTR; - ni.dtr = TIOCM_DTR; - } - if (mstat & UART_MCR_RTS) { - ni.mstat |= TIOCM_RTS; - ni.rts = TIOCM_RTS; - } - if (mstat & UART_MSR_CTS) { - ni.mstat |= TIOCM_CTS; - ni.cts = TIOCM_CTS; - } - if (mstat & UART_MSR_RI) { - ni.mstat |= TIOCM_RI; - ni.ri = TIOCM_RI; - } - if (mstat & UART_MSR_DCD) { - ni.mstat |= TIOCM_CD; - ni.dcd = TIOCM_CD; - } - if (mstat & UART_MSR_DSR) - ni.mstat |= TIOCM_DSR; - - ni.iflag = ch->ch_c_iflag; - ni.oflag = ch->ch_c_oflag; - ni.cflag = ch->ch_c_cflag; - ni.lflag = ch->ch_c_lflag; - - if (ch->ch_digi.digi_flags & CTSPACE || - ch->ch_c_cflag & CRTSCTS) - ni.hflow = 1; - else - ni.hflow = 0; - - if ((ch->ch_flags & CH_STOPI) || - (ch->ch_flags & CH_FORCED_STOPI)) - ni.recv_stopped = 1; - else - ni.recv_stopped = 0; - - if ((ch->ch_flags & CH_STOP) || (ch->ch_flags & CH_FORCED_STOP)) - ni.xmit_stopped = 1; - else - ni.xmit_stopped = 0; - - ni.curtx = ch->ch_txcount; - ni.currx = ch->ch_rxcount; - - ni.baud = ch->ch_old_baud; - - spin_unlock_irqrestore(&ch->ch_lock, flags); - - if (copy_to_user(uarg, &ni, sizeof(ni))) - return -EFAULT; - - break; - } - } - return 0; -} diff --git a/drivers/staging/dgnc/dgnc_mgmt.h b/drivers/staging/dgnc/dgnc_mgmt.h deleted file mode 100644 index a7a5770d7630..000000000000 --- a/drivers/staging/dgnc/dgnc_mgmt.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2003 Digi International (www.digi.com) - * Scott H Kilau <Scott_Kilau at digi dot com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - */ - -#ifndef _DGNC_MGMT_H -#define _DGNC_MGMT_H - -#define MAXMGMTDEVICES 8 - -int dgnc_mgmt_open(struct inode *inode, struct file *file); -int dgnc_mgmt_close(struct inode *inode, struct file *file); -long dgnc_mgmt_ioctl(struct file *file, unsigned int cmd, unsigned long arg); - -#endif /* _DGNC_MGMT_H */ - diff --git a/drivers/staging/dgnc/dgnc_neo.c b/drivers/staging/dgnc/dgnc_neo.c deleted file mode 100644 index 0ae229c3aaaa..000000000000 --- a/drivers/staging/dgnc/dgnc_neo.c +++ /dev/null @@ -1,1690 +0,0 @@ -/* - * Copyright 2003 Digi International (www.digi.com) - * Scott H Kilau <Scott_Kilau at digi dot com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - */ - -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/io.h> -#include <linux/serial.h> -#include <linux/serial_reg.h> - -#include "dgnc_driver.h" -#include "dgnc_neo.h" -#include "dgnc_tty.h" - -static inline void neo_parse_lsr(struct dgnc_board *brd, uint port); -static inline void neo_parse_isr(struct dgnc_board *brd, uint port); -static void neo_copy_data_from_uart_to_queue(struct channel_t *ch); -static inline void neo_clear_break(struct channel_t *ch, int force); -static inline void neo_set_cts_flow_control(struct channel_t *ch); -static inline void neo_set_rts_flow_control(struct channel_t *ch); -static inline void neo_set_ixon_flow_control(struct channel_t *ch); -static inline void neo_set_ixoff_flow_control(struct channel_t *ch); -static inline void neo_set_no_output_flow_control(struct channel_t *ch); -static inline void neo_set_no_input_flow_control(struct channel_t *ch); -static inline void neo_set_new_start_stop_chars(struct channel_t *ch); -static void neo_parse_modem(struct channel_t *ch, unsigned char signals); -static void neo_tasklet(unsigned long data); -static void neo_vpd(struct dgnc_board *brd); -static void neo_uart_init(struct channel_t *ch); -static void neo_uart_off(struct channel_t *ch); -static int neo_drain(struct tty_struct *tty, uint seconds); -static void neo_param(struct tty_struct *tty); -static void neo_assert_modem_signals(struct channel_t *ch); -static void neo_flush_uart_write(struct channel_t *ch); -static void neo_flush_uart_read(struct channel_t *ch); -static void neo_disable_receiver(struct channel_t *ch); -static void neo_enable_receiver(struct channel_t *ch); -static void neo_send_break(struct channel_t *ch, int msecs); -static void neo_send_start_character(struct channel_t *ch); -static void neo_send_stop_character(struct channel_t *ch); -static void neo_copy_data_from_queue_to_uart(struct channel_t *ch); -static uint neo_get_uart_bytes_left(struct channel_t *ch); -static void neo_send_immediate_char(struct channel_t *ch, unsigned char c); -static irqreturn_t neo_intr(int irq, void *voidbrd); - -struct board_ops dgnc_neo_ops = { - .tasklet = neo_tasklet, - .intr = neo_intr, - .uart_init = neo_uart_init, - .uart_off = neo_uart_off, - .drain = neo_drain, - .param = neo_param, - .vpd = neo_vpd, - .assert_modem_signals = neo_assert_modem_signals, - .flush_uart_write = neo_flush_uart_write, - .flush_uart_read = neo_flush_uart_read, - .disable_receiver = neo_disable_receiver, - .enable_receiver = neo_enable_receiver, - .send_break = neo_send_break, - .send_start_character = neo_send_start_character, - .send_stop_character = neo_send_stop_character, - .copy_data_from_queue_to_uart = neo_copy_data_from_queue_to_uart, - .get_uart_bytes_left = neo_get_uart_bytes_left, - .send_immediate_char = neo_send_immediate_char -}; - -/* - * This function allows calls to ensure that all outstanding - * PCI writes have been completed, by doing a PCI read against - * a non-destructive, read-only location on the Neo card. - * - * In this case, we are reading the DVID (Read-only Device Identification) - * value of the Neo card. - */ -static inline void neo_pci_posting_flush(struct dgnc_board *bd) -{ - readb(bd->re_map_membase + 0x8D); -} - -static inline void neo_set_cts_flow_control(struct channel_t *ch) -{ - unsigned char ier = readb(&ch->ch_neo_uart->ier); - unsigned char efr = readb(&ch->ch_neo_uart->efr); - - /* Turn on auto CTS flow control */ - ier |= UART_17158_IER_CTSDSR; - efr |= (UART_17158_EFR_ECB | UART_17158_EFR_CTSDSR); - - /* Turn off auto Xon flow control */ - efr &= ~UART_17158_EFR_IXON; - - /* - * Why? Because Exar's spec says we have to zero it - * out before setting it - */ - writeb(0, &ch->ch_neo_uart->efr); - - /* Turn on UART enhanced bits */ - writeb(efr, &ch->ch_neo_uart->efr); - - /* Turn on table D, with 8 char hi/low watermarks */ - writeb(UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_4DELAY, - &ch->ch_neo_uart->fctr); - - /* Feed the UART our trigger levels */ - writeb(8, &ch->ch_neo_uart->tfifo); - ch->ch_t_tlevel = 8; - - writeb(ier, &ch->ch_neo_uart->ier); - - neo_pci_posting_flush(ch->ch_bd); -} - -static inline void neo_set_rts_flow_control(struct channel_t *ch) -{ - unsigned char ier = readb(&ch->ch_neo_uart->ier); - unsigned char efr = readb(&ch->ch_neo_uart->efr); - - /* Turn on auto RTS flow control */ - ier |= UART_17158_IER_RTSDTR; - efr |= (UART_17158_EFR_ECB | UART_17158_EFR_RTSDTR); - - /* Turn off auto Xoff flow control */ - ier &= ~UART_17158_IER_XOFF; - efr &= ~UART_17158_EFR_IXOFF; - - /* - * Why? Because Exar's spec says we have to zero it - * out before setting it - */ - writeb(0, &ch->ch_neo_uart->efr); - - /* Turn on UART enhanced bits */ - writeb(efr, &ch->ch_neo_uart->efr); - - writeb(UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_4DELAY, - &ch->ch_neo_uart->fctr); - ch->ch_r_watermark = 4; - - writeb(32, &ch->ch_neo_uart->rfifo); - ch->ch_r_tlevel = 32; - - writeb(ier, &ch->ch_neo_uart->ier); - - /* - * From the Neo UART spec sheet: - * The auto RTS/DTR function must be started by asserting - * RTS/DTR# output pin (MCR bit-0 or 1 to logic 1 after - * it is enabled. - */ - ch->ch_mostat |= UART_MCR_RTS; - - neo_pci_posting_flush(ch->ch_bd); -} - -static inline void neo_set_ixon_flow_control(struct channel_t *ch) -{ - unsigned char ier = readb(&ch->ch_neo_uart->ier); - unsigned char efr = readb(&ch->ch_neo_uart->efr); - - /* Turn off auto CTS flow control */ - ier &= ~UART_17158_IER_CTSDSR; - efr &= ~UART_17158_EFR_CTSDSR; - - /* Turn on auto Xon flow control */ - efr |= (UART_17158_EFR_ECB | UART_17158_EFR_IXON); - - /* - * Why? Because Exar's spec says we have to zero it - * out before setting it - */ - writeb(0, &ch->ch_neo_uart->efr); - - /* Turn on UART enhanced bits */ - writeb(efr, &ch->ch_neo_uart->efr); - - writeb(UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY, - &ch->ch_neo_uart->fctr); - ch->ch_r_watermark = 4; - - writeb(32, &ch->ch_neo_uart->rfifo); - ch->ch_r_tlevel = 32; - - /* Tell UART what start/stop chars it should be looking for */ - writeb(ch->ch_startc, &ch->ch_neo_uart->xonchar1); - writeb(0, &ch->ch_neo_uart->xonchar2); - - writeb(ch->ch_stopc, &ch->ch_neo_uart->xoffchar1); - writeb(0, &ch->ch_neo_uart->xoffchar2); - - writeb(ier, &ch->ch_neo_uart->ier); - - neo_pci_posting_flush(ch->ch_bd); -} - -static inline void neo_set_ixoff_flow_control(struct channel_t *ch) -{ - unsigned char ier = readb(&ch->ch_neo_uart->ier); - unsigned char efr = readb(&ch->ch_neo_uart->efr); - - /* Turn off auto RTS flow control */ - ier &= ~UART_17158_IER_RTSDTR; - efr &= ~UART_17158_EFR_RTSDTR; - - /* Turn on auto Xoff flow control */ - ier |= UART_17158_IER_XOFF; - efr |= (UART_17158_EFR_ECB | UART_17158_EFR_IXOFF); - - /* - * Why? Because Exar's spec says we have to zero it - * out before setting it - */ - writeb(0, &ch->ch_neo_uart->efr); - - /* Turn on UART enhanced bits */ - writeb(efr, &ch->ch_neo_uart->efr); - - /* Turn on table D, with 8 char hi/low watermarks */ - writeb(UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY, - &ch->ch_neo_uart->fctr); - - writeb(8, &ch->ch_neo_uart->tfifo); - ch->ch_t_tlevel = 8; - - /* Tell UART what start/stop chars it should be looking for */ - writeb(ch->ch_startc, &ch->ch_neo_uart->xonchar1); - writeb(0, &ch->ch_neo_uart->xonchar2); - - writeb(ch->ch_stopc, &ch->ch_neo_uart->xoffchar1); - writeb(0, &ch->ch_neo_uart->xoffchar2); - - writeb(ier, &ch->ch_neo_uart->ier); - - neo_pci_posting_flush(ch->ch_bd); -} - -static inline void neo_set_no_input_flow_control(struct channel_t *ch) -{ - unsigned char ier = readb(&ch->ch_neo_uart->ier); - unsigned char efr = readb(&ch->ch_neo_uart->efr); - - /* Turn off auto RTS flow control */ - ier &= ~UART_17158_IER_RTSDTR; - efr &= ~UART_17158_EFR_RTSDTR; - - /* Turn off auto Xoff flow control */ - ier &= ~UART_17158_IER_XOFF; - if (ch->ch_c_iflag & IXON) - efr &= ~(UART_17158_EFR_IXOFF); - else - efr &= ~(UART_17158_EFR_ECB | UART_17158_EFR_IXOFF); - - /* - * Why? Because Exar's spec says we have to zero - * it out before setting it - */ - writeb(0, &ch->ch_neo_uart->efr); - - /* Turn on UART enhanced bits */ - writeb(efr, &ch->ch_neo_uart->efr); - - /* Turn on table D, with 8 char hi/low watermarks */ - writeb(UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY, - &ch->ch_neo_uart->fctr); - - ch->ch_r_watermark = 0; - - writeb(16, &ch->ch_neo_uart->tfifo); - ch->ch_t_tlevel = 16; - - writeb(16, &ch->ch_neo_uart->rfifo); - ch->ch_r_tlevel = 16; - - writeb(ier, &ch->ch_neo_uart->ier); - - neo_pci_posting_flush(ch->ch_bd); -} - -static inline void neo_set_no_output_flow_control(struct channel_t *ch) -{ - unsigned char ier = readb(&ch->ch_neo_uart->ier); - unsigned char efr = readb(&ch->ch_neo_uart->efr); - - /* Turn off auto CTS flow control */ - ier &= ~UART_17158_IER_CTSDSR; - efr &= ~UART_17158_EFR_CTSDSR; - - /* Turn off auto Xon flow control */ - if (ch->ch_c_iflag & IXOFF) - efr &= ~UART_17158_EFR_IXON; - else - efr &= ~(UART_17158_EFR_ECB | UART_17158_EFR_IXON); - - /* - * Why? Because Exar's spec says we have to zero it - * out before setting it - */ - writeb(0, &ch->ch_neo_uart->efr); - - /* Turn on UART enhanced bits */ - writeb(efr, &ch->ch_neo_uart->efr); - - /* Turn on table D, with 8 char hi/low watermarks */ - writeb(UART_17158_FCTR_TRGD | UART_17158_FCTR_RTS_8DELAY, - &ch->ch_neo_uart->fctr); - - ch->ch_r_watermark = 0; - - writeb(16, &ch->ch_neo_uart->tfifo); - ch->ch_t_tlevel = 16; - - writeb(16, &ch->ch_neo_uart->rfifo); - ch->ch_r_tlevel = 16; - - writeb(ier, &ch->ch_neo_uart->ier); - - neo_pci_posting_flush(ch->ch_bd); -} - -/* change UARTs start/stop chars */ -static inline void neo_set_new_start_stop_chars(struct channel_t *ch) -{ - /* if hardware flow control is set, then skip this whole thing */ - if (ch->ch_digi.digi_flags & (CTSPACE | RTSPACE) || - ch->ch_c_cflag & CRTSCTS) - return; - - /* Tell UART what start/stop chars it should be looking for */ - writeb(ch->ch_startc, &ch->ch_neo_uart->xonchar1); - writeb(0, &ch->ch_neo_uart->xonchar2); - - writeb(ch->ch_stopc, &ch->ch_neo_uart->xoffchar1); - writeb(0, &ch->ch_neo_uart->xoffchar2); - - neo_pci_posting_flush(ch->ch_bd); -} - -/* No locks are assumed to be held when calling this function. */ -static inline void neo_clear_break(struct channel_t *ch, int force) -{ - unsigned long flags; - - spin_lock_irqsave(&ch->ch_lock, flags); - - if (!ch->ch_stop_sending_break) { - spin_unlock_irqrestore(&ch->ch_lock, flags); - return; - } - - if (ch->ch_flags & CH_BREAK_SENDING) { - if (force || - time_after_eq(jiffies, ch->ch_stop_sending_break)) { - unsigned char temp = readb(&ch->ch_neo_uart->lcr); - - writeb((temp & ~UART_LCR_SBC), &ch->ch_neo_uart->lcr); - neo_pci_posting_flush(ch->ch_bd); - ch->ch_flags &= ~(CH_BREAK_SENDING); - ch->ch_stop_sending_break = 0; - } - } - spin_unlock_irqrestore(&ch->ch_lock, flags); -} - -/* Parse the ISR register. */ -static inline void neo_parse_isr(struct dgnc_board *brd, uint port) -{ - struct channel_t *ch; - unsigned char isr; - unsigned char cause; - unsigned long flags; - - ch = brd->channels[port]; - if (!ch) - return; - - /* Here we try to figure out what caused the interrupt to happen */ - while (1) { - isr = readb(&ch->ch_neo_uart->isr_fcr); - - if (isr & UART_IIR_NO_INT) - break; - - /* - * Yank off the upper 2 bits, - * which just show that the FIFO's are enabled. - */ - isr &= ~(UART_17158_IIR_FIFO_ENABLED); - - if (isr & (UART_17158_IIR_RDI_TIMEOUT | UART_IIR_RDI)) { - /* Read data from uart -> queue */ - neo_copy_data_from_uart_to_queue(ch); - /* - * Call our tty layer to enforce queue - * flow control if needed. - */ - spin_lock_irqsave(&ch->ch_lock, flags); - dgnc_check_queue_flow_control(ch); - spin_unlock_irqrestore(&ch->ch_lock, flags); - } - - if (isr & UART_IIR_THRI) { - spin_lock_irqsave(&ch->ch_lock, flags); - ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); - spin_unlock_irqrestore(&ch->ch_lock, flags); - neo_copy_data_from_queue_to_uart(ch); - } - - if (isr & UART_17158_IIR_XONXOFF) { - cause = readb(&ch->ch_neo_uart->xoffchar1); - - /* - * Since the UART detected either an XON or - * XOFF match, we need to figure out which - * one it was, so we can suspend or resume data flow. - */ - if (cause == UART_17158_XON_DETECT) { - /* resume output if stopped */ - if (brd->channels[port]->ch_flags & CH_STOP) { - spin_lock_irqsave(&ch->ch_lock, - flags); - ch->ch_flags &= ~(CH_STOP); - spin_unlock_irqrestore(&ch->ch_lock, - flags); - } - } else if (cause == UART_17158_XOFF_DETECT) { - if (!(brd->channels[port]->ch_flags & - CH_STOP)) { - spin_lock_irqsave(&ch->ch_lock, - flags); - ch->ch_flags |= CH_STOP; - spin_unlock_irqrestore(&ch->ch_lock, - flags); - } - } - } - - if (isr & UART_17158_IIR_HWFLOW_STATE_CHANGE) { - /* - * If we get here, this means the hardware is - * doing auto flow control. Check to see whether - * RTS/DTR or CTS/DSR caused this interrupt. - */ - cause = readb(&ch->ch_neo_uart->mcr); - /* Which pin is doing auto flow? RTS or DTR? */ - if ((cause & 0x4) == 0) { - if (cause & UART_MCR_RTS) { - spin_lock_irqsave(&ch->ch_lock, - flags); - ch->ch_mostat |= UART_MCR_RTS; - spin_unlock_irqrestore(&ch->ch_lock, - flags); - } else { - spin_lock_irqsave(&ch->ch_lock, - flags); - ch->ch_mostat &= ~(UART_MCR_RTS); - spin_unlock_irqrestore(&ch->ch_lock, - flags); - } - } else { - if (cause & UART_MCR_DTR) { - spin_lock_irqsave(&ch->ch_lock, - flags); - ch->ch_mostat |= UART_MCR_DTR; - spin_unlock_irqrestore(&ch->ch_lock, - flags); - } else { - spin_lock_irqsave(&ch->ch_lock, - flags); - ch->ch_mostat &= ~(UART_MCR_DTR); - spin_unlock_irqrestore(&ch->ch_lock, - flags); - } - } - } - - neo_parse_modem(ch, readb(&ch->ch_neo_uart->msr)); - } -} - -static inline void neo_parse_lsr(struct dgnc_board *brd, uint port) -{ - struct channel_t *ch; - int linestatus; - unsigned long flags; - - if (!brd) - return; - - if (port >= brd->maxports) - return; - - ch = brd->channels[port]; - if (!ch) - return; - - linestatus = readb(&ch->ch_neo_uart->lsr); - - ch->ch_cached_lsr |= linestatus; - - if (ch->ch_cached_lsr & UART_LSR_DR) { - neo_copy_data_from_uart_to_queue(ch); - spin_lock_irqsave(&ch->ch_lock, flags); - dgnc_check_queue_flow_control(ch); - spin_unlock_irqrestore(&ch->ch_lock, flags); - } - - /* - * The next 3 tests should *NOT* happen, as the above test - * should encapsulate all 3... At least, thats what Exar says. - */ - - if (linestatus & UART_LSR_PE) - ch->ch_err_parity++; - - if (linestatus & UART_LSR_FE) - ch->ch_err_frame++; - - if (linestatus & UART_LSR_BI) - ch->ch_err_break++; - - if (linestatus & UART_LSR_OE) { - /* - * Rx Oruns. Exar says that an orun will NOT corrupt - * the FIFO. It will just replace the holding register - * with this new data byte. So basically just ignore this. - * Probably we should eventually have an orun stat in our - * driver... - */ - ch->ch_err_overrun++; - } - - if (linestatus & UART_LSR_THRE) { - spin_lock_irqsave(&ch->ch_lock, flags); - ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); - spin_unlock_irqrestore(&ch->ch_lock, flags); - - neo_copy_data_from_queue_to_uart(ch); - } else if (linestatus & UART_17158_TX_AND_FIFO_CLR) { - spin_lock_irqsave(&ch->ch_lock, flags); - ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); - spin_unlock_irqrestore(&ch->ch_lock, flags); - - neo_copy_data_from_queue_to_uart(ch); - } -} - -/* Send any/all changes to the line to the UART. */ -static void neo_param(struct tty_struct *tty) -{ - unsigned char lcr = 0; - unsigned char uart_lcr = 0; - unsigned char ier = 0; - unsigned char uart_ier = 0; - uint baud = 9600; - int quot = 0; - struct dgnc_board *bd; - struct channel_t *ch; - struct un_t *un; - - if (!tty) - return; - - un = (struct un_t *)tty->driver_data; - if (!un) - return; - - ch = un->un_ch; - if (!ch) - return; - - bd = ch->ch_bd; - if (!bd) - return; - - /* If baud rate is zero, flush queues, and set mval to drop DTR. */ - if ((ch->ch_c_cflag & (CBAUD)) == 0) { - ch->ch_r_head = 0; - ch->ch_r_tail = 0; - ch->ch_e_head = 0; - ch->ch_e_tail = 0; - ch->ch_w_head = 0; - ch->ch_w_tail = 0; - - neo_flush_uart_write(ch); - neo_flush_uart_read(ch); - - /* The baudrate is B0 so all modem lines are to be dropped. */ - ch->ch_flags |= (CH_BAUD0); - ch->ch_mostat &= ~(UART_MCR_RTS | UART_MCR_DTR); - neo_assert_modem_signals(ch); - ch->ch_old_baud = 0; - return; - - } else if (ch->ch_custom_speed) { - baud = ch->ch_custom_speed; - /* Handle transition from B0 */ - if (ch->ch_flags & CH_BAUD0) { - ch->ch_flags &= ~(CH_BAUD0); - - /* - * Bring back up RTS and DTR... - * Also handle RTS or DTR toggle if set. - */ - if (!(ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE)) - ch->ch_mostat |= (UART_MCR_RTS); - if (!(ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE)) - ch->ch_mostat |= (UART_MCR_DTR); - } - } else { - int iindex = 0; - int jindex = 0; - - ulong bauds[4][16] = { - { /* slowbaud */ - 0, 50, 75, 110, - 134, 150, 200, 300, - 600, 1200, 1800, 2400, - 4800, 9600, 19200, 38400 }, - { /* slowbaud & CBAUDEX */ - 0, 57600, 115200, 230400, - 460800, 150, 200, 921600, - 600, 1200, 1800, 2400, - 4800, 9600, 19200, 38400 }, - { /* fastbaud */ - 0, 57600, 76800, 115200, - 131657, 153600, 230400, 460800, - 921600, 1200, 1800, 2400, - 4800, 9600, 19200, 38400 }, - { /* fastbaud & CBAUDEX */ - 0, 57600, 115200, 230400, - 460800, 150, 200, 921600, - 600, 1200, 1800, 2400, - 4800, 9600, 19200, 38400 } - }; - - /* - * Only use the TXPrint baud rate if the terminal unit - * is NOT open - */ - if (!(ch->ch_tun.un_flags & UN_ISOPEN) && - (un->un_type == DGNC_PRINT)) - baud = C_BAUD(ch->ch_pun.un_tty) & 0xff; - else - baud = C_BAUD(ch->ch_tun.un_tty) & 0xff; - - if (ch->ch_c_cflag & CBAUDEX) - iindex = 1; - - if (ch->ch_digi.digi_flags & DIGI_FAST) - iindex += 2; - - jindex = baud; - - if ((iindex >= 0) && (iindex < 4) && - (jindex >= 0) && (jindex < 16)) - baud = bauds[iindex][jindex]; - else - baud = 0; - - if (baud == 0) - baud = 9600; - - /* Handle transition from B0 */ - if (ch->ch_flags & CH_BAUD0) { - ch->ch_flags &= ~(CH_BAUD0); - - /* - * Bring back up RTS and DTR... - * Also handle RTS or DTR toggle if set. - */ - if (!(ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE)) - ch->ch_mostat |= (UART_MCR_RTS); - if (!(ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE)) - ch->ch_mostat |= (UART_MCR_DTR); - } - } - - if (ch->ch_c_cflag & PARENB) - lcr |= UART_LCR_PARITY; - - if (!(ch->ch_c_cflag & PARODD)) - lcr |= UART_LCR_EPAR; - -#ifdef CMSPAR - if (ch->ch_c_cflag & CMSPAR) - lcr |= UART_LCR_SPAR; -#endif - - if (ch->ch_c_cflag & CSTOPB) - lcr |= UART_LCR_STOP; - - switch (ch->ch_c_cflag & CSIZE) { - case CS5: - lcr |= UART_LCR_WLEN5; - break; - case CS6: - lcr |= UART_LCR_WLEN6; - break; - case CS7: - lcr |= UART_LCR_WLEN7; - break; - case CS8: - default: - lcr |= UART_LCR_WLEN8; - break; - } - - uart_ier = readb(&ch->ch_neo_uart->ier); - ier = uart_ier; - - uart_lcr = readb(&ch->ch_neo_uart->lcr); - - if (baud == 0) - baud = 9600; - - quot = ch->ch_bd->bd_dividend / baud; - - if (quot != 0 && ch->ch_old_baud != baud) { - ch->ch_old_baud = baud; - writeb(UART_LCR_DLAB, &ch->ch_neo_uart->lcr); - writeb((quot & 0xff), &ch->ch_neo_uart->txrx); - writeb((quot >> 8), &ch->ch_neo_uart->ier); - writeb(lcr, &ch->ch_neo_uart->lcr); - } - - if (uart_lcr != lcr) - writeb(lcr, &ch->ch_neo_uart->lcr); - - if (ch->ch_c_cflag & CREAD) - ier |= (UART_IER_RDI | UART_IER_RLSI); - else - ier &= ~(UART_IER_RDI | UART_IER_RLSI); - - /* - * Have the UART interrupt on modem signal changes ONLY when - * we are in hardware flow control mode, or CLOCAL/FORCEDCD is not set. - */ - if ((ch->ch_digi.digi_flags & CTSPACE) || - (ch->ch_digi.digi_flags & RTSPACE) || - (ch->ch_c_cflag & CRTSCTS) || - !(ch->ch_digi.digi_flags & DIGI_FORCEDCD) || - !(ch->ch_c_cflag & CLOCAL)) - ier |= UART_IER_MSI; - else - ier &= ~UART_IER_MSI; - - ier |= UART_IER_THRI; - - if (ier != uart_ier) - writeb(ier, &ch->ch_neo_uart->ier); - - neo_set_new_start_stop_chars(ch); - - if (ch->ch_digi.digi_flags & CTSPACE || ch->ch_c_cflag & CRTSCTS) { - neo_set_cts_flow_control(ch); - } else if (ch->ch_c_iflag & IXON) { - if ((ch->ch_startc == _POSIX_VDISABLE) || - (ch->ch_stopc == _POSIX_VDISABLE)) - neo_set_no_output_flow_control(ch); - else - neo_set_ixon_flow_control(ch); - } else { - neo_set_no_output_flow_control(ch); - } - - if (ch->ch_digi.digi_flags & RTSPACE || ch->ch_c_cflag & CRTSCTS) { - neo_set_rts_flow_control(ch); - } else if (ch->ch_c_iflag & IXOFF) { - if ((ch->ch_startc == _POSIX_VDISABLE) || - (ch->ch_stopc == _POSIX_VDISABLE)) - neo_set_no_input_flow_control(ch); - else - neo_set_ixoff_flow_control(ch); - } else { - neo_set_no_input_flow_control(ch); - } - - /* - * Adjust the RX FIFO Trigger level if baud is less than 9600. - * Not exactly elegant, but this is needed because of the Exar chip's - * delay on firing off the RX FIFO interrupt on slower baud rates. - */ - if (baud < 9600) { - writeb(1, &ch->ch_neo_uart->rfifo); - ch->ch_r_tlevel = 1; - } - - neo_assert_modem_signals(ch); - - neo_parse_modem(ch, readb(&ch->ch_neo_uart->msr)); -} - -/* Board poller function. */ -static void neo_tasklet(unsigned long data) -{ - struct dgnc_board *bd = (struct dgnc_board *)data; - struct channel_t *ch; - unsigned long flags; - int i; - int state = 0; - int ports = 0; - - if (!bd) - return; - - spin_lock_irqsave(&bd->bd_lock, flags); - state = bd->state; - ports = bd->nasync; - spin_unlock_irqrestore(&bd->bd_lock, flags); - - /* - * Do NOT allow the interrupt routine to read the intr registers - * Until we release this lock. - */ - spin_lock_irqsave(&bd->bd_intr_lock, flags); - - if ((state == BOARD_READY) && (ports > 0)) { - for (i = 0; i < ports; i++) { - ch = bd->channels[i]; - if (!ch) - continue; - - /* - * NOTE: Remember you CANNOT hold any channel - * locks when calling the input routine. - * - * During input processing, its possible we - * will call the Linux ld, which might in turn, - * do a callback right back into us, resulting - * in us trying to grab the channel lock twice! - */ - dgnc_input(ch); - - /* - * Channel lock is grabbed and then released - * inside both of these routines, but neither - * call anything else that could call back into us. - */ - neo_copy_data_from_queue_to_uart(ch); - dgnc_wakeup_writes(ch); - - dgnc_carrier(ch); - - /* - * Check to see if we need to turn off a sending break. - * The timing check is done inside clear_break() - */ - if (ch->ch_stop_sending_break) - neo_clear_break(ch, 0); - } - } - - spin_unlock_irqrestore(&bd->bd_intr_lock, flags); -} - -/* Neo specific interrupt handler. */ -static irqreturn_t neo_intr(int irq, void *voidbrd) -{ - struct dgnc_board *brd = voidbrd; - struct channel_t *ch; - int port = 0; - int type; - u32 uart_poll; - unsigned long flags; - unsigned long flags2; - - if (!brd) - return IRQ_NONE; - - /* Lock out the slow poller from running on this board. */ - spin_lock_irqsave(&brd->bd_intr_lock, flags); - - /* - * Read in "extended" IRQ information from the 32bit Neo register. - * Bits 0-7: What port triggered the interrupt. - * Bits 8-31: Each 3bits indicate what type of interrupt occurred. - */ - uart_poll = readl(brd->re_map_membase + UART_17158_POLL_ADDR_OFFSET); - - /* - * If 0, no interrupts pending. - * This can happen if the IRQ is shared among a couple Neo/Classic - * boards. - */ - if (!uart_poll) { - spin_unlock_irqrestore(&brd->bd_intr_lock, flags); - return IRQ_NONE; - } - - while ((uart_poll & 0xff) != 0) { - type = uart_poll >> (8 + (port * 3)); - type &= 0x7; - - uart_poll &= ~(0x01 << port); - - switch (type) { - case UART_17158_RXRDY_TIMEOUT: - /* - * RXRDY Time-out is cleared by reading data in the - * RX FIFO until it falls below the trigger level. - */ - - if (port >= brd->nasync) - break; - - ch = brd->channels[port]; - neo_copy_data_from_uart_to_queue(ch); - - /* - * Call our tty layer to enforce queue flow control if - * needed. - */ - spin_lock_irqsave(&ch->ch_lock, flags2); - dgnc_check_queue_flow_control(ch); - spin_unlock_irqrestore(&ch->ch_lock, flags2); - - break; - - case UART_17158_RX_LINE_STATUS: - - /* RXRDY and RX LINE Status (logic OR of LSR[4:1]) */ - - neo_parse_lsr(brd, port); - break; - - case UART_17158_TXRDY: - /* - * TXRDY interrupt clears after reading ISR register - * for the UART channel. - */ - - /* - * Yes, this is odd... - * Why would I check EVERY possibility of type of - * interrupt, when we know its TXRDY??? - * Becuz for some reason, even tho we got triggered for - * TXRDY, it seems to be occasionally wrong. Instead of - * TX, which it should be, I was getting things like - * RXDY too. Weird. - */ - neo_parse_isr(brd, port); - break; - - case UART_17158_MSR: - /* MSR or flow control was seen. */ - neo_parse_isr(brd, port); - break; - - default: - break; - } - - port++; - } - - tasklet_schedule(&brd->helper_tasklet); - - spin_unlock_irqrestore(&brd->bd_intr_lock, flags); - - return IRQ_HANDLED; -} - -/* - * Neo specific way of turning off the receiver. - * Used as a way to enforce queue flow control when in - * hardware flow control mode. - */ -static void neo_disable_receiver(struct channel_t *ch) -{ - unsigned char tmp = readb(&ch->ch_neo_uart->ier); - - tmp &= ~(UART_IER_RDI); - writeb(tmp, &ch->ch_neo_uart->ier); - neo_pci_posting_flush(ch->ch_bd); -} - -/* - * Neo specific way of turning on the receiver. - * Used as a way to un-enforce queue flow control when in - * hardware flow control mode. - */ -static void neo_enable_receiver(struct channel_t *ch) -{ - unsigned char tmp = readb(&ch->ch_neo_uart->ier); - - tmp |= (UART_IER_RDI); - writeb(tmp, &ch->ch_neo_uart->ier); - neo_pci_posting_flush(ch->ch_bd); -} - -static void neo_copy_data_from_uart_to_queue(struct channel_t *ch) -{ - int qleft = 0; - unsigned char linestatus = 0; - unsigned char error_mask = 0; - int n = 0; - int total = 0; - ushort head; - ushort tail; - unsigned long flags; - - if (!ch) - return; - - spin_lock_irqsave(&ch->ch_lock, flags); - - head = ch->ch_r_head & RQUEUEMASK; - tail = ch->ch_r_tail & RQUEUEMASK; - - linestatus = ch->ch_cached_lsr; - ch->ch_cached_lsr = 0; - - qleft = tail - head - 1; - if (qleft < 0) - qleft += RQUEUEMASK + 1; - - if (!(ch->ch_flags & CH_FIFO_ENABLED)) { - /* force the FIFO copy to NOT be run */ - total = 0; - } else { - total = readb(&ch->ch_neo_uart->rfifo); - - /* - * EXAR chip bug - RX FIFO COUNT - Fudge factor. - * - * This resolves a problem/bug with the Exar chip that sometimes - * returns a bogus value in the rfifo register. - * The count can be any where from 0-3 bytes "off". - * Bizarre, but true. - */ - if ((ch->ch_bd->dvid & 0xf0) >= UART_XR17E158_DVID) - total -= 1; - else - total -= 3; - } - - total = min(total, qleft); - - while (total > 0) { - linestatus = readb(&ch->ch_neo_uart->lsr); - - if (linestatus & UART_17158_RX_FIFO_DATA_ERROR) - break; - - /* Make sure we don't go over the end of our queue */ - n = min(((uint)total), (RQUEUESIZE - (uint)head)); - - /* - * Cut down n even further if needed, this is to fix - * a problem with memcpy_fromio() with the Neo on the - * IBM pSeries platform. - * 15 bytes max appears to be the magic number. - */ - n = min_t(uint, n, 12); - - /* - * Since we are grabbing the linestatus register, which - * will reset some bits after our read, we need to ensure - * we don't miss our TX FIFO emptys. - */ - if (linestatus & (UART_LSR_THRE | UART_17158_TX_AND_FIFO_CLR)) - ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); - - linestatus = 0; - - memcpy_fromio(ch->ch_rqueue + head, - &ch->ch_neo_uart->txrxburst, n); - - /* - * Since RX_FIFO_DATA_ERROR was 0, we are guaranteed - * that all the data currently in the FIFO is free of - * breaks and parity/frame/orun errors. - */ - memset(ch->ch_equeue + head, 0, n); - - head = (head + n) & RQUEUEMASK; - total -= n; - qleft -= n; - ch->ch_rxcount += n; - } - - /* - * Create a mask to determine whether we should - * insert the character (if any) into our queue. - */ - if (ch->ch_c_iflag & IGNBRK) - error_mask |= UART_LSR_BI; - - /* - * Now cleanup any leftover bytes still in the UART. - * Also deal with any possible queue overflow here as well. - */ - while (1) { - /* - * Its possible we have a linestatus from the loop above - * this, so we "OR" on any extra bits. - */ - linestatus |= readb(&ch->ch_neo_uart->lsr); - - /* - * If the chip tells us there is no more data pending to - * be read, we can then leave. - * But before we do, cache the linestatus, just in case. - */ - if (!(linestatus & UART_LSR_DR)) { - ch->ch_cached_lsr = linestatus; - break; - } - - /* No need to store this bit */ - linestatus &= ~UART_LSR_DR; - - /* - * Since we are grabbing the linestatus register, which - * will reset some bits after our read, we need to ensure - * we don't miss our TX FIFO emptys. - */ - if (linestatus & (UART_LSR_THRE | UART_17158_TX_AND_FIFO_CLR)) { - linestatus &= ~(UART_LSR_THRE | - UART_17158_TX_AND_FIFO_CLR); - ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); - } - - if (linestatus & error_mask) { - unsigned char discard; - - linestatus = 0; - memcpy_fromio(&discard, &ch->ch_neo_uart->txrxburst, 1); - continue; - } - - /* - * If our queue is full, we have no choice but to drop - * some data. The assumption is that HWFLOW or SWFLOW - * should have stopped things way way before we got to - * this point. - */ - while (qleft < 1) { - tail = (tail + 1) & RQUEUEMASK; - ch->ch_r_tail = tail; - ch->ch_err_overrun++; - qleft++; - } - - memcpy_fromio(ch->ch_rqueue + head, - &ch->ch_neo_uart->txrxburst, 1); - ch->ch_equeue[head] = (unsigned char)linestatus; - - linestatus = 0; - - head = (head + 1) & RQUEUEMASK; - - qleft--; - ch->ch_rxcount++; - } - - ch->ch_r_head = head & RQUEUEMASK; - ch->ch_e_head = head & EQUEUEMASK; - - spin_unlock_irqrestore(&ch->ch_lock, flags); -} - -/* - * This function basically goes to sleep for secs, or until - * it gets signalled that the port has fully drained. - */ -static int neo_drain(struct tty_struct *tty, uint seconds) -{ - unsigned long flags; - struct channel_t *ch; - struct un_t *un; - - if (!tty) - return -ENXIO; - - un = (struct un_t *)tty->driver_data; - if (!un) - return -ENXIO; - - ch = un->un_ch; - if (!ch) - return -ENXIO; - - spin_lock_irqsave(&ch->ch_lock, flags); - un->un_flags |= UN_EMPTY; - spin_unlock_irqrestore(&ch->ch_lock, flags); - - /* If returned value is non-zero, user ctrl-c'ed us */ - return wait_event_interruptible_timeout(un->un_flags_wait, - ((un->un_flags & UN_EMPTY) == 0), - msecs_to_jiffies(seconds * 1000)); -} - -/* - * Flush the WRITE FIFO on the Neo. - * Channel lock MUST be held before calling this function! - */ -static void neo_flush_uart_write(struct channel_t *ch) -{ - unsigned char tmp = 0; - int i = 0; - - if (!ch) - return; - - writeb((UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_XMIT), - &ch->ch_neo_uart->isr_fcr); - neo_pci_posting_flush(ch->ch_bd); - - for (i = 0; i < 10; i++) { - /* - * Check to see if the UART completely flushed the FIFO - * FIFO. - */ - tmp = readb(&ch->ch_neo_uart->isr_fcr); - if (tmp & 4) - udelay(10); - else - break; - } - - ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); -} - -/* - * Flush the READ FIFO on the Neo. - * Channel lock MUST be held before calling this function! - */ -static void neo_flush_uart_read(struct channel_t *ch) -{ - unsigned char tmp = 0; - int i = 0; - - if (!ch) - return; - - writeb(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR, - &ch->ch_neo_uart->isr_fcr); - neo_pci_posting_flush(ch->ch_bd); - - for (i = 0; i < 10; i++) { - /* - * Check to see if the UART feels it completely flushed the - * FIFO. - */ - tmp = readb(&ch->ch_neo_uart->isr_fcr); - if (tmp & 2) - udelay(10); - else - break; - } -} - -static void neo_copy_data_from_queue_to_uart(struct channel_t *ch) -{ - ushort head; - ushort tail; - int n; - int s; - int qlen; - uint len_written = 0; - unsigned long flags; - - if (!ch) - return; - - spin_lock_irqsave(&ch->ch_lock, flags); - - if (ch->ch_w_tail == ch->ch_w_head) - goto exit_unlock; - - /* If port is "stopped", don't send any data to the UART */ - if ((ch->ch_flags & CH_FORCED_STOP) || - (ch->ch_flags & CH_BREAK_SENDING)) - goto exit_unlock; - - if (!(ch->ch_flags & CH_FIFO_ENABLED)) { - /* Send data directly to txrx register */ - unsigned char lsrbits = readb(&ch->ch_neo_uart->lsr); - - ch->ch_cached_lsr |= lsrbits; - if (ch->ch_cached_lsr & UART_LSR_THRE) { - ch->ch_cached_lsr &= ~(UART_LSR_THRE); - - /* - * If RTS Toggle mode is on, turn on RTS now if not - * already set, and make sure we get an event when the - * data transfer has completed. - */ - if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) { - if (!(ch->ch_mostat & UART_MCR_RTS)) { - ch->ch_mostat |= (UART_MCR_RTS); - neo_assert_modem_signals(ch); - } - ch->ch_tun.un_flags |= (UN_EMPTY); - } - /* - * If DTR Toggle mode is on, turn on DTR now if not - * already set, and make sure we get an event when the - * data transfer has completed. - */ - if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) { - if (!(ch->ch_mostat & UART_MCR_DTR)) { - ch->ch_mostat |= (UART_MCR_DTR); - neo_assert_modem_signals(ch); - } - ch->ch_tun.un_flags |= (UN_EMPTY); - } - - writeb(ch->ch_wqueue[ch->ch_w_tail], - &ch->ch_neo_uart->txrx); - ch->ch_w_tail++; - ch->ch_w_tail &= WQUEUEMASK; - ch->ch_txcount++; - } - - goto exit_unlock; - } - - /* We have to do it this way, because of the EXAR TXFIFO count bug. */ - - if ((ch->ch_bd->dvid & 0xf0) < UART_XR17E158_DVID) { - if (!(ch->ch_flags & (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM))) - goto exit_unlock; - - len_written = 0; - - n = readb(&ch->ch_neo_uart->tfifo); - - if ((unsigned int)n > ch->ch_t_tlevel) - goto exit_unlock; - - n = UART_17158_TX_FIFOSIZE - ch->ch_t_tlevel; - } else { - n = UART_17158_TX_FIFOSIZE - readb(&ch->ch_neo_uart->tfifo); - } - - head = ch->ch_w_head & WQUEUEMASK; - tail = ch->ch_w_tail & WQUEUEMASK; - qlen = (head - tail) & WQUEUEMASK; - - n = min(n, qlen); - - while (n > 0) { - s = ((head >= tail) ? head : WQUEUESIZE) - tail; - s = min(s, n); - - if (s <= 0) - break; - - /* - * If RTS Toggle mode is on, turn on RTS now if not already set, - * and make sure we get an event when the data transfer has - * completed. - */ - if (ch->ch_digi.digi_flags & DIGI_RTS_TOGGLE) { - if (!(ch->ch_mostat & UART_MCR_RTS)) { - ch->ch_mostat |= (UART_MCR_RTS); - neo_assert_modem_signals(ch); - } - ch->ch_tun.un_flags |= (UN_EMPTY); - } - - /* - * If DTR Toggle mode is on, turn on DTR now if not already set, - * and make sure we get an event when the data transfer has - * completed. - */ - if (ch->ch_digi.digi_flags & DIGI_DTR_TOGGLE) { - if (!(ch->ch_mostat & UART_MCR_DTR)) { - ch->ch_mostat |= (UART_MCR_DTR); - neo_assert_modem_signals(ch); - } - ch->ch_tun.un_flags |= (UN_EMPTY); - } - - memcpy_toio(&ch->ch_neo_uart->txrxburst, - ch->ch_wqueue + tail, s); - - tail = (tail + s) & WQUEUEMASK; - n -= s; - ch->ch_txcount += s; - len_written += s; - } - - ch->ch_w_tail = tail & WQUEUEMASK; - - if (len_written > 0) { - neo_pci_posting_flush(ch->ch_bd); - ch->ch_flags &= ~(CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); - } - -exit_unlock: - spin_unlock_irqrestore(&ch->ch_lock, flags); -} - -static void neo_parse_modem(struct channel_t *ch, unsigned char signals) -{ - unsigned char msignals = signals; - - if (!ch) - return; - - /* - * Do altpin switching. Altpin switches DCD and DSR. - * This prolly breaks DSRPACE, so we should be more clever here. - */ - if (ch->ch_digi.digi_flags & DIGI_ALTPIN) { - unsigned char mswap = msignals; - - if (mswap & UART_MSR_DDCD) { - msignals &= ~UART_MSR_DDCD; - msignals |= UART_MSR_DDSR; - } - if (mswap & UART_MSR_DDSR) { - msignals &= ~UART_MSR_DDSR; - msignals |= UART_MSR_DDCD; - } - if (mswap & UART_MSR_DCD) { - msignals &= ~UART_MSR_DCD; - msignals |= UART_MSR_DSR; - } - if (mswap & UART_MSR_DSR) { - msignals &= ~UART_MSR_DSR; - msignals |= UART_MSR_DCD; - } - } - - /* Scrub off lower bits. They signify delta's */ - msignals &= 0xf0; - - if (msignals & UART_MSR_DCD) - ch->ch_mistat |= UART_MSR_DCD; - else - ch->ch_mistat &= ~UART_MSR_DCD; - - if (msignals & UART_MSR_DSR) - ch->ch_mistat |= UART_MSR_DSR; - else - ch->ch_mistat &= ~UART_MSR_DSR; - - if (msignals & UART_MSR_RI) - ch->ch_mistat |= UART_MSR_RI; - else - ch->ch_mistat &= ~UART_MSR_RI; - - if (msignals & UART_MSR_CTS) - ch->ch_mistat |= UART_MSR_CTS; - else - ch->ch_mistat &= ~UART_MSR_CTS; -} - -/* Make the UART raise any of the output signals we want up */ -static void neo_assert_modem_signals(struct channel_t *ch) -{ - unsigned char out; - - if (!ch) - return; - - out = ch->ch_mostat; - - if (ch->ch_flags & CH_LOOPBACK) - out |= UART_MCR_LOOP; - - writeb(out, &ch->ch_neo_uart->mcr); - neo_pci_posting_flush(ch->ch_bd); - - /* Give time for the UART to actually raise/drop the signals */ - udelay(10); -} - -static void neo_send_start_character(struct channel_t *ch) -{ - if (!ch) - return; - - if (ch->ch_startc != _POSIX_VDISABLE) { - ch->ch_xon_sends++; - writeb(ch->ch_startc, &ch->ch_neo_uart->txrx); - neo_pci_posting_flush(ch->ch_bd); - udelay(10); - } -} - -static void neo_send_stop_character(struct channel_t *ch) -{ - if (!ch) - return; - - if (ch->ch_stopc != _POSIX_VDISABLE) { - ch->ch_xoff_sends++; - writeb(ch->ch_stopc, &ch->ch_neo_uart->txrx); - neo_pci_posting_flush(ch->ch_bd); - udelay(10); - } -} - -/* neo_uart_init */ - -static void neo_uart_init(struct channel_t *ch) -{ - writeb(0, &ch->ch_neo_uart->ier); - writeb(0, &ch->ch_neo_uart->efr); - writeb(UART_EFR_ECB, &ch->ch_neo_uart->efr); - - /* Clear out UART and FIFO */ - readb(&ch->ch_neo_uart->txrx); - writeb(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT, - &ch->ch_neo_uart->isr_fcr); - readb(&ch->ch_neo_uart->lsr); - readb(&ch->ch_neo_uart->msr); - - ch->ch_flags |= CH_FIFO_ENABLED; - - /* Assert any signals we want up */ - writeb(ch->ch_mostat, &ch->ch_neo_uart->mcr); - neo_pci_posting_flush(ch->ch_bd); -} - -/* Make the UART completely turn off. */ -static void neo_uart_off(struct channel_t *ch) -{ - /* Turn off UART enhanced bits */ - writeb(0, &ch->ch_neo_uart->efr); - - /* Stop all interrupts from occurring. */ - writeb(0, &ch->ch_neo_uart->ier); - neo_pci_posting_flush(ch->ch_bd); -} - -static uint neo_get_uart_bytes_left(struct channel_t *ch) -{ - unsigned char left = 0; - unsigned char lsr = readb(&ch->ch_neo_uart->lsr); - - /* We must cache the LSR as some of the bits get reset once read... */ - ch->ch_cached_lsr |= lsr; - - /* Determine whether the Transmitter is empty or not */ - if (!(lsr & UART_LSR_TEMT)) { - if (ch->ch_flags & CH_TX_FIFO_EMPTY) - tasklet_schedule(&ch->ch_bd->helper_tasklet); - left = 1; - } else { - ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); - left = 0; - } - - return left; -} - -/* Channel lock MUST be held by the calling function! */ -static void neo_send_break(struct channel_t *ch, int msecs) -{ - /* If we receive a time of 0, this means turn off the break. */ - - if (msecs == 0) { - if (ch->ch_flags & CH_BREAK_SENDING) { - unsigned char temp = readb(&ch->ch_neo_uart->lcr); - - writeb((temp & ~UART_LCR_SBC), &ch->ch_neo_uart->lcr); - neo_pci_posting_flush(ch->ch_bd); - ch->ch_flags &= ~(CH_BREAK_SENDING); - ch->ch_stop_sending_break = 0; - } - return; - } - - /* - * Set the time we should stop sending the break. - * If we are already sending a break, toss away the existing - * time to stop, and use this new value instead. - */ - ch->ch_stop_sending_break = jiffies + dgnc_jiffies_from_ms(msecs); - - /* Tell the UART to start sending the break */ - if (!(ch->ch_flags & CH_BREAK_SENDING)) { - unsigned char temp = readb(&ch->ch_neo_uart->lcr); - - writeb((temp | UART_LCR_SBC), &ch->ch_neo_uart->lcr); - neo_pci_posting_flush(ch->ch_bd); - ch->ch_flags |= (CH_BREAK_SENDING); - } -} - -/* - * Sends a specific character as soon as possible to the UART, - * jumping over any bytes that might be in the write queue. - * - * The channel lock MUST be held by the calling function. - */ -static void neo_send_immediate_char(struct channel_t *ch, unsigned char c) -{ - if (!ch) - return; - - writeb(c, &ch->ch_neo_uart->txrx); - neo_pci_posting_flush(ch->ch_bd); -} - -static unsigned int neo_read_eeprom(unsigned char __iomem *base, - unsigned int address) -{ - unsigned int enable; - unsigned int bits; - unsigned int databit; - unsigned int val; - - /* enable chip select */ - writeb(NEO_EECS, base + NEO_EEREG); - /* READ */ - enable = address | 0x180; - - for (bits = 9; bits--; ) { - databit = (enable & (1 << bits)) ? NEO_EEDI : 0; - /* Set read address */ - writeb(databit | NEO_EECS, base + NEO_EEREG); - writeb(databit | NEO_EECS | NEO_EECK, base + NEO_EEREG); - } - - val = 0; - - for (bits = 17; bits--; ) { - /* clock to EEPROM */ - writeb(NEO_EECS, base + NEO_EEREG); - writeb(NEO_EECS | NEO_EECK, base + NEO_EEREG); - val <<= 1; - /* read EEPROM */ - if (readb(base + NEO_EEREG) & NEO_EEDO) - val |= 1; - } - - /* clock falling edge */ - writeb(NEO_EECS, base + NEO_EEREG); - - /* drop chip select */ - writeb(0x00, base + NEO_EEREG); - - return val; -} - -static void neo_vpd(struct dgnc_board *brd) -{ - unsigned int i = 0; - unsigned int a; - - if (!brd) - return; - - if (!brd->re_map_membase) - return; - - /* Store the VPD into our buffer */ - for (i = 0; i < NEO_VPD_IMAGESIZE; i++) { - a = neo_read_eeprom(brd->re_map_membase, i); - brd->vpd[i * 2] = a & 0xff; - brd->vpd[(i * 2) + 1] = (a >> 8) & 0xff; - } - - /* - * brd->vpd has different name tags by below index. - * 0x08 : long resource name tag - * 0x10 : long resource name tage (PCI-66 files) - * 0x7F : small resource end tag - */ - if (((brd->vpd[0x08] != 0x82) && - (brd->vpd[0x10] != 0x82)) || - (brd->vpd[0x7F] != 0x78)) { - memset(brd->vpd, '\0', NEO_VPD_IMAGESIZE); - } else { - /* Search for the serial number */ - for (i = 0; i < NEO_VPD_IMAGEBYTES - 3; i++) - if (brd->vpd[i] == 'S' && brd->vpd[i + 1] == 'N') - strncpy(brd->serial_num, &brd->vpd[i + 3], 9); - } -} diff --git a/drivers/staging/dgnc/dgnc_neo.h b/drivers/staging/dgnc/dgnc_neo.h deleted file mode 100644 index c30a2c2b5eea..000000000000 --- a/drivers/staging/dgnc/dgnc_neo.h +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright 2003 Digi International (www.digi.com) - * Scott H Kilau <Scott_Kilau at digi dot com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - */ - -#ifndef _DGNC_NEO_H -#define _DGNC_NEO_H - -#include "dgnc_driver.h" - -/** - * struct neo_uart_struct - Per channel/port NEO UART structure - * - * key - W = read write - * - R = read only - * - U = unused - * - * @txrx: (RW) Holding Register. - * @ier: (RW) Interrupt Enable Register. - * @isr_fcr: (RW) Interrupt Status Reg/Fifo Control Register. - * @lcr: (RW) Line Control Register. - * @mcr: (RW) Modem Control Register. - * @lsr: (RW) Line Status Register. - * @msr: (RW) Modem Status Register. - * @spr: (RW) Scratch Pad Register. - * @fctr: (RW) Feature Control Register. - * @efr: (RW) Enhanced Function Register. - * @tfifo: (RW) Transmit FIFO Register. - * @rfifo: (RW) Receive FIFO Register. - * @xoffchar1: (RW) XOff Character 1 Register. - * @xoffchar2: (RW) XOff Character 2 Register. - * @xonchar1: (RW) Xon Character 1 Register. - * @xonchar2: (RW) XOn Character 2 Register. - * @reserved1: (U) Reserved by Exar. - * @txrxburst: (RW) 64 bytes of RX/TX FIFO Data. - * @reserved2: (U) Reserved by Exar. - * @rxburst_with_errors: (R) bytes of RX FIFO Data + LSR. - */ -struct neo_uart_struct { - u8 txrx; - u8 ier; - u8 isr_fcr; - - u8 lcr; - u8 mcr; - u8 lsr; - u8 msr; - u8 spr; - u8 fctr; - u8 efr; - u8 tfifo; - u8 rfifo; - u8 xoffchar1; - u8 xoffchar2; - u8 xonchar1; - u8 xonchar2; - - u8 reserved1[0x2ff - 0x200]; - u8 txrxburst[64]; - u8 reserved2[0x37f - 0x340]; - u8 rxburst_with_errors[64]; -}; - -/* Where to read the extended interrupt register (32bits instead of 8bits) */ -#define UART_17158_POLL_ADDR_OFFSET 0x80 - -/* These are the current dvid's of the Neo boards */ -#define UART_XR17C158_DVID 0x20 -#define UART_XR17D158_DVID 0x20 -#define UART_XR17E158_DVID 0x40 - -#define NEO_EECK 0x10 /* Clock */ -#define NEO_EECS 0x20 /* Chip Select */ -#define NEO_EEDI 0x40 /* Data In is an Output Pin */ -#define NEO_EEDO 0x80 /* Data Out is an Input Pin */ -#define NEO_EEREG 0x8E /* offset to EEPROM control reg */ - -#define NEO_VPD_IMAGESIZE 0x40 /* size of image to read from EEPROM in words */ -#define NEO_VPD_IMAGEBYTES (NEO_VPD_IMAGESIZE * 2) - -/* - * These are the redefinitions for the FCTR on the XR17C158, since - * Exar made them different than their earlier design. (XR16C854) - */ - -/* These are only applicable when table D is selected */ -#define UART_17158_FCTR_RTS_NODELAY 0x00 -#define UART_17158_FCTR_RTS_4DELAY 0x01 -#define UART_17158_FCTR_RTS_6DELAY 0x02 -#define UART_17158_FCTR_RTS_8DELAY 0x03 -#define UART_17158_FCTR_RTS_12DELAY 0x12 -#define UART_17158_FCTR_RTS_16DELAY 0x05 -#define UART_17158_FCTR_RTS_20DELAY 0x13 -#define UART_17158_FCTR_RTS_24DELAY 0x06 -#define UART_17158_FCTR_RTS_28DELAY 0x14 -#define UART_17158_FCTR_RTS_32DELAY 0x07 -#define UART_17158_FCTR_RTS_36DELAY 0x16 -#define UART_17158_FCTR_RTS_40DELAY 0x08 -#define UART_17158_FCTR_RTS_44DELAY 0x09 -#define UART_17158_FCTR_RTS_48DELAY 0x10 -#define UART_17158_FCTR_RTS_52DELAY 0x11 - -#define UART_17158_FCTR_RTS_IRDA 0x10 -#define UART_17158_FCTR_RS485 0x20 -#define UART_17158_FCTR_TRGA 0x00 -#define UART_17158_FCTR_TRGB 0x40 -#define UART_17158_FCTR_TRGC 0x80 -#define UART_17158_FCTR_TRGD 0xC0 - -/* 17158 trigger table selects.. */ -#define UART_17158_FCTR_BIT6 0x40 -#define UART_17158_FCTR_BIT7 0x80 - -/* 17158 TX/RX memmapped buffer offsets */ -#define UART_17158_RX_FIFOSIZE 64 -#define UART_17158_TX_FIFOSIZE 64 - -/* 17158 Extended IIR's */ -#define UART_17158_IIR_RDI_TIMEOUT 0x0C /* Receiver data TIMEOUT */ -#define UART_17158_IIR_XONXOFF 0x10 /* Received an XON/XOFF char */ -#define UART_17158_IIR_HWFLOW_STATE_CHANGE 0x20 /* CTS/DSR or RTS/DTR - * state change - */ -#define UART_17158_IIR_FIFO_ENABLED 0xC0 /* 16550 FIFOs are Enabled */ - -/* - * These are the extended interrupts that get sent - * back to us from the UART's 32bit interrupt register - */ -#define UART_17158_RX_LINE_STATUS 0x1 /* RX Ready */ -#define UART_17158_RXRDY_TIMEOUT 0x2 /* RX Ready Timeout */ -#define UART_17158_TXRDY 0x3 /* TX Ready */ -#define UART_17158_MSR 0x4 /* Modem State Change */ -#define UART_17158_TX_AND_FIFO_CLR 0x40 /* Transmitter Holding - * Reg Empty - */ -#define UART_17158_RX_FIFO_DATA_ERROR 0x80 /* UART detected an RX FIFO - * Data error - */ - -/* - * These are the EXTENDED definitions for the 17C158's Interrupt - * Enable Register. - */ -#define UART_17158_EFR_ECB 0x10 /* Enhanced control bit */ -#define UART_17158_EFR_IXON 0x2 /* Receiver compares Xon1/Xoff1 */ -#define UART_17158_EFR_IXOFF 0x8 /* Transmit Xon1/Xoff1 */ -#define UART_17158_EFR_RTSDTR 0x40 /* Auto RTS/DTR Flow Control Enable */ -#define UART_17158_EFR_CTSDSR 0x80 /* Auto CTS/DSR Flow Control Enable */ - -#define UART_17158_XOFF_DETECT 0x1 /* Indicates whether chip saw an - * incoming XOFF char - */ -#define UART_17158_XON_DETECT 0x2 /* Indicates whether chip saw an - * incoming XON char - */ - -#define UART_17158_IER_RSVD1 0x10 /* Reserved by Exar */ -#define UART_17158_IER_XOFF 0x20 /* Xoff Interrupt Enable */ -#define UART_17158_IER_RTSDTR 0x40 /* Output Interrupt Enable */ -#define UART_17158_IER_CTSDSR 0x80 /* Input Interrupt Enable */ - -extern struct board_ops dgnc_neo_ops; - -#endif /* _DGNC_NEO_H */ diff --git a/drivers/staging/dgnc/dgnc_pci.h b/drivers/staging/dgnc/dgnc_pci.h deleted file mode 100644 index 59845916d90c..000000000000 --- a/drivers/staging/dgnc/dgnc_pci.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2003 Digi International (www.digi.com) - * Scott H Kilau <Scott_Kilau at digi dot com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - */ - -#ifndef _DGNC_PCI_H -#define _DGNC_PCI_H - -/* Maximum number of PCI boards */ -#define PCIMAX 32 - -#define DIGI_VID 0x114F - -#define PCI_DEVICE_CLASSIC_4_DID 0x0028 -#define PCI_DEVICE_CLASSIC_8_DID 0x0029 -#define PCI_DEVICE_CLASSIC_4_422_DID 0x00D0 -#define PCI_DEVICE_CLASSIC_8_422_DID 0x00D1 -#define PCI_DEVICE_NEO_4_DID 0x00B0 -#define PCI_DEVICE_NEO_8_DID 0x00B1 -#define PCI_DEVICE_NEO_2DB9_DID 0x00C8 -#define PCI_DEVICE_NEO_2DB9PRI_DID 0x00C9 -#define PCI_DEVICE_NEO_2RJ45_DID 0x00CA -#define PCI_DEVICE_NEO_2RJ45PRI_DID 0x00CB -#define PCI_DEVICE_NEO_1_422_DID 0x00CC -#define PCI_DEVICE_NEO_1_422_485_DID 0x00CD -#define PCI_DEVICE_NEO_2_422_485_DID 0x00CE -#define PCI_DEVICE_NEO_EXPRESS_8_DID 0x00F0 -#define PCI_DEVICE_NEO_EXPRESS_4_DID 0x00F1 -#define PCI_DEVICE_NEO_EXPRESS_4RJ45_DID 0x00F2 -#define PCI_DEVICE_NEO_EXPRESS_8RJ45_DID 0x00F3 -#define PCI_DEVICE_NEO_EXPRESS_4_IBM_DID 0x00F4 - -#define PCI_DEVICE_CLASSIC_4_PCI_NAME "ClassicBoard 4 PCI" -#define PCI_DEVICE_CLASSIC_8_PCI_NAME "ClassicBoard 8 PCI" -#define PCI_DEVICE_CLASSIC_4_422_PCI_NAME "ClassicBoard 4 422 PCI" -#define PCI_DEVICE_CLASSIC_8_422_PCI_NAME "ClassicBoard 8 422 PCI" -#define PCI_DEVICE_NEO_4_PCI_NAME "Neo 4 PCI" -#define PCI_DEVICE_NEO_8_PCI_NAME "Neo 8 PCI" -#define PCI_DEVICE_NEO_2DB9_PCI_NAME "Neo 2 - DB9 Universal PCI" -#define PCI_DEVICE_NEO_2DB9PRI_PCI_NAME "Neo 2 - DB9 Universal PCI - Powered Ring Indicator" -#define PCI_DEVICE_NEO_2RJ45_PCI_NAME "Neo 2 - RJ45 Universal PCI" -#define PCI_DEVICE_NEO_2RJ45PRI_PCI_NAME "Neo 2 - RJ45 Universal PCI - Powered Ring Indicator" -#define PCI_DEVICE_NEO_1_422_PCI_NAME "Neo 1 422 PCI" -#define PCI_DEVICE_NEO_1_422_485_PCI_NAME "Neo 1 422/485 PCI" -#define PCI_DEVICE_NEO_2_422_485_PCI_NAME "Neo 2 422/485 PCI" - -#define PCI_DEVICE_NEO_EXPRESS_8_PCI_NAME "Neo 8 PCI Express" -#define PCI_DEVICE_NEO_EXPRESS_4_PCI_NAME "Neo 4 PCI Express" -#define PCI_DEVICE_NEO_EXPRESS_4RJ45_PCI_NAME "Neo 4 PCI Express RJ45" -#define PCI_DEVICE_NEO_EXPRESS_8RJ45_PCI_NAME "Neo 8 PCI Express RJ45" -#define PCI_DEVICE_NEO_EXPRESS_4_IBM_PCI_NAME "Neo 4 PCI Express IBM" - -/* Size of memory and I/O for PCI (4 K) */ -#define PCI_RAM_SIZE 0x1000 - -/* Size of memory (2MB) */ -#define PCI_MEM_SIZE 0x1000 - -#endif /* _DGNC_PCI_H */ diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index d3736daf8cf2..9f9b9a5b4b27 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -1,16 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright 2003 Digi International (www.digi.com) * Scott H Kilau <Scott_Kilau at digi dot com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. */ /* @@ -33,9 +24,7 @@ #include <linux/pci.h> #include "dgnc_driver.h" #include "dgnc_tty.h" -#include "dgnc_neo.h" #include "dgnc_cls.h" -#include "dgnc_utils.h" /* Default transparent print information. */ @@ -240,10 +229,7 @@ int dgnc_tty_init(struct dgnc_board *brd) ch->ch_pun.un_type = DGNC_PRINT; ch->ch_pun.un_dev = i + 128; - if (brd->bd_uart_offset == 0x200) - ch->ch_neo_uart = vaddr + (brd->bd_uart_offset * i); - else - ch->ch_cls_uart = vaddr + (brd->bd_uart_offset * i); + ch->ch_cls_uart = vaddr + (brd->bd_uart_offset * i); ch->ch_bd = brd; ch->ch_portnum = i; @@ -1238,7 +1224,7 @@ static void dgnc_tty_close(struct tty_struct *tty, struct file *file) if (ch->ch_close_delay) { spin_unlock_irqrestore(&ch->ch_lock, flags); - dgnc_ms_sleep(ch->ch_close_delay); + msleep_interruptible(ch->ch_close_delay); spin_lock_irqsave(&ch->ch_lock, flags); } } diff --git a/drivers/staging/dgnc/dgnc_tty.h b/drivers/staging/dgnc/dgnc_tty.h index 6c58f1b3461a..00e31035b83d 100644 --- a/drivers/staging/dgnc/dgnc_tty.h +++ b/drivers/staging/dgnc/dgnc_tty.h @@ -1,16 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright 2003 Digi International (www.digi.com) * Scott H Kilau <Scott_Kilau at digi dot com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. */ #ifndef _DGNC_TTY_H diff --git a/drivers/staging/dgnc/dgnc_utils.c b/drivers/staging/dgnc/dgnc_utils.c deleted file mode 100644 index 620f5741a1ed..000000000000 --- a/drivers/staging/dgnc/dgnc_utils.c +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include <linux/tty.h> -#include <linux/sched/signal.h> -#include "dgnc_utils.h" - -/** - * dgnc_ms_sleep - Put the driver to sleep - * @ms - milliseconds to sleep - * - * Return: 0 if timed out, if interrupted by a signal return signal. - */ -int dgnc_ms_sleep(ulong ms) -{ - __set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout((ms * HZ) / 1000); - return signal_pending(current); -} diff --git a/drivers/staging/dgnc/dgnc_utils.h b/drivers/staging/dgnc/dgnc_utils.h deleted file mode 100644 index b30527f0889d..000000000000 --- a/drivers/staging/dgnc/dgnc_utils.h +++ /dev/null @@ -1,7 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _DGNC_UTILS_H -#define _DGNC_UTILS_H - -int dgnc_ms_sleep(ulong ms); - -#endif /* _DGNC_UTILS_H */ diff --git a/drivers/staging/dgnc/digi.h b/drivers/staging/dgnc/digi.h index 46b06b07bbf2..b414ee80db88 100644 --- a/drivers/staging/dgnc/digi.h +++ b/drivers/staging/dgnc/digi.h @@ -1,50 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright 2003 Digi International (www.digi.com) * Scott H Kilau <Scott_Kilau at digi dot com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the - * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. */ #ifndef _DIGI_H #define _DIGI_H -#ifndef TIOCM_LE -#define TIOCM_LE 0x01 /* line enable */ -#define TIOCM_DTR 0x02 /* data terminal ready */ -#define TIOCM_RTS 0x04 /* request to send */ -#define TIOCM_ST 0x08 /* secondary transmit */ -#define TIOCM_SR 0x10 /* secondary receive */ -#define TIOCM_CTS 0x20 /* clear to send */ -#define TIOCM_CAR 0x40 /* carrier detect */ -#define TIOCM_RNG 0x80 /* ring indicator */ -#define TIOCM_DSR 0x100 /* data set ready */ -#define TIOCM_RI TIOCM_RNG /* ring (alternate) */ -#define TIOCM_CD TIOCM_CAR /* carrier detect (alt) */ -#endif - -#if !defined(TIOCMSET) -#define TIOCMSET (('d' << 8) | 252) /* set modem ctrl state */ -#define TIOCMGET (('d' << 8) | 253) /* set modem ctrl state */ -#endif - -#if !defined(TIOCMBIC) -#define TIOCMBIC (('d' << 8) | 254) /* set modem ctrl state */ -#define TIOCMBIS (('d' << 8) | 255) /* set modem ctrl state */ -#endif - #define DIGI_GETA (('e' << 8) | 94) /* Read params */ #define DIGI_SETA (('e' << 8) | 95) /* Set params */ #define DIGI_SETAW (('e' << 8) | 96) /* Drain & set params */ #define DIGI_SETAF (('e' << 8) | 97) /* Drain, flush & set params */ -#define DIGI_GET_NI_INFO (('d' << 8) | 250) /* Non-intelligent state info */ #define DIGI_LOOPBACK (('d' << 8) | 252) /* Enable/disable UART * internal loopback */ @@ -88,49 +54,6 @@ struct digi_t { }; /** - * struct digi_dinfo - Driver status information. - * @dinfo_nboards: Number of boards configured. - * @dinfo_reserved: Not used, for future expansion. - * @dinfio_version: Driver version. - */ -struct digi_dinfo { - unsigned int dinfo_nboards; - char dinfo_reserved[12]; - char dinfo_version[16]; -}; - -#define DIGI_GETDD (('d' << 8) | 248) /* get driver info */ - -/** - * struct digi_info - Ioctl commands for per board information. - * - * Physsize and memsize differ when board has "windowed" memory. - * - * @info_bdnum: Board number (0 based). - * @info_ioport: IO port address. - * @indo_physaddr: Memory address. - * @info_physize: Size of host memory window. - * @info_memsize: Amount of dual-port memory on board. - * @info_bdtype: Board type. - * @info_nports: Number of ports. - * @info_bdstate: Board state. - * @info_reserved: Not used, for future expansion. - */ -struct digi_info { - unsigned int info_bdnum; - unsigned int info_ioport; - unsigned int info_physaddr; - unsigned int info_physsize; - unsigned int info_memsize; - unsigned short info_bdtype; - unsigned short info_nports; - char info_bdstate; - char info_reserved[7]; -}; - -#define DIGI_GETBD (('d' << 8) | 249) /* get board info */ - -/** * struct digi_getbuffer - Holds buffer use counts. */ struct digi_getbuffer { @@ -161,10 +84,6 @@ struct digi_getcounter { unsigned long tbytes; }; -/* Board State Definitions */ -#define BD_RUNNING 0x0 -#define BD_NOFEP 0x5 - #define DIGI_SETCUSTOMBAUD _IOW('e', 106, int) /* Set integer baud rate */ #define DIGI_GETCUSTOMBAUD _IOR('e', 107, int) /* Get integer baud rate */ @@ -204,11 +123,6 @@ struct ni_info { unsigned int baud; }; -#define T_CLASSIC 0002 -#define T_PCIBUS 0400 -#define T_NEO_EXPRESS 0001 -#define T_NEO 0000 - #define TTY_FLIPBUF_SIZE 512 #endif /* _DIGI_H */ diff --git a/drivers/staging/emxx_udc/emxx_udc.c b/drivers/staging/emxx_udc/emxx_udc.c index bb010cb98a1c..7517001fb8f0 100644 --- a/drivers/staging/emxx_udc/emxx_udc.c +++ b/drivers/staging/emxx_udc/emxx_udc.c @@ -1,17 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * drivers/usb/gadget/emxx_udc.c * EMXX FCD (Function Controller Driver) for USB. * * Copyright (C) 2010 Renesas Electronics Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/kernel.h> diff --git a/drivers/staging/emxx_udc/emxx_udc.h b/drivers/staging/emxx_udc/emxx_udc.h index 928d531a5115..8337e38c238a 100644 --- a/drivers/staging/emxx_udc/emxx_udc.h +++ b/drivers/staging/emxx_udc/emxx_udc.h @@ -1,16 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * EMXX FCD (Function Controller Driver) for USB. * * Copyright (C) 2010 Renesas Electronics Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _LINUX_EMXX_H diff --git a/drivers/staging/fbtft/Kconfig b/drivers/staging/fbtft/Kconfig index dba676761d72..84b2e7ebc024 100644 --- a/drivers/staging/fbtft/Kconfig +++ b/drivers/staging/fbtft/Kconfig @@ -135,12 +135,6 @@ config FB_TFT_SSD1306 help Framebuffer support for SSD1306 -config FB_TFT_SSD1325 - tristate "FB driver for the SSD1325 OLED Controller" - depends on FB_TFT - help - Framebuffer support for SSD1305 - config FB_TFT_SSD1331 tristate "FB driver for the SSD1331 LCD Controller" depends on FB_TFT diff --git a/drivers/staging/fbtft/fb_agm1264k-fl.c b/drivers/staging/fbtft/fb_agm1264k-fl.c index 456a8dd65caf..f6f30f5bf15a 100644 --- a/drivers/staging/fbtft/fb_agm1264k-fl.c +++ b/drivers/staging/fbtft/fb_agm1264k-fl.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for Two KS0108 LCD controllers in AGM1264K-FL display * * Copyright (C) 2014 ololoshka2871 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_bd663474.c b/drivers/staging/fbtft/fb_bd663474.c index 6010e6cbbd72..a58c514f4721 100644 --- a/drivers/staging/fbtft/fb_bd663474.c +++ b/drivers/staging/fbtft/fb_bd663474.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for the uPD161704 LCD Controller * @@ -6,16 +7,6 @@ * Based on fb_ili9325.c by Noralf Tronnes * Based on ili9325.c by Jeroen Domburg * Init code from UTFT library by Henning Karlsen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_hx8340bn.c b/drivers/staging/fbtft/fb_hx8340bn.c index fbd5ef525243..d47dcf31fffb 100644 --- a/drivers/staging/fbtft/fb_hx8340bn.c +++ b/drivers/staging/fbtft/fb_hx8340bn.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for the HX8340BN LCD Controller * @@ -7,16 +8,6 @@ * This is done by transferring eight 9-bit words in 9 bytes. * * Copyright (C) 2013 Noralf Tronnes - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_hx8347d.c b/drivers/staging/fbtft/fb_hx8347d.c index bbf78f8644a8..0b605303813e 100644 --- a/drivers/staging/fbtft/fb_hx8347d.c +++ b/drivers/staging/fbtft/fb_hx8347d.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for the HX8347D LCD Controller * * Copyright (C) 2013 Christian Vogelgsang * * Based on driver code found here: https://github.com/watterott/r61505u-Adapter - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_hx8353d.c b/drivers/staging/fbtft/fb_hx8353d.c index 2c18051a44b3..3e73b69b6a27 100644 --- a/drivers/staging/fbtft/fb_hx8353d.c +++ b/drivers/staging/fbtft/fb_hx8353d.c @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for the HX8353D LCD Controller * * Copyright (c) 2014 Petr Olivka * Copyright (c) 2013 Noralf Tronnes - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_hx8357d.c b/drivers/staging/fbtft/fb_hx8357d.c index 32e6efe1d0a7..94a357e8fdf6 100644 --- a/drivers/staging/fbtft/fb_hx8357d.c +++ b/drivers/staging/fbtft/fb_hx8357d.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for the HX8357D LCD Controller * Copyright (C) 2015 Adafruit Industries @@ -6,16 +7,6 @@ * Copyright (C) 2013 Christian Vogelgsang * * Based on driver code found here: https://github.com/watterott/r61505u-Adapter - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_hx8357d.h b/drivers/staging/fbtft/fb_hx8357d.h index e281921d4a97..6180b093f94f 100644 --- a/drivers/staging/fbtft/fb_hx8357d.h +++ b/drivers/staging/fbtft/fb_hx8357d.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: MIT */ /* * This is our library for the Adafruit ILI9341 Breakout and Shield * ----> http://www.adafruit.com/products/1651 diff --git a/drivers/staging/fbtft/fb_ili9163.c b/drivers/staging/fbtft/fb_ili9163.c index 045cadc3bc65..fd3dd671509f 100644 --- a/drivers/staging/fbtft/fb_ili9163.c +++ b/drivers/staging/fbtft/fb_ili9163.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for the ILI9163 LCD Controller * @@ -5,16 +6,6 @@ * * Based on ili9325.c by Noralf Tronnes and * .S.U.M.O.T.O.Y. by Max MC Costa (https://github.com/sumotoy/TFT_ILI9163C). - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_ili9320.c b/drivers/staging/fbtft/fb_ili9320.c index 20ba86da028b..501eee7dce4c 100644 --- a/drivers/staging/fbtft/fb_ili9320.c +++ b/drivers/staging/fbtft/fb_ili9320.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for the ILI9320 LCD Controller * * Copyright (C) 2013 Noralf Tronnes - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_ili9325.c b/drivers/staging/fbtft/fb_ili9325.c index 7f9e9b25490e..d6b1d4be9ff4 100644 --- a/drivers/staging/fbtft/fb_ili9325.c +++ b/drivers/staging/fbtft/fb_ili9325.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for the ILI9325 LCD Controller * * Copyright (C) 2013 Noralf Tronnes * * Based on ili9325.c by Jeroen Domburg - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_ili9340.c b/drivers/staging/fbtft/fb_ili9340.c index 0711121c303c..430f21e50f4d 100644 --- a/drivers/staging/fbtft/fb_ili9340.c +++ b/drivers/staging/fbtft/fb_ili9340.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for the ILI9340 LCD Controller * * Copyright (C) 2013 Noralf Tronnes - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_ili9341.c b/drivers/staging/fbtft/fb_ili9341.c index 21a98e9e1a14..a10e8c9de438 100644 --- a/drivers/staging/fbtft/fb_ili9341.c +++ b/drivers/staging/fbtft/fb_ili9341.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for the ILI9341 LCD display controller * @@ -8,16 +9,6 @@ * * Copyright (C) 2013 Christian Vogelgsang * Based on adafruit22fb.c by Noralf Tronnes - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_ili9481.c b/drivers/staging/fbtft/fb_ili9481.c index 7f182a1c084c..19eba085ea53 100644 --- a/drivers/staging/fbtft/fb_ili9481.c +++ b/drivers/staging/fbtft/fb_ili9481.c @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for the ILI9481 LCD Controller * * Copyright (c) 2014 Petr Olivka * Copyright (c) 2013 Noralf Tronnes - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_ili9486.c b/drivers/staging/fbtft/fb_ili9486.c index ddd07a64c48a..66210a7137fc 100644 --- a/drivers/staging/fbtft/fb_ili9486.c +++ b/drivers/staging/fbtft/fb_ili9486.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for the ILI9486 LCD Controller * * Copyright (C) 2014 Noralf Tronnes - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_pcd8544.c b/drivers/staging/fbtft/fb_pcd8544.c index 87f678a314cc..32172f8f79f0 100644 --- a/drivers/staging/fbtft/fb_pcd8544.c +++ b/drivers/staging/fbtft/fb_pcd8544.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for the PCD8544 LCD Controller * @@ -5,16 +6,6 @@ * Any pixel value except 0 turns the pixel on. * * Copyright (C) 2013 Noralf Tronnes - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_ra8875.c b/drivers/staging/fbtft/fb_ra8875.c index 6d1cad85957b..5d3b76ca74d8 100644 --- a/drivers/staging/fbtft/fb_ra8875.c +++ b/drivers/staging/fbtft/fb_ra8875.c @@ -1,16 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FBTFT driver for the RA8875 LCD Controller * Copyright by Pf@nne & NOTRO - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_s6d02a1.c b/drivers/staging/fbtft/fb_s6d02a1.c index c12855bb6891..75295760f491 100644 --- a/drivers/staging/fbtft/fb_s6d02a1.c +++ b/drivers/staging/fbtft/fb_s6d02a1.c @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for the S6D02A1 LCD Controller * * Based on fb_st7735r.c by Noralf Tronnes * Init code from UTFT library by Henning Karlsen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_s6d1121.c b/drivers/staging/fbtft/fb_s6d1121.c index 3b36ed50d491..b90244259d43 100644 --- a/drivers/staging/fbtft/fb_s6d1121.c +++ b/drivers/staging/fbtft/fb_s6d1121.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for the S6D1121 LCD Controller * @@ -6,16 +7,6 @@ * Based on fb_ili9325.c by Noralf Tronnes * Based on ili9325.c by Jeroen Domburg * Init code from UTFT library by Henning Karlsen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_sh1106.c b/drivers/staging/fbtft/fb_sh1106.c index 89c27a440305..3fc18c0a6f11 100644 --- a/drivers/staging/fbtft/fb_sh1106.c +++ b/drivers/staging/fbtft/fb_sh1106.c @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for the SH1106 OLED Controller * Based on the SSD1306 driver by Noralf Tronnes * * Copyright (C) 2017 Heiner Kallweit - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_ssd1289.c b/drivers/staging/fbtft/fb_ssd1289.c index 129e175fcd7e..cbf22e1f4b61 100644 --- a/drivers/staging/fbtft/fb_ssd1289.c +++ b/drivers/staging/fbtft/fb_ssd1289.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for the SSD1289 LCD Controller * * Copyright (C) 2013 Noralf Tronnes * * Init sequence taken from ITDB02_Graph16.cpp - (C)2010-2011 Henning Karlsen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_ssd1305.c b/drivers/staging/fbtft/fb_ssd1305.c index 33c03872ca84..3515888d94c9 100644 --- a/drivers/staging/fbtft/fb_ssd1305.c +++ b/drivers/staging/fbtft/fb_ssd1305.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for the SSD1305 OLED Controller * * based on SSD1306 driver by Noralf Tronnes - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_ssd1306.c b/drivers/staging/fbtft/fb_ssd1306.c index 96c58de85288..9276be499303 100644 --- a/drivers/staging/fbtft/fb_ssd1306.c +++ b/drivers/staging/fbtft/fb_ssd1306.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for the SSD1306 OLED Controller * * Copyright (C) 2013 Noralf Tronnes - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_ssd1325.c b/drivers/staging/fbtft/fb_ssd1325.c index b7e40c24f58e..1a469b3c92d4 100644 --- a/drivers/staging/fbtft/fb_ssd1325.c +++ b/drivers/staging/fbtft/fb_ssd1325.c @@ -1,15 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for the SSD1325 OLED Controller - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_ssd1331.c b/drivers/staging/fbtft/fb_ssd1331.c index e4a759b54ba0..383e197cf56a 100644 --- a/drivers/staging/fbtft/fb_ssd1331.c +++ b/drivers/staging/fbtft/fb_ssd1331.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> diff --git a/drivers/staging/fbtft/fb_ssd1351.c b/drivers/staging/fbtft/fb_ssd1351.c index e62235d4d9e7..b8ef75f5e856 100644 --- a/drivers/staging/fbtft/fb_ssd1351.c +++ b/drivers/staging/fbtft/fb_ssd1351.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> diff --git a/drivers/staging/fbtft/fb_st7735r.c b/drivers/staging/fbtft/fb_st7735r.c index d98522a39344..631208bd3a17 100644 --- a/drivers/staging/fbtft/fb_st7735r.c +++ b/drivers/staging/fbtft/fb_st7735r.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for the ST7735R LCD Controller * * Copyright (C) 2013 Noralf Tronnes - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_st7789v.c b/drivers/staging/fbtft/fb_st7789v.c index a5d7c87557f8..7d7573a7b615 100644 --- a/drivers/staging/fbtft/fb_st7789v.c +++ b/drivers/staging/fbtft/fb_st7789v.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for the ST7789V LCD Controller * * Copyright (C) 2015 Dennis Menschel - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/bitops.h> diff --git a/drivers/staging/fbtft/fb_tinylcd.c b/drivers/staging/fbtft/fb_tinylcd.c index 097e71cfef62..e463b0ddf16d 100644 --- a/drivers/staging/fbtft/fb_tinylcd.c +++ b/drivers/staging/fbtft/fb_tinylcd.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Custom FB driver for tinylcd.com display * * Copyright (C) 2013 Noralf Tronnes - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_tls8204.c b/drivers/staging/fbtft/fb_tls8204.c index 4302e822de3b..277b6ed9c725 100644 --- a/drivers/staging/fbtft/fb_tls8204.c +++ b/drivers/staging/fbtft/fb_tls8204.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for the TLS8204 LCD Controller * @@ -6,16 +7,6 @@ * * Copyright (C) 2013 Noralf Tronnes * Copyright (C) 2014 Michael Hope (adapted for the TLS8204) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_uc1611.c b/drivers/staging/fbtft/fb_uc1611.c index 8eb5e7f10fb5..4d65567eefe2 100644 --- a/drivers/staging/fbtft/fb_uc1611.c +++ b/drivers/staging/fbtft/fb_uc1611.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for the UltraChip UC1611 LCD controller * * The display is 4-bit grayscale (16 shades) 240x160. * * Copyright (C) 2015 Henri Chain - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_uc1701.c b/drivers/staging/fbtft/fb_uc1701.c index 78899a172c7e..0a3531d6eb39 100644 --- a/drivers/staging/fbtft/fb_uc1701.c +++ b/drivers/staging/fbtft/fb_uc1701.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for the UC1701 LCD Controller * @@ -5,16 +6,6 @@ * Any pixel value except 0 turns the pixel on. * * Copyright (C) 2014 Juergen Holzmann - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_upd161704.c b/drivers/staging/fbtft/fb_upd161704.c index 970b8430eccf..acc425fdf34e 100644 --- a/drivers/staging/fbtft/fb_upd161704.c +++ b/drivers/staging/fbtft/fb_upd161704.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for the uPD161704 LCD Controller * @@ -6,16 +7,6 @@ * Based on fb_ili9325.c by Noralf Tronnes * Based on ili9325.c by Jeroen Domburg * Init code from UTFT library by Henning Karlsen - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fb_watterott.c b/drivers/staging/fbtft/fb_watterott.c index 180e5be6fa4f..bfd1527f20f7 100644 --- a/drivers/staging/fbtft/fb_watterott.c +++ b/drivers/staging/fbtft/fb_watterott.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FB driver for the Watterott LCD Controller * * Copyright (C) 2013 Noralf Tronnes - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c index 6d0363deba61..0e36b66ae5f7 100644 --- a/drivers/staging/fbtft/fbtft-core.c +++ b/drivers/staging/fbtft/fbtft-core.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2013 Noralf Tronnes * * This driver is inspired by: * st7735fb.c, Copyright (C) 2011, Matt Porter * broadsheetfb.c, Copyright (C) 2008, Jaya Kumar - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> @@ -1367,20 +1358,18 @@ int fbtft_probe_common(struct fbtft_display *display, } /* write register functions */ - if (display->regwidth == 8 && display->buswidth == 8) { + if (display->regwidth == 8 && display->buswidth == 8) par->fbtftops.write_register = fbtft_write_reg8_bus8; - } else - if (display->regwidth == 8 && display->buswidth == 9 && par->spi) { + else if (display->regwidth == 8 && display->buswidth == 9 && par->spi) par->fbtftops.write_register = fbtft_write_reg8_bus9; - } else if (display->regwidth == 16 && display->buswidth == 8) { + else if (display->regwidth == 16 && display->buswidth == 8) par->fbtftops.write_register = fbtft_write_reg16_bus8; - } else if (display->regwidth == 16 && display->buswidth == 16) { + else if (display->regwidth == 16 && display->buswidth == 16) par->fbtftops.write_register = fbtft_write_reg16_bus16; - } else { + else dev_warn(dev, - "no default functions for regwidth=%d and buswidth=%d\n", - display->regwidth, display->buswidth); - } + "no default functions for regwidth=%d and buswidth=%d\n", + display->regwidth, display->buswidth); /* write_vmem() functions */ if (display->buswidth == 8) diff --git a/drivers/staging/fbtft/fbtft.h b/drivers/staging/fbtft/fbtft.h index 488ab788138e..e19e64e0d094 100644 --- a/drivers/staging/fbtft/fbtft.h +++ b/drivers/staging/fbtft/fbtft.h @@ -1,16 +1,5 @@ -/* - * Copyright (C) 2013 Noralf Tronnes - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* Copyright (C) 2013 Noralf Tronnes */ #ifndef __LINUX_FBTFT_H #define __LINUX_FBTFT_H diff --git a/drivers/staging/fbtft/fbtft_device.c b/drivers/staging/fbtft/fbtft_device.c index 0d974738c1c4..ec8477674b7d 100644 --- a/drivers/staging/fbtft/fbtft_device.c +++ b/drivers/staging/fbtft/fbtft_device.c @@ -1,16 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * * Copyright (C) 2013, Noralf Tronnes - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #define pr_fmt(fmt) "fbtft_device: " fmt diff --git a/drivers/staging/fbtft/flexfb.c b/drivers/staging/fbtft/flexfb.c index 7134624a16c2..f676c9b853f1 100644 --- a/drivers/staging/fbtft/flexfb.c +++ b/drivers/staging/fbtft/flexfb.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Generic FB driver for TFT LCD displays * * Copyright (C) 2013 Noralf Tronnes - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/staging/fbtft/internal.h b/drivers/staging/fbtft/internal.h index 25b9bf6f54bb..ae2ff4a4a472 100644 --- a/drivers/staging/fbtft/internal.h +++ b/drivers/staging/fbtft/internal.h @@ -1,17 +1,5 @@ -/* - * Copyright (C) 2013 Noralf Tronnes - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* Copyright (C) 2013 Noralf Tronnes */ #ifndef __LINUX_FBTFT_INTERNAL_H #define __LINUX_FBTFT_INTERNAL_H diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c index 0d8ed002adcb..2817e67df3d5 100644 --- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c +++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c @@ -230,7 +230,8 @@ static struct sk_buff *build_frag_skb(struct dpaa2_eth_priv *priv, static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv, struct dpaa2_eth_channel *ch, const struct dpaa2_fd *fd, - struct napi_struct *napi) + struct napi_struct *napi, + u16 queue_id) { dma_addr_t addr = dpaa2_fd_get_addr(fd); u8 fd_format = dpaa2_fd_get_format(fd); @@ -249,7 +250,7 @@ static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv, vaddr = dpaa2_iova_to_virt(priv->iommu_domain, addr); dma_unmap_single(dev, addr, DPAA2_ETH_RX_BUF_SIZE, DMA_FROM_DEVICE); - fas = dpaa2_get_fas(vaddr); + fas = dpaa2_get_fas(vaddr, false); prefetch(fas); buf_data = vaddr + dpaa2_fd_get_offset(fd); prefetch(buf_data); @@ -281,6 +282,7 @@ static void dpaa2_eth_rx(struct dpaa2_eth_priv *priv, } skb->protocol = eth_type_trans(skb, priv->net_dev); + skb_record_rx_queue(skb, queue_id); percpu_stats->rx_packets++; percpu_stats->rx_bytes += dpaa2_fd_get_len(fd); @@ -325,7 +327,7 @@ static int consume_frames(struct dpaa2_eth_channel *ch) fq = (struct dpaa2_eth_fq *)dpaa2_dq_fqd_ctx(dq); fq->stats.frames++; - fq->consume(priv, ch, fd, &ch->napi); + fq->consume(priv, ch, fd, &ch->napi, fq->flowid); cleaned++; } while (!is_last); @@ -348,7 +350,6 @@ static int build_sg_fd(struct dpaa2_eth_priv *priv, int num_sg; int num_dma_bufs; struct dpaa2_eth_swa *swa; - struct dpaa2_fas *fas; /* Create and map scatterlist. * We don't advertise NETIF_F_FRAGLIST, so skb_to_sgvec() will not have @@ -379,15 +380,6 @@ static int build_sg_fd(struct dpaa2_eth_priv *priv, goto sgt_buf_alloc_failed; } sgt_buf = PTR_ALIGN(sgt_buf, DPAA2_ETH_TX_BUF_ALIGN); - - /* PTA from egress side is passed as is to the confirmation side so - * we need to clear some fields here in order to find consistent values - * on TX confirmation. We are clearing FAS (Frame Annotation Status) - * field from the hardware annotation area - */ - fas = dpaa2_get_fas(sgt_buf); - memset(fas, 0, DPAA2_FAS_SIZE); - sgt = (struct dpaa2_sg_entry *)(sgt_buf + priv->tx_data_offset); /* Fill in the HW SGT structure. @@ -424,8 +416,7 @@ static int build_sg_fd(struct dpaa2_eth_priv *priv, dpaa2_fd_set_format(fd, dpaa2_fd_sg); dpaa2_fd_set_addr(fd, addr); dpaa2_fd_set_len(fd, skb->len); - dpaa2_fd_set_ctrl(fd, DPAA2_FD_CTRL_ASAL | DPAA2_FD_CTRL_PTA | - DPAA2_FD_CTRL_PTV1); + dpaa2_fd_set_ctrl(fd, DPAA2_FD_CTRL_PTA | DPAA2_FD_CTRL_PTV1); return 0; @@ -444,22 +435,19 @@ static int build_single_fd(struct dpaa2_eth_priv *priv, struct dpaa2_fd *fd) { struct device *dev = priv->net_dev->dev.parent; - u8 *buffer_start; - struct dpaa2_fas *fas; + u8 *buffer_start, *aligned_start; struct sk_buff **skbh; dma_addr_t addr; - buffer_start = PTR_ALIGN(skb->data - priv->tx_data_offset - - DPAA2_ETH_TX_BUF_ALIGN, - DPAA2_ETH_TX_BUF_ALIGN); + buffer_start = skb->data - dpaa2_eth_needed_headroom(priv, skb); - /* PTA from egress side is passed as is to the confirmation side so - * we need to clear some fields here in order to find consistent values - * on TX confirmation. We are clearing FAS (Frame Annotation Status) - * field from the hardware annotation area + /* If there's enough room to align the FD address, do it. + * It will help hardware optimize accesses. */ - fas = dpaa2_get_fas(buffer_start); - memset(fas, 0, DPAA2_FAS_SIZE); + aligned_start = PTR_ALIGN(buffer_start - DPAA2_ETH_TX_BUF_ALIGN, + DPAA2_ETH_TX_BUF_ALIGN); + if (aligned_start >= skb->head) + buffer_start = aligned_start; /* Store a backpointer to the skb at the beginning of the buffer * (in the private data area) such that we can release it @@ -478,8 +466,7 @@ static int build_single_fd(struct dpaa2_eth_priv *priv, dpaa2_fd_set_offset(fd, (u16)(skb->data - buffer_start)); dpaa2_fd_set_len(fd, skb->len); dpaa2_fd_set_format(fd, dpaa2_fd_single); - dpaa2_fd_set_ctrl(fd, DPAA2_FD_CTRL_ASAL | DPAA2_FD_CTRL_PTA | - DPAA2_FD_CTRL_PTV1); + dpaa2_fd_set_ctrl(fd, DPAA2_FD_CTRL_PTA | DPAA2_FD_CTRL_PTV1); return 0; } @@ -494,8 +481,7 @@ static int build_single_fd(struct dpaa2_eth_priv *priv, * to be checked if we're on the confirmation path. */ static void free_tx_fd(const struct dpaa2_eth_priv *priv, - const struct dpaa2_fd *fd, - u32 *status) + const struct dpaa2_fd *fd) { struct device *dev = priv->net_dev->dev.parent; dma_addr_t fd_addr; @@ -506,11 +492,9 @@ static void free_tx_fd(const struct dpaa2_eth_priv *priv, int num_sg, num_dma_bufs; struct dpaa2_eth_swa *swa; u8 fd_format = dpaa2_fd_get_format(fd); - struct dpaa2_fas *fas; fd_addr = dpaa2_fd_get_addr(fd); skbh = dpaa2_iova_to_virt(priv->iommu_domain, fd_addr); - fas = dpaa2_get_fas(skbh); if (fd_format == dpaa2_fd_single) { skb = *skbh; @@ -537,19 +521,10 @@ static void free_tx_fd(const struct dpaa2_eth_priv *priv, sizeof(struct dpaa2_sg_entry) * (1 + num_dma_bufs); dma_unmap_single(dev, fd_addr, unmap_size, DMA_BIDIRECTIONAL); } else { - /* Unsupported format, mark it as errored and give up */ - if (status) - *status = ~0; + netdev_dbg(priv->net_dev, "Invalid FD format\n"); return; } - /* Read the status from the Frame Annotation after we unmap the first - * buffer but before we free it. The caller function is responsible - * for checking the status value. - */ - if (status) - *status = le32_to_cpu(fas->status); - /* Free SGT buffer kmalloc'ed on tx */ if (fd_format != dpaa2_fd_single) kfree(skbh); @@ -566,19 +541,22 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct net_device *net_dev) struct dpaa2_eth_drv_stats *percpu_extras; struct dpaa2_eth_fq *fq; u16 queue_mapping; + unsigned int needed_headroom; int err, i; percpu_stats = this_cpu_ptr(priv->percpu_stats); percpu_extras = this_cpu_ptr(priv->percpu_extras); - if (unlikely(skb_headroom(skb) < dpaa2_eth_needed_headroom(priv))) { + needed_headroom = dpaa2_eth_needed_headroom(priv, skb); + if (skb_headroom(skb) < needed_headroom) { struct sk_buff *ns; - ns = skb_realloc_headroom(skb, dpaa2_eth_needed_headroom(priv)); + ns = skb_realloc_headroom(skb, needed_headroom); if (unlikely(!ns)) { percpu_stats->tx_dropped++; goto err_alloc_headroom; } + percpu_extras->tx_reallocs++; dev_kfree_skb(skb); skb = ns; } @@ -612,13 +590,15 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct net_device *net_dev) /* Tracing point */ trace_dpaa2_tx_fd(net_dev, &fd); - /* TxConf FQ selection primarily based on cpu affinity; this is - * non-migratable context, so it's safe to call smp_processor_id(). + /* TxConf FQ selection relies on queue id from the stack. + * In case of a forwarded frame from another DPNI interface, we choose + * a queue affined to the same core that processed the Rx frame */ - queue_mapping = smp_processor_id() % dpaa2_eth_queue_count(priv); + queue_mapping = skb_get_queue_mapping(skb); fq = &priv->fq[queue_mapping]; for (i = 0; i < DPAA2_ETH_ENQUEUE_RETRIES; i++) { - err = dpaa2_io_service_enqueue_qd(NULL, priv->tx_qdid, 0, + err = dpaa2_io_service_enqueue_qd(fq->channel->dpio, + priv->tx_qdid, 0, fq->tx_qdbin, &fd); if (err != -EBUSY) break; @@ -627,7 +607,7 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct net_device *net_dev) if (unlikely(err < 0)) { percpu_stats->tx_errors++; /* Clean up everything, including freeing the skb */ - free_tx_fd(priv, &fd, NULL); + free_tx_fd(priv, &fd); } else { percpu_stats->tx_packets++; percpu_stats->tx_bytes += dpaa2_fd_get_len(&fd); @@ -646,13 +626,12 @@ err_alloc_headroom: static void dpaa2_eth_tx_conf(struct dpaa2_eth_priv *priv, struct dpaa2_eth_channel *ch, const struct dpaa2_fd *fd, - struct napi_struct *napi __always_unused) + struct napi_struct *napi __always_unused, + u16 queue_id __always_unused) { struct rtnl_link_stats64 *percpu_stats; struct dpaa2_eth_drv_stats *percpu_extras; - u32 status = 0; u32 fd_errors; - bool has_fas_errors = false; /* Tracing point */ trace_dpaa2_tx_conf_fd(priv->net_dev, fd); @@ -663,29 +642,18 @@ static void dpaa2_eth_tx_conf(struct dpaa2_eth_priv *priv, /* Check frame errors in the FD field */ fd_errors = dpaa2_fd_get_ctrl(fd) & DPAA2_FD_TX_ERR_MASK; - if (unlikely(fd_errors)) { - /* We only check error bits in the FAS field if corresponding - * FAERR bit is set in FD and the FAS field is marked as valid - */ - has_fas_errors = (fd_errors & DPAA2_FD_CTRL_FAERR) && - !!(dpaa2_fd_get_frc(fd) & DPAA2_FD_FRC_FASV); - if (net_ratelimit()) - netdev_dbg(priv->net_dev, "TX frame FD error: 0x%08x\n", - fd_errors); - } - - free_tx_fd(priv, fd, has_fas_errors ? &status : NULL); + free_tx_fd(priv, fd); if (likely(!fd_errors)) return; + if (net_ratelimit()) + netdev_dbg(priv->net_dev, "TX frame FD error: 0x%08x\n", + fd_errors); + percpu_stats = this_cpu_ptr(priv->percpu_stats); /* Tx-conf logically pertains to the egress path. */ percpu_stats->tx_errors++; - - if (has_fas_errors && net_ratelimit()) - netdev_dbg(priv->net_dev, "TX frame FAS error: 0x%08x\n", - status & DPAA2_FAS_TX_ERR_MASK); } static int set_rx_csum(struct dpaa2_eth_priv *priv, bool enable) @@ -752,7 +720,8 @@ static void free_bufs(struct dpaa2_eth_priv *priv, u64 *buf_array, int count) /* Perform a single release command to add buffers * to the specified buffer pool */ -static int add_bufs(struct dpaa2_eth_priv *priv, u16 bpid) +static int add_bufs(struct dpaa2_eth_priv *priv, + struct dpaa2_eth_channel *ch, u16 bpid) { struct device *dev = priv->net_dev->dev.parent; u64 buf_array[DPAA2_ETH_BUFS_PER_CMD]; @@ -786,7 +755,7 @@ static int add_bufs(struct dpaa2_eth_priv *priv, u16 bpid) release_bufs: /* In case the portal is busy, retry until successful */ - while ((err = dpaa2_io_service_release(NULL, bpid, + while ((err = dpaa2_io_service_release(ch->dpio, bpid, buf_array, i)) == -EBUSY) cpu_relax(); @@ -827,7 +796,7 @@ static int seed_pool(struct dpaa2_eth_priv *priv, u16 bpid) for (j = 0; j < priv->num_channels; j++) { for (i = 0; i < DPAA2_ETH_NUM_BUFS; i += DPAA2_ETH_BUFS_PER_CMD) { - new_count = add_bufs(priv, bpid); + new_count = add_bufs(priv, priv->channel[j], bpid); priv->channel[j]->buf_count += new_count; if (new_count < DPAA2_ETH_BUFS_PER_CMD) { @@ -885,7 +854,7 @@ static int refill_pool(struct dpaa2_eth_priv *priv, return 0; do { - new_count = add_bufs(priv, bpid); + new_count = add_bufs(priv, ch, bpid); if (unlikely(!new_count)) { /* Out of memory; abort for now, we'll try later on */ break; @@ -906,7 +875,8 @@ static int pull_channel(struct dpaa2_eth_channel *ch) /* Retry while portal is busy */ do { - err = dpaa2_io_service_pull_channel(NULL, ch->ch_id, ch->store); + err = dpaa2_io_service_pull_channel(ch->dpio, ch->ch_id, + ch->store); dequeues++; cpu_relax(); } while (err == -EBUSY); @@ -956,7 +926,7 @@ static int dpaa2_eth_poll(struct napi_struct *napi, int budget) if (cleaned < budget && napi_complete_done(napi, cleaned)) { /* Re-enable data available notifications */ do { - err = dpaa2_io_service_rearm(NULL, &ch->nctx); + err = dpaa2_io_service_rearm(ch->dpio, &ch->nctx); cpu_relax(); } while (err == -EBUSY); WARN_ONCE(err, "CDAN notifications rearm failed on core %d", @@ -1564,7 +1534,8 @@ static int setup_dpio(struct dpaa2_eth_priv *priv) nctx->desired_cpu = i; /* Register the new context */ - err = dpaa2_io_service_register(NULL, nctx); + channel->dpio = dpaa2_io_service_select(i); + err = dpaa2_io_service_register(channel->dpio, nctx); if (err) { dev_dbg(dev, "No affine DPIO for cpu %d\n", i); /* If no affine DPIO for this core, there's probably @@ -1604,7 +1575,7 @@ static int setup_dpio(struct dpaa2_eth_priv *priv) return 0; err_set_cdan: - dpaa2_io_service_deregister(NULL, nctx); + dpaa2_io_service_deregister(channel->dpio, nctx); err_service_reg: free_channel(priv, channel); err_alloc_ch: @@ -1627,7 +1598,7 @@ static void free_dpio(struct dpaa2_eth_priv *priv) /* deregister CDAN notifications and free channels */ for (i = 0; i < priv->num_channels; i++) { ch = priv->channel[i]; - dpaa2_io_service_deregister(NULL, &ch->nctx); + dpaa2_io_service_deregister(ch->dpio, &ch->nctx); free_channel(priv, ch); } } @@ -1653,9 +1624,10 @@ static struct dpaa2_eth_channel *get_affine_channel(struct dpaa2_eth_priv *priv, static void set_fq_affinity(struct dpaa2_eth_priv *priv) { struct device *dev = priv->net_dev->dev.parent; + struct cpumask xps_mask; struct dpaa2_eth_fq *fq; int rx_cpu, txc_cpu; - int i; + int i, err; /* For each FQ, pick one channel/CPU to deliver frames to. * This may well change at runtime, either through irqbalance or @@ -1674,6 +1646,17 @@ static void set_fq_affinity(struct dpaa2_eth_priv *priv) break; case DPAA2_TX_CONF_FQ: fq->target_cpu = txc_cpu; + + /* Tell the stack to affine to txc_cpu the Tx queue + * associated with the confirmation one + */ + cpumask_clear(&xps_mask); + cpumask_set_cpu(txc_cpu, &xps_mask); + err = netif_set_xps_queue(priv->net_dev, &xps_mask, + fq->flowid); + if (err) + dev_err(dev, "Error setting XPS queue\n"); + txc_cpu = cpumask_next(txc_cpu, &priv->dpio_cpumask); if (txc_cpu >= nr_cpu_ids) txc_cpu = cpumask_first(&priv->dpio_cpumask); @@ -1791,10 +1774,8 @@ static int set_buffer_layout(struct dpaa2_eth_priv *priv) priv->rx_buf_align = DPAA2_ETH_RX_BUF_ALIGN; /* tx buffer */ - buf_layout.pass_frame_status = true; buf_layout.private_data_size = DPAA2_ETH_SWA_SIZE; - buf_layout.options = DPNI_BUF_LAYOUT_OPT_FRAME_STATUS | - DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE; + buf_layout.options = DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE; err = dpni_set_buffer_layout(priv->mc_io, 0, priv->mc_token, DPNI_QUEUE_TX, &buf_layout); if (err) { @@ -1803,7 +1784,7 @@ static int set_buffer_layout(struct dpaa2_eth_priv *priv) } /* tx-confirm buffer */ - buf_layout.options = DPNI_BUF_LAYOUT_OPT_FRAME_STATUS; + buf_layout.options = 0; err = dpni_set_buffer_layout(priv->mc_io, 0, priv->mc_token, DPNI_QUEUE_TX_CONFIRM, &buf_layout); if (err) { @@ -1826,6 +1807,7 @@ static int set_buffer_layout(struct dpaa2_eth_priv *priv) priv->tx_data_offset); /* rx buffer */ + buf_layout.pass_frame_status = true; buf_layout.pass_parser_result = true; buf_layout.data_align = priv->rx_buf_align; buf_layout.data_head_room = dpaa2_eth_rx_head_room(priv); @@ -2273,7 +2255,6 @@ static int netdev_init(struct net_device *net_dev) { struct device *dev = net_dev->dev.parent; struct dpaa2_eth_priv *priv = netdev_priv(net_dev); - u16 rx_headroom, req_headroom; u8 bcast_addr[ETH_ALEN]; u8 num_queues; int err; @@ -2292,24 +2273,6 @@ static int netdev_init(struct net_device *net_dev) return err; } - /* Reserve enough space to align buffer as per hardware requirement; - * NOTE: priv->tx_data_offset MUST be initialized at this point. - */ - net_dev->needed_headroom = dpaa2_eth_needed_headroom(priv); - - /* If headroom guaranteed by hardware in the Rx frame buffer is - * smaller than the Tx headroom required by the stack, issue a - * one time warning. This will most likely mean skbs forwarded to - * another DPAA2 network interface will get reallocated, with a - * significant performance impact. - */ - req_headroom = LL_RESERVED_SPACE(net_dev) - ETH_HLEN; - rx_headroom = ALIGN(DPAA2_ETH_RX_HWA_SIZE + - dpaa2_eth_rx_head_room(priv), priv->rx_buf_align); - if (req_headroom > rx_headroom) - dev_info_once(dev, "Required headroom (%d) greater than available (%d)\n", - req_headroom, rx_headroom); - /* Set MTU limits */ net_dev->min_mtu = 68; net_dev->max_mtu = DPAA2_ETH_MAX_MTU; diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h index 5b3ab9f62d5e..e577410fdf4f 100644 --- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h +++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h @@ -134,7 +134,6 @@ struct dpaa2_eth_swa { DPAA2_FD_CTRL_FAERR) /* Annotation bits in FD CTRL */ -#define DPAA2_FD_CTRL_ASAL 0x00010000 /* ASAL = 64 */ #define DPAA2_FD_CTRL_PTA 0x00800000 #define DPAA2_FD_CTRL_PTV1 0x00400000 @@ -153,10 +152,15 @@ struct dpaa2_fas { #define DPAA2_FAS_SIZE (sizeof(struct dpaa2_fas)) /* Accessors for the hardware annotation fields that we use */ -#define dpaa2_get_hwa(buf_addr) \ - ((void *)(buf_addr) + DPAA2_ETH_SWA_SIZE) -#define dpaa2_get_fas(buf_addr) \ - (struct dpaa2_fas *)(dpaa2_get_hwa(buf_addr) + DPAA2_FAS_OFFSET) +static inline void *dpaa2_get_hwa(void *buf_addr, bool swa) +{ + return buf_addr + (swa ? DPAA2_ETH_SWA_SIZE : 0); +} + +static inline struct dpaa2_fas *dpaa2_get_fas(void *buf_addr, bool swa) +{ + return dpaa2_get_hwa(buf_addr, swa) + DPAA2_FAS_OFFSET; +} /* Error and status bits in the frame annotation status word */ /* Debug frame, otherwise supposed to be discarded */ @@ -203,11 +207,6 @@ struct dpaa2_fas { DPAA2_FAS_BLE | \ DPAA2_FAS_L3CE | \ DPAA2_FAS_L4CE) -/* Tx errors */ -#define DPAA2_FAS_TX_ERR_MASK (DPAA2_FAS_KSE | \ - DPAA2_FAS_EOFHE | \ - DPAA2_FAS_MNLE | \ - DPAA2_FAS_TIDE) /* Time in milliseconds between link state updates */ #define DPAA2_ETH_LINK_STATE_REFRESH 1000 @@ -226,6 +225,7 @@ struct dpaa2_eth_drv_stats { __u64 tx_conf_bytes; __u64 tx_sg_frames; __u64 tx_sg_bytes; + __u64 tx_reallocs; __u64 rx_sg_frames; __u64 rx_sg_bytes; /* Enqueues retried due to portal busy */ @@ -276,7 +276,8 @@ struct dpaa2_eth_fq { void (*consume)(struct dpaa2_eth_priv *, struct dpaa2_eth_channel *, const struct dpaa2_fd *, - struct napi_struct *); + struct napi_struct *, + u16 queue_id); struct dpaa2_eth_fq_stats stats; }; @@ -287,6 +288,7 @@ struct dpaa2_eth_channel { int ch_id; int dpio_id; struct napi_struct napi; + struct dpaa2_io *dpio; struct dpaa2_io_store *store; struct dpaa2_eth_priv *priv; int buf_count; @@ -364,9 +366,13 @@ static inline unsigned int dpaa2_eth_buf_raw_size(struct dpaa2_eth_priv *priv) } static inline -unsigned int dpaa2_eth_needed_headroom(struct dpaa2_eth_priv *priv) +unsigned int dpaa2_eth_needed_headroom(struct dpaa2_eth_priv *priv, + struct sk_buff *skb) { - return priv->tx_data_offset + DPAA2_ETH_TX_BUF_ALIGN - HH_DATA_MOD; + if (skb_is_nonlinear(skb)) + return 0; + + return DPAA2_ETH_SWA_SIZE; } /* Extra headroom space requested to hardware, in order to make sure there's @@ -374,7 +380,8 @@ unsigned int dpaa2_eth_needed_headroom(struct dpaa2_eth_priv *priv) */ static inline unsigned int dpaa2_eth_rx_head_room(struct dpaa2_eth_priv *priv) { - return dpaa2_eth_needed_headroom(priv) - DPAA2_ETH_RX_HWA_SIZE; + return priv->tx_data_offset + DPAA2_ETH_TX_BUF_ALIGN - + DPAA2_ETH_RX_HWA_SIZE; } static int dpaa2_eth_queue_count(struct dpaa2_eth_priv *priv) diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-ethtool.c b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-ethtool.c index ebe8fd6ccf2c..070a3f2a0523 100644 --- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-ethtool.c +++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-ethtool.c @@ -62,6 +62,7 @@ static char dpaa2_ethtool_extras[][ETH_GSTRING_LEN] = { "[drv] tx conf bytes", "[drv] tx sg frames", "[drv] tx sg bytes", + "[drv] tx realloc frames", "[drv] rx sg frames", "[drv] rx sg bytes", "[drv] enqueue portal busy", diff --git a/drivers/staging/fsl-mc/Kconfig b/drivers/staging/fsl-mc/Kconfig index 32df07b15e09..3002229bec1b 100644 --- a/drivers/staging/fsl-mc/Kconfig +++ b/drivers/staging/fsl-mc/Kconfig @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 source "drivers/staging/fsl-mc/bus/Kconfig" diff --git a/drivers/staging/fsl-mc/Makefile b/drivers/staging/fsl-mc/Makefile index 9c6a00128c65..14683889dabd 100644 --- a/drivers/staging/fsl-mc/Makefile +++ b/drivers/staging/fsl-mc/Makefile @@ -1,2 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 # Freescale Management Complex (MC) bus drivers obj-$(CONFIG_FSL_MC_BUS) += bus/ diff --git a/drivers/staging/fsl-mc/README.txt b/drivers/staging/fsl-mc/README.txt deleted file mode 100644 index 524eda1de04f..000000000000 --- a/drivers/staging/fsl-mc/README.txt +++ /dev/null @@ -1,386 +0,0 @@ -Copyright (C) 2015 Freescale Semiconductor Inc. - -DPAA2 (Data Path Acceleration Architecture Gen2) ------------------------------------------------- - -This document provides an overview of the Freescale DPAA2 architecture -and how it is integrated into the Linux kernel. - -Contents summary - -DPAA2 overview - -Overview of DPAA2 objects - -DPAA2 Linux driver architecture overview - -bus driver - -DPRC driver - -allocator - -DPIO driver - -Ethernet - -MAC - -DPAA2 Overview --------------- - -DPAA2 is a hardware architecture designed for high-speeed network -packet processing. DPAA2 consists of sophisticated mechanisms for -processing Ethernet packets, queue management, buffer management, -autonomous L2 switching, virtual Ethernet bridging, and accelerator -(e.g. crypto) sharing. - -A DPAA2 hardware component called the Management Complex (or MC) manages the -DPAA2 hardware resources. The MC provides an object-based abstraction for -software drivers to use the DPAA2 hardware. - -The MC uses DPAA2 hardware resources such as queues, buffer pools, and -network ports to create functional objects/devices such as network -interfaces, an L2 switch, or accelerator instances. - -The MC provides memory-mapped I/O command interfaces (MC portals) -which DPAA2 software drivers use to operate on DPAA2 objects: - -The diagram below shows an overview of the DPAA2 resource management -architecture: - - +--------------------------------------+ - | OS | - | DPAA2 drivers | - | | | - +-----------------------------|--------+ - | - | (create,discover,connect - | config,use,destroy) - | - DPAA2 | - +------------------------| mc portal |-+ - | | | - | +- - - - - - - - - - - - -V- - -+ | - | | | | - | | Management Complex (MC) | | - | | | | - | +- - - - - - - - - - - - - - - -+ | - | | - | Hardware Hardware | - | Resources Objects | - | --------- ------- | - | -queues -DPRC | - | -buffer pools -DPMCP | - | -Eth MACs/ports -DPIO | - | -network interface -DPNI | - | profiles -DPMAC | - | -queue portals -DPBP | - | -MC portals ... | - | ... | - | | - +--------------------------------------+ - -The MC mediates operations such as create, discover, -connect, configuration, and destroy. Fast-path operations -on data, such as packet transmit/receive, are not mediated by -the MC and are done directly using memory mapped regions in -DPIO objects. - -Overview of DPAA2 Objects -------------------------- -The section provides a brief overview of some key DPAA2 objects. -A simple scenario is described illustrating the objects involved -in creating a network interfaces. - --DPRC (Datapath Resource Container) - - A DPRC is a container object that holds all the other - types of DPAA2 objects. In the example diagram below there - are 8 objects of 5 types (DPMCP, DPIO, DPBP, DPNI, and DPMAC) - in the container. - - +---------------------------------------------------------+ - | DPRC | - | | - | +-------+ +-------+ +-------+ +-------+ +-------+ | - | | DPMCP | | DPIO | | DPBP | | DPNI | | DPMAC | | - | +-------+ +-------+ +-------+ +---+---+ +---+---+ | - | | DPMCP | | DPIO | | - | +-------+ +-------+ | - | | DPMCP | | - | +-------+ | - | | - +---------------------------------------------------------+ - - From the point of view of an OS, a DPRC behaves similar to a plug and - play bus, like PCI. DPRC commands can be used to enumerate the contents - of the DPRC, discover the hardware objects present (including mappable - regions and interrupts). - - DPRC.1 (bus) - | - +--+--------+-------+-------+-------+ - | | | | | - DPMCP.1 DPIO.1 DPBP.1 DPNI.1 DPMAC.1 - DPMCP.2 DPIO.2 - DPMCP.3 - - Hardware objects can be created and destroyed dynamically, providing - the ability to hot plug/unplug objects in and out of the DPRC. - - A DPRC has a mappable MMIO region (an MC portal) that can be used - to send MC commands. It has an interrupt for status events (like - hotplug). - - All objects in a container share the same hardware "isolation context". - This means that with respect to an IOMMU the isolation granularity - is at the DPRC (container) level, not at the individual object - level. - - DPRCs can be defined statically and populated with objects - via a config file passed to the MC when firmware starts - it. - --DPAA2 Objects for an Ethernet Network Interface - - A typical Ethernet NIC is monolithic-- the NIC device contains TX/RX - queuing mechanisms, configuration mechanisms, buffer management, - physical ports, and interrupts. DPAA2 uses a more granular approach - utilizing multiple hardware objects. Each object provides specialized - functions. Groups of these objects are used by software to provide - Ethernet network interface functionality. This approach provides - efficient use of finite hardware resources, flexibility, and - performance advantages. - - The diagram below shows the objects needed for a simple - network interface configuration on a system with 2 CPUs. - - +---+---+ +---+---+ - CPU0 CPU1 - +---+---+ +---+---+ - | | - +---+---+ +---+---+ - DPIO DPIO - +---+---+ +---+---+ - \ / - \ / - \ / - +---+---+ - DPNI --- DPBP,DPMCP - +---+---+ - | - | - +---+---+ - DPMAC - +---+---+ - | - port/PHY - - Below the objects are described. For each object a brief description - is provided along with a summary of the kinds of operations the object - supports and a summary of key resources of the object (MMIO regions - and IRQs). - - -DPMAC (Datapath Ethernet MAC): represents an Ethernet MAC, a - hardware device that connects to an Ethernet PHY and allows - physical transmission and reception of Ethernet frames. - -MMIO regions: none - -IRQs: DPNI link change - -commands: set link up/down, link config, get stats, - IRQ config, enable, reset - - -DPNI (Datapath Network Interface): contains TX/RX queues, - network interface configuration, and RX buffer pool configuration - mechanisms. The TX/RX queues are in memory and are identified by - queue number. - -MMIO regions: none - -IRQs: link state - -commands: port config, offload config, queue config, - parse/classify config, IRQ config, enable, reset - - -DPIO (Datapath I/O): provides interfaces to enqueue and dequeue - packets and do hardware buffer pool management operations. The DPAA2 - architecture separates the mechanism to access queues (the DPIO object) - from the queues themselves. The DPIO provides an MMIO interface to - enqueue/dequeue packets. To enqueue something a descriptor is written - to the DPIO MMIO region, which includes the target queue number. - There will typically be one DPIO assigned to each CPU. This allows all - CPUs to simultaneously perform enqueue/dequeued operations. DPIOs are - expected to be shared by different DPAA2 drivers. - -MMIO regions: queue operations, buffer management - -IRQs: data availability, congestion notification, buffer - pool depletion - -commands: IRQ config, enable, reset - - -DPBP (Datapath Buffer Pool): represents a hardware buffer - pool. - -MMIO regions: none - -IRQs: none - -commands: enable, reset - - -DPMCP (Datapath MC Portal): provides an MC command portal. - Used by drivers to send commands to the MC to manage - objects. - -MMIO regions: MC command portal - -IRQs: command completion - -commands: IRQ config, enable, reset - - Object Connections - ------------------ - Some objects have explicit relationships that must - be configured: - - -DPNI <--> DPMAC - -DPNI <--> DPNI - -DPNI <--> L2-switch-port - A DPNI must be connected to something such as a DPMAC, - another DPNI, or L2 switch port. The DPNI connection - is made via a DPRC command. - - +-------+ +-------+ - | DPNI | | DPMAC | - +---+---+ +---+---+ - | | - +==========+ - - -DPNI <--> DPBP - A network interface requires a 'buffer pool' (DPBP - object) which provides a list of pointers to memory - where received Ethernet data is to be copied. The - Ethernet driver configures the DPBPs associated with - the network interface. - - Interrupts - ---------- - All interrupts generated by DPAA2 objects are message - interrupts. At the hardware level message interrupts - generated by devices will normally have 3 components-- - 1) a non-spoofable 'device-id' expressed on the hardware - bus, 2) an address, 3) a data value. - - In the case of DPAA2 devices/objects, all objects in the - same container/DPRC share the same 'device-id'. - For ARM-based SoC this is the same as the stream ID. - - -DPAA2 Linux Driver Overview ---------------------------- - -This section provides an overview of the Linux kernel drivers for -DPAA2-- 1) the bus driver and associated "DPAA2 infrastructure" -drivers and 2) functional object drivers (such as Ethernet). - -As described previously, a DPRC is a container that holds the other -types of DPAA2 objects. It is functionally similar to a plug-and-play -bus controller. - -Each object in the DPRC is a Linux "device" and is bound to a driver. -The diagram below shows the Linux drivers involved in a networking -scenario and the objects bound to each driver. A brief description -of each driver follows. - - +------------+ - | OS Network | - | Stack | - +------------+ +------------+ - | Allocator |. . . . . . . | Ethernet | - |(DPMCP,DPBP)| | (DPNI) | - +-.----------+ +---+---+----+ - . . ^ | - . . <data avail, | |<enqueue, - . . tx confirm> | | dequeue> - +-------------+ . | | - | DPRC driver | . +---+---V----+ +---------+ - | (DPRC) | . . . . . .| DPIO driver| | MAC | - +----------+--+ | (DPIO) | | (DPMAC) | - | +------+-----+ +-----+---+ - |<dev add/remove> | | - | | | - +----+--------------+ | +--+---+ - | MC-bus driver | | | PHY | - | | | |driver| - | /soc/fsl-mc | | +--+---+ - +-------------------+ | | - | | - ================================ HARDWARE =========|=================|====== - DPIO | - | | - DPNI---DPBP | - | | - DPMAC | - | | - PHY ---------------+ - ===================================================|======================== - -A brief description of each driver is provided below. - - MC-bus driver - ------------- - The MC-bus driver is a platform driver and is probed from a - node in the device tree (compatible "fsl,qoriq-mc") passed in by boot - firmware. It is responsible for bootstrapping the DPAA2 kernel - infrastructure. - Key functions include: - -registering a new bus type named "fsl-mc" with the kernel, - and implementing bus call-backs (e.g. match/uevent/dev_groups) - -implementing APIs for DPAA2 driver registration and for device - add/remove - -creates an MSI IRQ domain - -doing a 'device add' to expose the 'root' DPRC, in turn triggering - a bind of the root DPRC to the DPRC driver - The binding for the MC-bus device-tree node can be consulted here: - Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt - - DPRC driver - ----------- - The DPRC driver is bound to DPRC objects and does runtime management - of a bus instance. It performs the initial bus scan of the DPRC - and handles interrupts for container events such as hot plug by - re-scanning the DPRC. - - Allocator - ---------- - Certain objects such as DPMCP and DPBP are generic and fungible, - and are intended to be used by other drivers. For example, - the DPAA2 Ethernet driver needs: - -DPMCPs to send MC commands, to configure network interfaces - -DPBPs for network buffer pools - - The allocator driver registers for these allocatable object types - and those objects are bound to the allocator when the bus is probed. - The allocator maintains a pool of objects that are available for - allocation by other DPAA2 drivers. - - DPIO driver - ----------- - The DPIO driver is bound to DPIO objects and provides services that allow - other drivers such as the Ethernet driver to enqueue and dequeue data for - their respective objects. - Key services include: - -data availability notifications - -hardware queuing operations (enqueue and dequeue of data) - -hardware buffer pool management - - To transmit a packet the Ethernet driver puts data on a queue and - invokes a DPIO API. For receive, the Ethernet driver registers - a data availability notification callback. To dequeue a packet - a DPIO API is used. - - There is typically one DPIO object per physical CPU for optimum - performance, allowing different CPUs to simultaneously enqueue - and dequeue data. - - The DPIO driver operates on behalf of all DPAA2 drivers - active in the kernel-- Ethernet, crypto, compression, - etc. - - Ethernet - -------- - The Ethernet driver is bound to a DPNI and implements the kernel - interfaces needed to connect the DPAA2 network interface to - the network stack. - - Each DPNI corresponds to a Linux network interface. - - MAC driver - ---------- - An Ethernet PHY is an off-chip, board specific component and is managed - by the appropriate PHY driver via an mdio bus. The MAC driver - plays a role of being a proxy between the PHY driver and the - MC. It does this proxy via the MC commands to a DPMAC object. - If the PHY driver signals a link change, the MAC driver notifies - the MC via a DPMAC command. If a network interface is brought - up or down, the MC notifies the DPMAC driver via an interrupt and - the driver can take appropriate action. diff --git a/drivers/staging/fsl-mc/bus/Kconfig b/drivers/staging/fsl-mc/bus/Kconfig index 504c987447f2..1f9100049176 100644 --- a/drivers/staging/fsl-mc/bus/Kconfig +++ b/drivers/staging/fsl-mc/bus/Kconfig @@ -1,10 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 # # DPAA2 fsl-mc bus # # Copyright (C) 2014-2016 Freescale Semiconductor, Inc. # -# This file is released under the GPLv2 -# config FSL_MC_BUS bool "QorIQ DPAA2 fsl-mc bus driver" diff --git a/drivers/staging/fsl-mc/bus/Makefile b/drivers/staging/fsl-mc/bus/Makefile index 6df407edfade..29059db95ecc 100644 --- a/drivers/staging/fsl-mc/bus/Makefile +++ b/drivers/staging/fsl-mc/bus/Makefile @@ -1,10 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 # # Freescale Management Complex (MC) bus drivers # # Copyright (C) 2014 Freescale Semiconductor, Inc. # -# This file is released under the GPLv2 -# obj-$(CONFIG_FSL_MC_BUS) += mc-bus-driver.o mc-bus-driver-objs := fsl-mc-bus.o \ diff --git a/drivers/staging/fsl-mc/bus/dpbp-cmd.h b/drivers/staging/fsl-mc/bus/dpbp-cmd.h index 5904836fd741..0b7f5c041f19 100644 --- a/drivers/staging/fsl-mc/bus/dpbp-cmd.h +++ b/drivers/staging/fsl-mc/bus/dpbp-cmd.h @@ -1,33 +1,7 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ /* * Copyright 2013-2016 Freescale Semiconductor Inc. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ #ifndef _FSL_DPBP_CMD_H #define _FSL_DPBP_CMD_H diff --git a/drivers/staging/fsl-mc/bus/dpbp.c b/drivers/staging/fsl-mc/bus/dpbp.c index 363730a80cbb..a4df84668d5b 100644 --- a/drivers/staging/fsl-mc/bus/dpbp.c +++ b/drivers/staging/fsl-mc/bus/dpbp.c @@ -1,33 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* * Copyright 2013-2016 Freescale Semiconductor Inc. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ #include <linux/kernel.h> #include "../include/mc.h" @@ -77,7 +51,7 @@ int dpbp_open(struct fsl_mc_io *mc_io, return err; } -EXPORT_SYMBOL(dpbp_open); +EXPORT_SYMBOL_GPL(dpbp_open); /** * dpbp_close() - Close the control session of the object @@ -103,7 +77,7 @@ int dpbp_close(struct fsl_mc_io *mc_io, /* send command to mc*/ return mc_send_command(mc_io, &cmd); } -EXPORT_SYMBOL(dpbp_close); +EXPORT_SYMBOL_GPL(dpbp_close); /** * dpbp_enable() - Enable the DPBP. @@ -126,7 +100,7 @@ int dpbp_enable(struct fsl_mc_io *mc_io, /* send command to mc*/ return mc_send_command(mc_io, &cmd); } -EXPORT_SYMBOL(dpbp_enable); +EXPORT_SYMBOL_GPL(dpbp_enable); /** * dpbp_disable() - Disable the DPBP. @@ -149,7 +123,7 @@ int dpbp_disable(struct fsl_mc_io *mc_io, /* send command to mc*/ return mc_send_command(mc_io, &cmd); } -EXPORT_SYMBOL(dpbp_disable); +EXPORT_SYMBOL_GPL(dpbp_disable); /** * dpbp_is_enabled() - Check if the DPBP is enabled. @@ -183,7 +157,7 @@ int dpbp_is_enabled(struct fsl_mc_io *mc_io, return 0; } -EXPORT_SYMBOL(dpbp_is_enabled); +EXPORT_SYMBOL_GPL(dpbp_is_enabled); /** * dpbp_reset() - Reset the DPBP, returns the object to initial state. @@ -206,7 +180,7 @@ int dpbp_reset(struct fsl_mc_io *mc_io, /* send command to mc*/ return mc_send_command(mc_io, &cmd); } -EXPORT_SYMBOL(dpbp_reset); +EXPORT_SYMBOL_GPL(dpbp_reset); /** * dpbp_get_attributes - Retrieve DPBP attributes. @@ -243,7 +217,7 @@ int dpbp_get_attributes(struct fsl_mc_io *mc_io, return 0; } -EXPORT_SYMBOL(dpbp_get_attributes); +EXPORT_SYMBOL_GPL(dpbp_get_attributes); /** * dpbp_get_api_version - Get Data Path Buffer Pool API version @@ -276,4 +250,4 @@ int dpbp_get_api_version(struct fsl_mc_io *mc_io, return 0; } -EXPORT_SYMBOL(dpbp_get_api_version); +EXPORT_SYMBOL_GPL(dpbp_get_api_version); diff --git a/drivers/staging/fsl-mc/bus/dpcon-cmd.h b/drivers/staging/fsl-mc/bus/dpcon-cmd.h index 2bb66988ecf6..27fa09877970 100644 --- a/drivers/staging/fsl-mc/bus/dpcon-cmd.h +++ b/drivers/staging/fsl-mc/bus/dpcon-cmd.h @@ -1,33 +1,7 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ /* * Copyright 2013-2016 Freescale Semiconductor Inc. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ #ifndef _FSL_DPCON_CMD_H #define _FSL_DPCON_CMD_H @@ -45,13 +19,11 @@ /* Command IDs */ #define DPCON_CMDID_CLOSE DPCON_CMD(0x800) #define DPCON_CMDID_OPEN DPCON_CMD(0x808) -#define DPCON_CMDID_GET_API_VERSION DPCON_CMD(0xa08) #define DPCON_CMDID_ENABLE DPCON_CMD(0x002) #define DPCON_CMDID_DISABLE DPCON_CMD(0x003) #define DPCON_CMDID_GET_ATTR DPCON_CMD(0x004) #define DPCON_CMDID_RESET DPCON_CMD(0x005) -#define DPCON_CMDID_IS_ENABLED DPCON_CMD(0x006) #define DPCON_CMDID_SET_NOTIFICATION DPCON_CMD(0x100) @@ -61,10 +33,6 @@ struct dpcon_cmd_open { #define DPCON_ENABLE 1 -struct dpcon_rsp_is_enabled { - u8 enabled; -}; - struct dpcon_rsp_get_attr { /* response word 0 */ __le32 id; diff --git a/drivers/staging/fsl-mc/bus/dpcon.c b/drivers/staging/fsl-mc/bus/dpcon.c index ca1da85c6dda..8f84d7b5465c 100644 --- a/drivers/staging/fsl-mc/bus/dpcon.c +++ b/drivers/staging/fsl-mc/bus/dpcon.c @@ -1,33 +1,7 @@ -/* Copyright 2013-2016 Freescale Semiconductor Inc. +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright 2013-2016 Freescale Semiconductor Inc. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ #include <linux/kernel.h> #include "../include/mc.h" @@ -78,7 +52,7 @@ int dpcon_open(struct fsl_mc_io *mc_io, return 0; } -EXPORT_SYMBOL(dpcon_open); +EXPORT_SYMBOL_GPL(dpcon_open); /** * dpcon_close() - Close the control session of the object @@ -105,7 +79,7 @@ int dpcon_close(struct fsl_mc_io *mc_io, /* send command to mc*/ return mc_send_command(mc_io, &cmd); } -EXPORT_SYMBOL(dpcon_close); +EXPORT_SYMBOL_GPL(dpcon_close); /** * dpcon_enable() - Enable the DPCON @@ -129,7 +103,7 @@ int dpcon_enable(struct fsl_mc_io *mc_io, /* send command to mc*/ return mc_send_command(mc_io, &cmd); } -EXPORT_SYMBOL(dpcon_enable); +EXPORT_SYMBOL_GPL(dpcon_enable); /** * dpcon_disable() - Disable the DPCON @@ -153,43 +127,7 @@ int dpcon_disable(struct fsl_mc_io *mc_io, /* send command to mc*/ return mc_send_command(mc_io, &cmd); } -EXPORT_SYMBOL(dpcon_disable); - -/** - * dpcon_is_enabled() - Check if the DPCON is enabled. - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPCON object - * @en: Returns '1' if object is enabled; '0' otherwise - * - * Return: '0' on Success; Error code otherwise. - */ -int dpcon_is_enabled(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - int *en) -{ - struct mc_command cmd = { 0 }; - struct dpcon_rsp_is_enabled *dpcon_rsp; - int err; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPCON_CMDID_IS_ENABLED, - cmd_flags, - token); - - /* send command to mc*/ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - dpcon_rsp = (struct dpcon_rsp_is_enabled *)cmd.params; - *en = dpcon_rsp->enabled & DPCON_ENABLE; - - return 0; -} -EXPORT_SYMBOL(dpcon_is_enabled); +EXPORT_SYMBOL_GPL(dpcon_disable); /** * dpcon_reset() - Reset the DPCON, returns the object to initial state. @@ -212,7 +150,7 @@ int dpcon_reset(struct fsl_mc_io *mc_io, /* send command to mc*/ return mc_send_command(mc_io, &cmd); } -EXPORT_SYMBOL(dpcon_reset); +EXPORT_SYMBOL_GPL(dpcon_reset); /** * dpcon_get_attributes() - Retrieve DPCON attributes. @@ -250,7 +188,7 @@ int dpcon_get_attributes(struct fsl_mc_io *mc_io, return 0; } -EXPORT_SYMBOL(dpcon_get_attributes); +EXPORT_SYMBOL_GPL(dpcon_get_attributes); /** * dpcon_set_notification() - Set DPCON notification destination @@ -281,37 +219,4 @@ int dpcon_set_notification(struct fsl_mc_io *mc_io, /* send command to mc*/ return mc_send_command(mc_io, &cmd); } -EXPORT_SYMBOL(dpcon_set_notification); - -/** - * dpcon_get_api_version - Get Data Path Concentrator API version - * @mc_io: Pointer to MC portal's DPCON object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @major_ver: Major version of DPCON API - * @minor_ver: Minor version of DPCON API - * - * Return: '0' on Success; Error code otherwise - */ -int dpcon_get_api_version(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 *major_ver, - u16 *minor_ver) -{ - struct mc_command cmd = { 0 }; - int err; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPCON_CMDID_GET_API_VERSION, - cmd_flags, 0); - - /* send command to mc */ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - mc_cmd_read_api_version(&cmd, major_ver, minor_ver); - - return 0; -} -EXPORT_SYMBOL(dpcon_get_api_version); +EXPORT_SYMBOL_GPL(dpcon_set_notification); diff --git a/drivers/staging/fsl-mc/bus/dpio/Makefile b/drivers/staging/fsl-mc/bus/dpio/Makefile index 837d3303e11d..53ba84d7b884 100644 --- a/drivers/staging/fsl-mc/bus/dpio/Makefile +++ b/drivers/staging/fsl-mc/bus/dpio/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # # QorIQ DPAA2 DPIO driver # diff --git a/drivers/staging/fsl-mc/bus/dpio/dpio-cmd.h b/drivers/staging/fsl-mc/bus/dpio/dpio-cmd.h index b2dc6e766f09..ab8f82ee7ee5 100644 --- a/drivers/staging/fsl-mc/bus/dpio/dpio-cmd.h +++ b/drivers/staging/fsl-mc/bus/dpio/dpio-cmd.h @@ -1,34 +1,8 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ /* * Copyright 2013-2016 Freescale Semiconductor Inc. * Copyright 2016 NXP * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ #ifndef _FSL_DPIO_CMD_H #define _FSL_DPIO_CMD_H diff --git a/drivers/staging/fsl-mc/bus/dpio/dpio-driver.c b/drivers/staging/fsl-mc/bus/dpio/dpio-driver.c index e36da20a2796..b8479ef64c71 100644 --- a/drivers/staging/fsl-mc/bus/dpio/dpio-driver.c +++ b/drivers/staging/fsl-mc/bus/dpio/dpio-driver.c @@ -1,33 +1,8 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* * Copyright 2014-2016 Freescale Semiconductor Inc. * Copyright NXP 2016 * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include <linux/types.h> diff --git a/drivers/staging/fsl-mc/bus/dpio/dpio-service.c b/drivers/staging/fsl-mc/bus/dpio/dpio-service.c index a609ec82daf3..d3c8462d43e8 100644 --- a/drivers/staging/fsl-mc/bus/dpio/dpio-service.c +++ b/drivers/staging/fsl-mc/bus/dpio/dpio-service.c @@ -1,33 +1,8 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* * Copyright 2014-2016 Freescale Semiconductor Inc. * Copyright 2016 NXP * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include <linux/types.h> #include "../../include/mc.h" @@ -43,7 +18,6 @@ #include "qbman-portal.h" struct dpaa2_io { - atomic_t refs; struct dpaa2_io_desc dpio_desc; struct qbman_swp_desc swp_desc; struct qbman_swp *swp; @@ -105,6 +79,23 @@ static inline struct dpaa2_io *service_select(struct dpaa2_io *d) } /** + * dpaa2_io_service_select() - return a dpaa2_io service affined to this cpu + * @cpu: the cpu id + * + * Return the affine dpaa2_io service, or NULL if there is no service affined + * to the specified cpu. If DPAA2_IO_ANY_CPU is used, return the next available + * service. + */ +struct dpaa2_io *dpaa2_io_service_select(int cpu) +{ + if (cpu == DPAA2_IO_ANY_CPU) + return service_select(NULL); + + return service_select_by_cpu(NULL, cpu); +} +EXPORT_SYMBOL_GPL(dpaa2_io_service_select); + +/** * dpaa2_io_create() - create a dpaa2_io object. * @desc: the dpaa2_io descriptor * @@ -126,7 +117,6 @@ struct dpaa2_io *dpaa2_io_create(const struct dpaa2_io_desc *desc) return NULL; } - atomic_set(&obj->refs, 1); obj->dpio_desc = *desc; obj->swp_desc.cena_bar = obj->dpio_desc.regs_cena; obj->swp_desc.cinh_bar = obj->dpio_desc.regs_cinh; @@ -158,7 +148,6 @@ struct dpaa2_io *dpaa2_io_create(const struct dpaa2_io_desc *desc) return obj; } -EXPORT_SYMBOL(dpaa2_io_create); /** * dpaa2_io_down() - release the dpaa2_io object. @@ -171,11 +160,8 @@ EXPORT_SYMBOL(dpaa2_io_create); */ void dpaa2_io_down(struct dpaa2_io *d) { - if (!atomic_dec_and_test(&d->refs)) - return; kfree(d); } -EXPORT_SYMBOL(dpaa2_io_down); #define DPAA_POLL_MAX 32 @@ -222,7 +208,6 @@ done: qbman_swp_interrupt_set_inhibit(swp, 0); return IRQ_HANDLED; } -EXPORT_SYMBOL(dpaa2_io_irq); /** * dpaa2_io_service_register() - Prepare for servicing of FQDAN or CDAN @@ -265,7 +250,7 @@ int dpaa2_io_service_register(struct dpaa2_io *d, ctx->qman64); return 0; } -EXPORT_SYMBOL(dpaa2_io_service_register); +EXPORT_SYMBOL_GPL(dpaa2_io_service_register); /** * dpaa2_io_service_deregister - The opposite of 'register'. @@ -288,7 +273,7 @@ void dpaa2_io_service_deregister(struct dpaa2_io *service, list_del(&ctx->node); spin_unlock_irqrestore(&d->lock_notifications, irqflags); } -EXPORT_SYMBOL(dpaa2_io_service_deregister); +EXPORT_SYMBOL_GPL(dpaa2_io_service_deregister); /** * dpaa2_io_service_rearm() - Rearm the notification for the given DPIO service. @@ -322,38 +307,7 @@ int dpaa2_io_service_rearm(struct dpaa2_io *d, return err; } -EXPORT_SYMBOL(dpaa2_io_service_rearm); - -/** - * dpaa2_io_service_pull_fq() - pull dequeue functions from a fq. - * @d: the given DPIO service. - * @fqid: the given frame queue id. - * @s: the dpaa2_io_store object for the result. - * - * Return 0 for success, or error code for failure. - */ -int dpaa2_io_service_pull_fq(struct dpaa2_io *d, u32 fqid, - struct dpaa2_io_store *s) -{ - struct qbman_pull_desc pd; - int err; - - qbman_pull_desc_clear(&pd); - qbman_pull_desc_set_storage(&pd, s->vaddr, s->paddr, 1); - qbman_pull_desc_set_numframes(&pd, (u8)s->max); - qbman_pull_desc_set_fq(&pd, fqid); - - d = service_select(d); - if (!d) - return -ENODEV; - s->swp = d->swp; - err = qbman_swp_pull(d->swp, &pd); - if (err) - s->swp = NULL; - - return err; -} -EXPORT_SYMBOL(dpaa2_io_service_pull_fq); +EXPORT_SYMBOL_GPL(dpaa2_io_service_rearm); /** * dpaa2_io_service_pull_channel() - pull dequeue functions from a channel. @@ -385,34 +339,7 @@ int dpaa2_io_service_pull_channel(struct dpaa2_io *d, u32 channelid, return err; } -EXPORT_SYMBOL(dpaa2_io_service_pull_channel); - -/** - * dpaa2_io_service_enqueue_fq() - Enqueue a frame to a frame queue. - * @d: the given DPIO service. - * @fqid: the given frame queue id. - * @fd: the frame descriptor which is enqueued. - * - * Return 0 for successful enqueue, -EBUSY if the enqueue ring is not ready, - * or -ENODEV if there is no dpio service. - */ -int dpaa2_io_service_enqueue_fq(struct dpaa2_io *d, - u32 fqid, - const struct dpaa2_fd *fd) -{ - struct qbman_eq_desc ed; - - d = service_select(d); - if (!d) - return -ENODEV; - - qbman_eq_desc_clear(&ed); - qbman_eq_desc_set_no_orp(&ed, 0); - qbman_eq_desc_set_fq(&ed, fqid); - - return qbman_swp_enqueue(d->swp, &ed, fd); -} -EXPORT_SYMBOL(dpaa2_io_service_enqueue_fq); +EXPORT_SYMBOL_GPL(dpaa2_io_service_pull_channel); /** * dpaa2_io_service_enqueue_qd() - Enqueue a frame to a QD. @@ -441,7 +368,7 @@ int dpaa2_io_service_enqueue_qd(struct dpaa2_io *d, return qbman_swp_enqueue(d->swp, &ed, fd); } -EXPORT_SYMBOL(dpaa2_io_service_enqueue_qd); +EXPORT_SYMBOL_GPL(dpaa2_io_service_enqueue_qd); /** * dpaa2_io_service_release() - Release buffers to a buffer pool. @@ -468,7 +395,7 @@ int dpaa2_io_service_release(struct dpaa2_io *d, return qbman_swp_release(d->swp, &rd, buffers, num_buffers); } -EXPORT_SYMBOL(dpaa2_io_service_release); +EXPORT_SYMBOL_GPL(dpaa2_io_service_release); /** * dpaa2_io_service_acquire() - Acquire buffers from a buffer pool. @@ -499,7 +426,7 @@ int dpaa2_io_service_acquire(struct dpaa2_io *d, return err; } -EXPORT_SYMBOL(dpaa2_io_service_acquire); +EXPORT_SYMBOL_GPL(dpaa2_io_service_acquire); /* * 'Stores' are reusable memory blocks for holding dequeue results, and to @@ -553,7 +480,7 @@ struct dpaa2_io_store *dpaa2_io_store_create(unsigned int max_frames, return ret; } -EXPORT_SYMBOL(dpaa2_io_store_create); +EXPORT_SYMBOL_GPL(dpaa2_io_store_create); /** * dpaa2_io_store_destroy() - Frees the dma memory storage for dequeue @@ -567,7 +494,7 @@ void dpaa2_io_store_destroy(struct dpaa2_io_store *s) kfree(s->alloced_addr); kfree(s); } -EXPORT_SYMBOL(dpaa2_io_store_destroy); +EXPORT_SYMBOL_GPL(dpaa2_io_store_destroy); /** * dpaa2_io_store_next() - Determine when the next dequeue result is available. @@ -615,4 +542,4 @@ struct dpaa2_dq *dpaa2_io_store_next(struct dpaa2_io_store *s, int *is_last) return ret; } -EXPORT_SYMBOL(dpaa2_io_store_next); +EXPORT_SYMBOL_GPL(dpaa2_io_store_next); diff --git a/drivers/staging/fsl-mc/bus/dpio/dpio.c b/drivers/staging/fsl-mc/bus/dpio/dpio.c index 00eb22186f42..20cdeae54a74 100644 --- a/drivers/staging/fsl-mc/bus/dpio/dpio.c +++ b/drivers/staging/fsl-mc/bus/dpio/dpio.c @@ -1,34 +1,8 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* * Copyright 2013-2016 Freescale Semiconductor Inc. * Copyright 2016 NXP * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ #include <linux/kernel.h> #include "../../include/mc.h" diff --git a/drivers/staging/fsl-mc/bus/dpio/dpio.h b/drivers/staging/fsl-mc/bus/dpio/dpio.h index ced1103d157c..49194c8e45f1 100644 --- a/drivers/staging/fsl-mc/bus/dpio/dpio.h +++ b/drivers/staging/fsl-mc/bus/dpio/dpio.h @@ -1,34 +1,8 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ /* * Copyright 2013-2016 Freescale Semiconductor Inc. * Copyright 2016 NXP * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __FSL_DPIO_H #define __FSL_DPIO_H diff --git a/drivers/staging/fsl-mc/bus/dpio/qbman-portal.c b/drivers/staging/fsl-mc/bus/dpio/qbman-portal.c index 163bdac6b051..376e9ed0297a 100644 --- a/drivers/staging/fsl-mc/bus/dpio/qbman-portal.c +++ b/drivers/staging/fsl-mc/bus/dpio/qbman-portal.c @@ -1,33 +1,8 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* * Copyright (C) 2014-2016 Freescale Semiconductor, Inc. * Copyright 2016 NXP * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include <asm/cacheflush.h> diff --git a/drivers/staging/fsl-mc/bus/dpio/qbman-portal.h b/drivers/staging/fsl-mc/bus/dpio/qbman-portal.h index 842855971f34..fb8b9d35a3eb 100644 --- a/drivers/staging/fsl-mc/bus/dpio/qbman-portal.h +++ b/drivers/staging/fsl-mc/bus/dpio/qbman-portal.h @@ -1,33 +1,8 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ /* * Copyright (C) 2014-2016 Freescale Semiconductor, Inc. * Copyright 2016 NXP * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __FSL_QBMAN_PORTAL_H #define __FSL_QBMAN_PORTAL_H diff --git a/drivers/staging/fsl-mc/bus/dpmcp-cmd.h b/drivers/staging/fsl-mc/bus/dpmcp-cmd.h deleted file mode 100644 index 861b2a708af8..000000000000 --- a/drivers/staging/fsl-mc/bus/dpmcp-cmd.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2013-2016 Freescale Semiconductor Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef _FSL_DPMCP_CMD_H -#define _FSL_DPMCP_CMD_H - -/* Minimal supported DPMCP Version */ -#define DPMCP_MIN_VER_MAJOR 3 -#define DPMCP_MIN_VER_MINOR 0 - -/* Command versioning */ -#define DPMCP_CMD_BASE_VERSION 1 -#define DPMCP_CMD_ID_OFFSET 4 - -#define DPMCP_CMD(id) (((id) << DPMCP_CMD_ID_OFFSET) | DPMCP_CMD_BASE_VERSION) - -/* Command IDs */ -#define DPMCP_CMDID_CLOSE DPMCP_CMD(0x800) -#define DPMCP_CMDID_OPEN DPMCP_CMD(0x80b) -#define DPMCP_CMDID_GET_API_VERSION DPMCP_CMD(0xa0b) - -#define DPMCP_CMDID_RESET DPMCP_CMD(0x005) - -struct dpmcp_cmd_open { - __le32 dpmcp_id; -}; - -#endif /* _FSL_DPMCP_CMD_H */ diff --git a/drivers/staging/fsl-mc/bus/dpmcp.c b/drivers/staging/fsl-mc/bus/dpmcp.c index eea42f61af86..be07c77520af 100644 --- a/drivers/staging/fsl-mc/bus/dpmcp.c +++ b/drivers/staging/fsl-mc/bus/dpmcp.c @@ -1,39 +1,12 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* * Copyright 2013-2016 Freescale Semiconductor Inc. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ #include <linux/kernel.h> #include "../include/mc.h" -#include "dpmcp.h" -#include "dpmcp-cmd.h" +#include "fsl-mc-private.h" /** * dpmcp_open() - Open a control session for the specified object. @@ -124,35 +97,3 @@ int dpmcp_reset(struct fsl_mc_io *mc_io, /* send command to mc*/ return mc_send_command(mc_io, &cmd); } - -/** - * dpmcp_get_api_version - Get Data Path Management Command Portal API version - * @mc_io: Pointer to Mc portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @major_ver: Major version of Data Path Management Command Portal API - * @minor_ver: Minor version of Data Path Management Command Portal API - * - * Return: '0' on Success; Error code otherwise. - */ -int dpmcp_get_api_version(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 *major_ver, - u16 *minor_ver) -{ - struct mc_command cmd = { 0 }; - int err; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPMCP_CMDID_GET_API_VERSION, - cmd_flags, 0); - - /* send command to mc */ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - mc_cmd_read_api_version(&cmd, major_ver, minor_ver); - - return 0; -} diff --git a/drivers/staging/fsl-mc/bus/dpmcp.h b/drivers/staging/fsl-mc/bus/dpmcp.h deleted file mode 100644 index f616031e3e59..000000000000 --- a/drivers/staging/fsl-mc/bus/dpmcp.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2013-2016 Freescale Semiconductor Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef __FSL_DPMCP_H -#define __FSL_DPMCP_H - -/* - * Data Path Management Command Portal API - * Contains initialization APIs and runtime control APIs for DPMCP - */ - -struct fsl_mc_io; - -int dpmcp_open(struct fsl_mc_io *mc_io, - u32 cmd_flags, - int dpmcp_id, - u16 *token); - -int dpmcp_close(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token); - -int dpmcp_get_api_version(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 *major_ver, - u16 *minor_ver); - -int dpmcp_reset(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token); - -#endif /* __FSL_DPMCP_H */ diff --git a/drivers/staging/fsl-mc/bus/dpmng-cmd.h b/drivers/staging/fsl-mc/bus/dpmng-cmd.h deleted file mode 100644 index d1f04ac18b78..000000000000 --- a/drivers/staging/fsl-mc/bus/dpmng-cmd.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2013-2016 Freescale Semiconductor Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * dpmng-cmd.h - * - * defines portal commands - * - */ - -#ifndef __FSL_DPMNG_CMD_H -#define __FSL_DPMNG_CMD_H - -/* Command versioning */ -#define DPMNG_CMD_BASE_VERSION 1 -#define DPMNG_CMD_ID_OFFSET 4 - -#define DPMNG_CMD(id) (((id) << DPMNG_CMD_ID_OFFSET) | DPMNG_CMD_BASE_VERSION) - -/* Command IDs */ -#define DPMNG_CMDID_GET_VERSION DPMNG_CMD(0x831) - -struct dpmng_rsp_get_version { - __le32 revision; - __le32 version_major; - __le32 version_minor; -}; - -#endif /* __FSL_DPMNG_CMD_H */ diff --git a/drivers/staging/fsl-mc/bus/dprc-cmd.h b/drivers/staging/fsl-mc/bus/dprc-cmd.h deleted file mode 100644 index d9b2dcde468e..000000000000 --- a/drivers/staging/fsl-mc/bus/dprc-cmd.h +++ /dev/null @@ -1,451 +0,0 @@ -/* - * Copyright 2013-2016 Freescale Semiconductor Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * dprc-cmd.h - * - * defines dprc portal commands - * - */ - -#ifndef _FSL_DPRC_CMD_H -#define _FSL_DPRC_CMD_H - -/* Minimal supported DPRC Version */ -#define DPRC_MIN_VER_MAJOR 6 -#define DPRC_MIN_VER_MINOR 0 - -/* Command versioning */ -#define DPRC_CMD_BASE_VERSION 1 -#define DPRC_CMD_ID_OFFSET 4 - -#define DPRC_CMD(id) (((id) << DPRC_CMD_ID_OFFSET) | DPRC_CMD_BASE_VERSION) - -/* Command IDs */ -#define DPRC_CMDID_CLOSE DPRC_CMD(0x800) -#define DPRC_CMDID_OPEN DPRC_CMD(0x805) -#define DPRC_CMDID_GET_API_VERSION DPRC_CMD(0xa05) - -#define DPRC_CMDID_GET_ATTR DPRC_CMD(0x004) - -#define DPRC_CMDID_SET_IRQ DPRC_CMD(0x010) -#define DPRC_CMDID_GET_IRQ DPRC_CMD(0x011) -#define DPRC_CMDID_SET_IRQ_ENABLE DPRC_CMD(0x012) -#define DPRC_CMDID_GET_IRQ_ENABLE DPRC_CMD(0x013) -#define DPRC_CMDID_SET_IRQ_MASK DPRC_CMD(0x014) -#define DPRC_CMDID_GET_IRQ_MASK DPRC_CMD(0x015) -#define DPRC_CMDID_GET_IRQ_STATUS DPRC_CMD(0x016) -#define DPRC_CMDID_CLEAR_IRQ_STATUS DPRC_CMD(0x017) - -#define DPRC_CMDID_GET_CONT_ID DPRC_CMD(0x830) -#define DPRC_CMDID_GET_OBJ_COUNT DPRC_CMD(0x159) -#define DPRC_CMDID_GET_OBJ DPRC_CMD(0x15A) -#define DPRC_CMDID_GET_RES_COUNT DPRC_CMD(0x15B) -#define DPRC_CMDID_GET_OBJ_REG DPRC_CMD(0x15E) -#define DPRC_CMDID_SET_OBJ_IRQ DPRC_CMD(0x15F) -#define DPRC_CMDID_GET_OBJ_IRQ DPRC_CMD(0x160) - -struct dprc_cmd_open { - __le32 container_id; -}; - -struct dprc_cmd_create_container { - /* cmd word 0 */ - __le32 options; - __le16 icid; - __le16 pad0; - /* cmd word 1 */ - __le32 pad1; - __le32 portal_id; - /* cmd words 2-3 */ - u8 label[16]; -}; - -struct dprc_rsp_create_container { - /* response word 0 */ - __le64 pad0; - /* response word 1 */ - __le32 child_container_id; - __le32 pad1; - /* response word 2 */ - __le64 child_portal_addr; -}; - -struct dprc_cmd_destroy_container { - __le32 child_container_id; -}; - -struct dprc_cmd_reset_container { - __le32 child_container_id; -}; - -struct dprc_cmd_set_irq { - /* cmd word 0 */ - __le32 irq_val; - u8 irq_index; - u8 pad[3]; - /* cmd word 1 */ - __le64 irq_addr; - /* cmd word 2 */ - __le32 irq_num; -}; - -struct dprc_cmd_get_irq { - __le32 pad; - u8 irq_index; -}; - -struct dprc_rsp_get_irq { - /* response word 0 */ - __le32 irq_val; - __le32 pad; - /* response word 1 */ - __le64 irq_addr; - /* response word 2 */ - __le32 irq_num; - __le32 type; -}; - -#define DPRC_ENABLE 0x1 - -struct dprc_cmd_set_irq_enable { - u8 enable; - u8 pad[3]; - u8 irq_index; -}; - -struct dprc_cmd_get_irq_enable { - __le32 pad; - u8 irq_index; -}; - -struct dprc_rsp_get_irq_enable { - u8 enabled; -}; - -struct dprc_cmd_set_irq_mask { - __le32 mask; - u8 irq_index; -}; - -struct dprc_cmd_get_irq_mask { - __le32 pad; - u8 irq_index; -}; - -struct dprc_rsp_get_irq_mask { - __le32 mask; -}; - -struct dprc_cmd_get_irq_status { - __le32 status; - u8 irq_index; -}; - -struct dprc_rsp_get_irq_status { - __le32 status; -}; - -struct dprc_cmd_clear_irq_status { - __le32 status; - u8 irq_index; -}; - -struct dprc_rsp_get_attributes { - /* response word 0 */ - __le32 container_id; - __le16 icid; - __le16 pad; - /* response word 1 */ - __le32 options; - __le32 portal_id; -}; - -struct dprc_cmd_set_res_quota { - /* cmd word 0 */ - __le32 child_container_id; - __le16 quota; - __le16 pad; - /* cmd words 1-2 */ - u8 type[16]; -}; - -struct dprc_cmd_get_res_quota { - /* cmd word 0 */ - __le32 child_container_id; - __le32 pad; - /* cmd word 1-2 */ - u8 type[16]; -}; - -struct dprc_rsp_get_res_quota { - __le32 pad; - __le16 quota; -}; - -struct dprc_cmd_assign { - /* cmd word 0 */ - __le32 container_id; - __le32 options; - /* cmd word 1 */ - __le32 num; - __le32 id_base_align; - /* cmd word 2-3 */ - u8 type[16]; -}; - -struct dprc_cmd_unassign { - /* cmd word 0 */ - __le32 child_container_id; - __le32 options; - /* cmd word 1 */ - __le32 num; - __le32 id_base_align; - /* cmd word 2-3 */ - u8 type[16]; -}; - -struct dprc_rsp_get_pool_count { - __le32 pool_count; -}; - -struct dprc_cmd_get_pool { - __le32 pool_index; -}; - -struct dprc_rsp_get_pool { - /* response word 0 */ - __le64 pad; - /* response word 1-2 */ - u8 type[16]; -}; - -struct dprc_rsp_get_obj_count { - __le32 pad; - __le32 obj_count; -}; - -struct dprc_cmd_get_obj { - __le32 obj_index; -}; - -struct dprc_rsp_get_obj { - /* response word 0 */ - __le32 pad0; - __le32 id; - /* response word 1 */ - __le16 vendor; - u8 irq_count; - u8 region_count; - __le32 state; - /* response word 2 */ - __le16 version_major; - __le16 version_minor; - __le16 flags; - __le16 pad1; - /* response word 3-4 */ - u8 type[16]; - /* response word 5-6 */ - u8 label[16]; -}; - -struct dprc_cmd_get_obj_desc { - /* cmd word 0 */ - __le32 obj_id; - __le32 pad; - /* cmd word 1-2 */ - u8 type[16]; -}; - -struct dprc_rsp_get_obj_desc { - /* response word 0 */ - __le32 pad0; - __le32 id; - /* response word 1 */ - __le16 vendor; - u8 irq_count; - u8 region_count; - __le32 state; - /* response word 2 */ - __le16 version_major; - __le16 version_minor; - __le16 flags; - __le16 pad1; - /* response word 3-4 */ - u8 type[16]; - /* response word 5-6 */ - u8 label[16]; -}; - -struct dprc_cmd_get_res_count { - /* cmd word 0 */ - __le64 pad; - /* cmd word 1-2 */ - u8 type[16]; -}; - -struct dprc_rsp_get_res_count { - __le32 res_count; -}; - -struct dprc_cmd_get_res_ids { - /* cmd word 0 */ - u8 pad0[5]; - u8 iter_status; - __le16 pad1; - /* cmd word 1 */ - __le32 base_id; - __le32 last_id; - /* cmd word 2-3 */ - u8 type[16]; -}; - -struct dprc_rsp_get_res_ids { - /* response word 0 */ - u8 pad0[5]; - u8 iter_status; - __le16 pad1; - /* response word 1 */ - __le32 base_id; - __le32 last_id; -}; - -struct dprc_cmd_get_obj_region { - /* cmd word 0 */ - __le32 obj_id; - __le16 pad0; - u8 region_index; - u8 pad1; - /* cmd word 1-2 */ - __le64 pad2[2]; - /* cmd word 3-4 */ - u8 obj_type[16]; -}; - -struct dprc_rsp_get_obj_region { - /* response word 0 */ - __le64 pad; - /* response word 1 */ - __le64 base_addr; - /* response word 2 */ - __le32 size; -}; - -struct dprc_cmd_set_obj_label { - /* cmd word 0 */ - __le32 obj_id; - __le32 pad; - /* cmd word 1-2 */ - u8 label[16]; - /* cmd word 3-4 */ - u8 obj_type[16]; -}; - -struct dprc_cmd_set_obj_irq { - /* cmd word 0 */ - __le32 irq_val; - u8 irq_index; - u8 pad[3]; - /* cmd word 1 */ - __le64 irq_addr; - /* cmd word 2 */ - __le32 irq_num; - __le32 obj_id; - /* cmd word 3-4 */ - u8 obj_type[16]; -}; - -struct dprc_cmd_get_obj_irq { - /* cmd word 0 */ - __le32 obj_id; - u8 irq_index; - u8 pad[3]; - /* cmd word 1-2 */ - u8 obj_type[16]; -}; - -struct dprc_rsp_get_obj_irq { - /* response word 0 */ - __le32 irq_val; - __le32 pad; - /* response word 1 */ - __le64 irq_addr; - /* response word 2 */ - __le32 irq_num; - __le32 type; -}; - -struct dprc_cmd_connect { - /* cmd word 0 */ - __le32 ep1_id; - __le32 ep1_interface_id; - /* cmd word 1 */ - __le32 ep2_id; - __le32 ep2_interface_id; - /* cmd word 2-3 */ - u8 ep1_type[16]; - /* cmd word 4 */ - __le32 max_rate; - __le32 committed_rate; - /* cmd word 5-6 */ - u8 ep2_type[16]; -}; - -struct dprc_cmd_disconnect { - /* cmd word 0 */ - __le32 id; - __le32 interface_id; - /* cmd word 1-2 */ - u8 type[16]; -}; - -struct dprc_cmd_get_connection { - /* cmd word 0 */ - __le32 ep1_id; - __le32 ep1_interface_id; - /* cmd word 1-2 */ - u8 ep1_type[16]; -}; - -struct dprc_rsp_get_connection { - /* response word 0-2 */ - __le64 pad[3]; - /* response word 3 */ - __le32 ep2_id; - __le32 ep2_interface_id; - /* response word 4-5 */ - u8 ep2_type[16]; - /* response word 6 */ - __le32 state; -}; - -#endif /* _FSL_DPRC_CMD_H */ diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c b/drivers/staging/fsl-mc/bus/dprc-driver.c index 06df528f4cfc..b09075731e62 100644 --- a/drivers/staging/fsl-mc/bus/dprc-driver.c +++ b/drivers/staging/fsl-mc/bus/dprc-driver.c @@ -1,12 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Freescale data path resource container (DPRC) driver * * Copyright (C) 2014-2016 Freescale Semiconductor, Inc. * Author: German Rivera <German.Rivera@freescale.com> * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #include <linux/module.h> @@ -15,7 +13,6 @@ #include <linux/msi.h> #include "../include/mc.h" -#include "dprc-cmd.h" #include "fsl-mc-private.h" #define FSL_MC_DPRC_DRIVER_NAME "fsl_mc_dprc" @@ -39,8 +36,6 @@ static int __fsl_mc_device_remove_if_not_in_mc(struct device *dev, void *data) struct fsl_mc_child_objs *objs; struct fsl_mc_device *mc_dev; - WARN_ON(!dev); - WARN_ON(!data); mc_dev = to_fsl_mc_device(dev); objs = data; @@ -60,8 +55,6 @@ static int __fsl_mc_device_remove_if_not_in_mc(struct device *dev, void *data) static int __fsl_mc_device_remove(struct device *dev, void *data) { - WARN_ON(!dev); - WARN_ON(data); fsl_mc_device_remove(to_fsl_mc_device(dev)); return 0; } @@ -206,7 +199,8 @@ static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev, * dprc_scan_objects - Discover objects in a DPRC * * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object - * @total_irq_count: total number of IRQs needed by objects in the DPRC. + * @total_irq_count: If argument is provided the function populates the + * total number of IRQs created by objects in the DPRC. * * Detects objects added and removed from a DPRC and synchronizes the * state of the Linux bus driver, MC by adding and removing @@ -228,6 +222,7 @@ static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev, int error; unsigned int irq_count = mc_bus_dev->obj_desc.irq_count; struct fsl_mc_obj_desc *child_obj_desc_array = NULL; + struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev); error = dprc_get_obj_count(mc_bus_dev->mc_io, 0, @@ -297,7 +292,26 @@ static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev, } } - *total_irq_count = irq_count; + /* + * Allocate IRQ's before binding the scanned devices with their + * respective drivers. + */ + if (dev_get_msi_domain(&mc_bus_dev->dev) && !mc_bus->irq_resources) { + if (irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) { + dev_warn(&mc_bus_dev->dev, + "IRQs needed (%u) exceed IRQs preallocated (%u)\n", + irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS); + } + + error = fsl_mc_populate_irq_pool(mc_bus, + FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS); + if (error < 0) + return error; + } + + if (total_irq_count) + *total_irq_count = irq_count; + dprc_remove_devices(mc_bus_dev, child_obj_desc_array, num_child_objects); @@ -322,7 +336,6 @@ static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev, static int dprc_scan_container(struct fsl_mc_device *mc_bus_dev) { int error; - unsigned int irq_count; struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev); fsl_mc_init_all_resource_pools(mc_bus_dev); @@ -331,29 +344,14 @@ static int dprc_scan_container(struct fsl_mc_device *mc_bus_dev) * Discover objects in the DPRC: */ mutex_lock(&mc_bus->scan_mutex); - error = dprc_scan_objects(mc_bus_dev, &irq_count); + error = dprc_scan_objects(mc_bus_dev, NULL); mutex_unlock(&mc_bus->scan_mutex); - if (error < 0) - goto error; - - if (dev_get_msi_domain(&mc_bus_dev->dev) && !mc_bus->irq_resources) { - if (irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) { - dev_warn(&mc_bus_dev->dev, - "IRQs needed (%u) exceed IRQs preallocated (%u)\n", - irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS); - } - - error = fsl_mc_populate_irq_pool( - mc_bus, - FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS); - if (error < 0) - goto error; + if (error < 0) { + fsl_mc_cleanup_all_resource_pools(mc_bus_dev); + return error; } return 0; -error: - fsl_mc_cleanup_all_resource_pools(mc_bus_dev); - return error; } /** @@ -386,11 +384,11 @@ static irqreturn_t dprc_irq0_handler_thread(int irq_num, void *arg) dev_dbg(dev, "DPRC IRQ %d triggered on CPU %u\n", irq_num, smp_processor_id()); - if (WARN_ON(!(mc_dev->flags & FSL_MC_IS_DPRC))) + if (!(mc_dev->flags & FSL_MC_IS_DPRC)) return IRQ_HANDLED; mutex_lock(&mc_bus->scan_mutex); - if (WARN_ON(!msi_desc || msi_desc->irq != (u32)irq_num)) + if (!msi_desc || msi_desc->irq != (u32)irq_num) goto out; status = 0; @@ -453,8 +451,6 @@ static int disable_dprc_irq(struct fsl_mc_device *mc_dev) int error; struct fsl_mc_io *mc_io = mc_dev->mc_io; - WARN_ON(mc_dev->obj_desc.irq_count != 1); - /* * Disable generation of interrupt, while we configure it: */ @@ -496,8 +492,6 @@ static int register_dprc_irq_handler(struct fsl_mc_device *mc_dev) int error; struct fsl_mc_device_irq *irq = mc_dev->irqs[0]; - WARN_ON(mc_dev->obj_desc.irq_count != 1); - /* * NOTE: devm_request_threaded_irq() invokes the device-specific * function that programs the MSI physically in the device @@ -601,20 +595,20 @@ static int dprc_probe(struct fsl_mc_device *mc_dev) bool msi_domain_set = false; u16 major_ver, minor_ver; - if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0)) + if (!is_fsl_mc_bus_dprc(mc_dev)) return -EINVAL; - if (WARN_ON(dev_get_msi_domain(&mc_dev->dev))) + if (dev_get_msi_domain(&mc_dev->dev)) return -EINVAL; if (!mc_dev->mc_io) { /* * This is a child DPRC: */ - if (WARN_ON(!dev_is_fsl_mc(parent_dev))) + if (!dev_is_fsl_mc(parent_dev)) return -EINVAL; - if (WARN_ON(mc_dev->obj_desc.region_count == 0)) + if (mc_dev->obj_desc.region_count == 0) return -EINVAL; region_size = resource_size(mc_dev->regions); @@ -642,7 +636,7 @@ static int dprc_probe(struct fsl_mc_device *mc_dev) */ struct irq_domain *mc_msi_domain; - if (WARN_ON(dev_is_fsl_mc(parent_dev))) + if (dev_is_fsl_mc(parent_dev)) return -EINVAL; error = fsl_mc_find_msi_domain(parent_dev, @@ -753,12 +747,12 @@ static int dprc_remove(struct fsl_mc_device *mc_dev) int error; struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev); - if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0)) + if (!is_fsl_mc_bus_dprc(mc_dev)) return -EINVAL; - if (WARN_ON(!mc_dev->mc_io)) + if (!mc_dev->mc_io) return -EINVAL; - if (WARN_ON(!mc_bus->irq_resources)) + if (!mc_bus->irq_resources) return -EINVAL; if (dev_get_msi_domain(&mc_dev->dev)) diff --git a/drivers/staging/fsl-mc/bus/dprc.c b/drivers/staging/fsl-mc/bus/dprc.c index 6f6c65a42166..97f51726fa7e 100644 --- a/drivers/staging/fsl-mc/bus/dprc.c +++ b/drivers/staging/fsl-mc/bus/dprc.c @@ -1,39 +1,11 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* * Copyright 2013-2016 Freescale Semiconductor Inc. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ #include <linux/kernel.h> #include "../include/mc.h" -#include "dprc.h" - -#include "dprc-cmd.h" +#include "fsl-mc-private.h" /** * dprc_open() - Open DPRC object for use @@ -71,7 +43,7 @@ int dprc_open(struct fsl_mc_io *mc_io, return 0; } -EXPORT_SYMBOL(dprc_open); +EXPORT_SYMBOL_GPL(dprc_open); /** * dprc_close() - Close the control session of the object @@ -97,53 +69,7 @@ int dprc_close(struct fsl_mc_io *mc_io, /* send command to mc*/ return mc_send_command(mc_io, &cmd); } -EXPORT_SYMBOL(dprc_close); - -/** - * dprc_get_irq() - Get IRQ information from the DPRC. - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPRC object - * @irq_index: The interrupt index to configure - * @type: Interrupt type: 0 represents message interrupt - * type (both irq_addr and irq_val are valid) - * @irq_cfg: IRQ attributes - * - * Return: '0' on Success; Error code otherwise. - */ -int dprc_get_irq(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - int *type, - struct dprc_irq_cfg *irq_cfg) -{ - struct mc_command cmd = { 0 }; - struct dprc_cmd_get_irq *cmd_params; - struct dprc_rsp_get_irq *rsp_params; - int err; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_IRQ, - cmd_flags, - token); - cmd_params = (struct dprc_cmd_get_irq *)cmd.params; - cmd_params->irq_index = irq_index; - - /* send command to mc*/ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - rsp_params = (struct dprc_rsp_get_irq *)cmd.params; - irq_cfg->val = le32_to_cpu(rsp_params->irq_val); - irq_cfg->paddr = le64_to_cpu(rsp_params->irq_addr); - irq_cfg->irq_num = le32_to_cpu(rsp_params->irq_num); - *type = le32_to_cpu(rsp_params->type); - - return 0; -} +EXPORT_SYMBOL_GPL(dprc_close); /** * dprc_set_irq() - Set IRQ information for the DPRC to trigger an interrupt. @@ -179,45 +105,6 @@ int dprc_set_irq(struct fsl_mc_io *mc_io, } /** - * dprc_get_irq_enable() - Get overall interrupt state. - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPRC object - * @irq_index: The interrupt index to configure - * @en: Returned interrupt state - enable = 1, disable = 0 - * - * Return: '0' on Success; Error code otherwise. - */ -int dprc_get_irq_enable(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u8 *en) -{ - struct mc_command cmd = { 0 }; - struct dprc_cmd_get_irq_enable *cmd_params; - struct dprc_rsp_get_irq_enable *rsp_params; - int err; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_IRQ_ENABLE, - cmd_flags, token); - cmd_params = (struct dprc_cmd_get_irq_enable *)cmd.params; - cmd_params->irq_index = irq_index; - - /* send command to mc*/ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - rsp_params = (struct dprc_rsp_get_irq_enable *)cmd.params; - *en = rsp_params->enabled & DPRC_ENABLE; - - return 0; -} - -/** * dprc_set_irq_enable() - Set overall interrupt state. * @mc_io: Pointer to MC portal's I/O object * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' @@ -253,48 +140,6 @@ int dprc_set_irq_enable(struct fsl_mc_io *mc_io, } /** - * dprc_get_irq_mask() - Get interrupt mask. - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPRC object - * @irq_index: The interrupt index to configure - * @mask: Returned event mask to trigger interrupt - * - * Every interrupt can have up to 32 causes and the interrupt model supports - * masking/unmasking each cause independently - * - * Return: '0' on Success; Error code otherwise. - */ -int dprc_get_irq_mask(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u32 *mask) -{ - struct mc_command cmd = { 0 }; - struct dprc_cmd_get_irq_mask *cmd_params; - struct dprc_rsp_get_irq_mask *rsp_params; - int err; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_IRQ_MASK, - cmd_flags, token); - cmd_params = (struct dprc_cmd_get_irq_mask *)cmd.params; - cmd_params->irq_index = irq_index; - - /* send command to mc*/ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - rsp_params = (struct dprc_rsp_get_irq_mask *)cmd.params; - *mask = le32_to_cpu(rsp_params->mask); - - return 0; -} - -/** * dprc_set_irq_mask() - Set interrupt mask. * @mc_io: Pointer to MC portal's I/O object * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' @@ -475,7 +320,7 @@ int dprc_get_obj_count(struct fsl_mc_io *mc_io, return 0; } -EXPORT_SYMBOL(dprc_get_obj_count); +EXPORT_SYMBOL_GPL(dprc_get_obj_count); /** * dprc_get_obj() - Get general information on an object @@ -531,7 +376,7 @@ int dprc_get_obj(struct fsl_mc_io *mc_io, obj_desc->label[15] = '\0'; return 0; } -EXPORT_SYMBOL(dprc_get_obj); +EXPORT_SYMBOL_GPL(dprc_get_obj); /** * dprc_set_obj_irq() - Set IRQ information for object to trigger an interrupt. @@ -572,104 +417,7 @@ int dprc_set_obj_irq(struct fsl_mc_io *mc_io, /* send command to mc*/ return mc_send_command(mc_io, &cmd); } -EXPORT_SYMBOL(dprc_set_obj_irq); - -/** - * dprc_get_obj_irq() - Get IRQ information from object. - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPRC object - * @obj_type: Type od the object to get its IRQ - * @obj_id: ID of the object to get its IRQ - * @irq_index: The interrupt index to configure - * @type: Interrupt type: 0 represents message interrupt - * type (both irq_addr and irq_val are valid) - * @irq_cfg: The returned IRQ attributes - * - * Return: '0' on Success; Error code otherwise. - */ -int dprc_get_obj_irq(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - char *obj_type, - int obj_id, - u8 irq_index, - int *type, - struct dprc_irq_cfg *irq_cfg) -{ - struct mc_command cmd = { 0 }; - struct dprc_cmd_get_obj_irq *cmd_params; - struct dprc_rsp_get_obj_irq *rsp_params; - int err; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_IRQ, - cmd_flags, - token); - cmd_params = (struct dprc_cmd_get_obj_irq *)cmd.params; - cmd_params->obj_id = cpu_to_le32(obj_id); - cmd_params->irq_index = irq_index; - strncpy(cmd_params->obj_type, obj_type, 16); - cmd_params->obj_type[15] = '\0'; - - /* send command to mc*/ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - rsp_params = (struct dprc_rsp_get_obj_irq *)cmd.params; - irq_cfg->val = le32_to_cpu(rsp_params->irq_val); - irq_cfg->paddr = le64_to_cpu(rsp_params->irq_addr); - irq_cfg->irq_num = le32_to_cpu(rsp_params->irq_num); - *type = le32_to_cpu(rsp_params->type); - - return 0; -} -EXPORT_SYMBOL(dprc_get_obj_irq); - -/** - * dprc_get_res_count() - Obtains the number of free resources that are assigned - * to this container, by pool type - * @mc_io: Pointer to MC portal's I/O object - * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' - * @token: Token of DPRC object - * @type: pool type - * @res_count: Returned number of free resources of the given - * resource type that are assigned to this DPRC - * - * Return: '0' on Success; Error code otherwise. - */ -int dprc_get_res_count(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - char *type, - int *res_count) -{ - struct mc_command cmd = { 0 }; - struct dprc_cmd_get_res_count *cmd_params; - struct dprc_rsp_get_res_count *rsp_params; - int err; - - /* prepare command */ - cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_RES_COUNT, - cmd_flags, token); - cmd_params = (struct dprc_cmd_get_res_count *)cmd.params; - strncpy(cmd_params->type, type, 16); - cmd_params->type[15] = '\0'; - - /* send command to mc*/ - err = mc_send_command(mc_io, &cmd); - if (err) - return err; - - /* retrieve response parameters */ - rsp_params = (struct dprc_rsp_get_res_count *)cmd.params; - *res_count = le32_to_cpu(rsp_params->res_count); - - return 0; -} -EXPORT_SYMBOL(dprc_get_res_count); +EXPORT_SYMBOL_GPL(dprc_set_obj_irq); /** * dprc_get_obj_region() - Get region information for a specified object. @@ -717,7 +465,7 @@ int dprc_get_obj_region(struct fsl_mc_io *mc_io, return 0; } -EXPORT_SYMBOL(dprc_get_obj_region); +EXPORT_SYMBOL_GPL(dprc_get_obj_region); /** * dprc_get_api_version - Get Data Path Resource Container API version diff --git a/drivers/staging/fsl-mc/bus/dprc.h b/drivers/staging/fsl-mc/bus/dprc.h deleted file mode 100644 index 21295e4feb04..000000000000 --- a/drivers/staging/fsl-mc/bus/dprc.h +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright 2013-2016 Freescale Semiconductor Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef _FSL_DPRC_H -#define _FSL_DPRC_H - -/* - * Data Path Resource Container API - * Contains DPRC API for managing and querying DPAA resources - */ - -struct fsl_mc_io; -struct fsl_mc_obj_desc; - -int dprc_open(struct fsl_mc_io *mc_io, - u32 cmd_flags, - int container_id, - u16 *token); - -int dprc_close(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token); - -/* IRQ */ - -/* IRQ index */ -#define DPRC_IRQ_INDEX 0 - -/* Number of dprc's IRQs */ -#define DPRC_NUM_OF_IRQS 1 - -/* DPRC IRQ events */ - -/* IRQ event - Indicates that a new object added to the container */ -#define DPRC_IRQ_EVENT_OBJ_ADDED 0x00000001 -/* IRQ event - Indicates that an object was removed from the container */ -#define DPRC_IRQ_EVENT_OBJ_REMOVED 0x00000002 -/* IRQ event - Indicates that resources added to the container */ -#define DPRC_IRQ_EVENT_RES_ADDED 0x00000004 -/* IRQ event - Indicates that resources removed from the container */ -#define DPRC_IRQ_EVENT_RES_REMOVED 0x00000008 -/* - * IRQ event - Indicates that one of the descendant containers that opened by - * this container is destroyed - */ -#define DPRC_IRQ_EVENT_CONTAINER_DESTROYED 0x00000010 - -/* - * IRQ event - Indicates that on one of the container's opened object is - * destroyed - */ -#define DPRC_IRQ_EVENT_OBJ_DESTROYED 0x00000020 - -/* Irq event - Indicates that object is created at the container */ -#define DPRC_IRQ_EVENT_OBJ_CREATED 0x00000040 - -/** - * struct dprc_irq_cfg - IRQ configuration - * @paddr: Address that must be written to signal a message-based interrupt - * @val: Value to write into irq_addr address - * @irq_num: A user defined number associated with this IRQ - */ -struct dprc_irq_cfg { - phys_addr_t paddr; - u32 val; - int irq_num; -}; - -int dprc_set_irq(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - struct dprc_irq_cfg *irq_cfg); - -int dprc_get_irq(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - int *type, - struct dprc_irq_cfg *irq_cfg); - -int dprc_set_irq_enable(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u8 en); - -int dprc_get_irq_enable(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u8 *en); - -int dprc_set_irq_mask(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u32 mask); - -int dprc_get_irq_mask(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u32 *mask); - -int dprc_get_irq_status(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u32 *status); - -int dprc_clear_irq_status(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - u8 irq_index, - u32 status); - -/** - * struct dprc_attributes - Container attributes - * @container_id: Container's ID - * @icid: Container's ICID - * @portal_id: Container's portal ID - * @options: Container's options as set at container's creation - */ -struct dprc_attributes { - int container_id; - u16 icid; - int portal_id; - u64 options; -}; - -int dprc_get_attributes(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - struct dprc_attributes *attributes); - -int dprc_get_obj_count(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - int *obj_count); - -int dprc_get_obj(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - int obj_index, - struct fsl_mc_obj_desc *obj_desc); - -int dprc_get_obj_desc(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - char *obj_type, - int obj_id, - struct fsl_mc_obj_desc *obj_desc); - -int dprc_set_obj_irq(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - char *obj_type, - int obj_id, - u8 irq_index, - struct dprc_irq_cfg *irq_cfg); - -int dprc_get_obj_irq(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - char *obj_type, - int obj_id, - u8 irq_index, - int *type, - struct dprc_irq_cfg *irq_cfg); - -int dprc_get_res_count(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - char *type, - int *res_count); - -/** - * enum dprc_iter_status - Iteration status - * @DPRC_ITER_STATUS_FIRST: Perform first iteration - * @DPRC_ITER_STATUS_MORE: Indicates more/next iteration is needed - * @DPRC_ITER_STATUS_LAST: Indicates last iteration - */ -enum dprc_iter_status { - DPRC_ITER_STATUS_FIRST = 0, - DPRC_ITER_STATUS_MORE = 1, - DPRC_ITER_STATUS_LAST = 2 -}; - -/* Region flags */ -/* Cacheable - Indicates that region should be mapped as cacheable */ -#define DPRC_REGION_CACHEABLE 0x00000001 - -/** - * enum dprc_region_type - Region type - * @DPRC_REGION_TYPE_MC_PORTAL: MC portal region - * @DPRC_REGION_TYPE_QBMAN_PORTAL: Qbman portal region - */ -enum dprc_region_type { - DPRC_REGION_TYPE_MC_PORTAL, - DPRC_REGION_TYPE_QBMAN_PORTAL -}; - -/** - * struct dprc_region_desc - Mappable region descriptor - * @base_offset: Region offset from region's base address. - * For DPMCP and DPRC objects, region base is offset from SoC MC portals - * base address; For DPIO, region base is offset from SoC QMan portals - * base address - * @size: Region size (in bytes) - * @flags: Region attributes - * @type: Portal region type - */ -struct dprc_region_desc { - u32 base_offset; - u32 size; - u32 flags; - enum dprc_region_type type; -}; - -int dprc_get_obj_region(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - char *obj_type, - int obj_id, - u8 region_index, - struct dprc_region_desc *region_desc); - -int dprc_get_api_version(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 *major_ver, - u16 *minor_ver); - -int dprc_get_container_id(struct fsl_mc_io *mc_io, - u32 cmd_flags, - int *container_id); - -#endif /* _FSL_DPRC_H */ - diff --git a/drivers/staging/fsl-mc/bus/fsl-mc-allocator.c b/drivers/staging/fsl-mc/bus/fsl-mc-allocator.c index 8ea3920400a0..8f313a41240b 100644 --- a/drivers/staging/fsl-mc/bus/fsl-mc-allocator.c +++ b/drivers/staging/fsl-mc/bus/fsl-mc-allocator.c @@ -1,11 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * fsl-mc object allocator driver * * Copyright (C) 2013-2016 Freescale Semiconductor, Inc. * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #include <linux/module.h> @@ -14,11 +12,11 @@ #include "fsl-mc-private.h" -static bool __must_check fsl_mc_is_allocatable(const char *obj_type) +static bool __must_check fsl_mc_is_allocatable(struct fsl_mc_device *mc_dev) { - return strcmp(obj_type, "dpbp") == 0 || - strcmp(obj_type, "dpmcp") == 0 || - strcmp(obj_type, "dpcon") == 0; + return is_fsl_mc_bus_dpbp(mc_dev) || + is_fsl_mc_bus_dpmcp(mc_dev) || + is_fsl_mc_bus_dpcon(mc_dev); } /** @@ -41,25 +39,25 @@ static int __must_check fsl_mc_resource_pool_add_device(struct fsl_mc_bus struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev; int error = -EINVAL; - if (WARN_ON(pool_type < 0 || pool_type >= FSL_MC_NUM_POOL_TYPES)) + if (pool_type < 0 || pool_type >= FSL_MC_NUM_POOL_TYPES) goto out; - if (WARN_ON(!fsl_mc_is_allocatable(mc_dev->obj_desc.type))) + if (!fsl_mc_is_allocatable(mc_dev)) goto out; - if (WARN_ON(mc_dev->resource)) + if (mc_dev->resource) goto out; res_pool = &mc_bus->resource_pools[pool_type]; - if (WARN_ON(res_pool->type != pool_type)) + if (res_pool->type != pool_type) goto out; - if (WARN_ON(res_pool->mc_bus != mc_bus)) + if (res_pool->mc_bus != mc_bus) goto out; mutex_lock(&res_pool->mutex); - if (WARN_ON(res_pool->max_count < 0)) + if (res_pool->max_count < 0) goto out_unlock; - if (WARN_ON(res_pool->free_count < 0 || - res_pool->free_count > res_pool->max_count)) + if (res_pool->free_count < 0 || + res_pool->free_count > res_pool->max_count) goto out_unlock; resource = devm_kzalloc(&mc_bus_dev->dev, sizeof(*resource), @@ -105,25 +103,25 @@ static int __must_check fsl_mc_resource_pool_remove_device(struct fsl_mc_device struct fsl_mc_resource *resource; int error = -EINVAL; - if (WARN_ON(!fsl_mc_is_allocatable(mc_dev->obj_desc.type))) + if (!fsl_mc_is_allocatable(mc_dev)) goto out; resource = mc_dev->resource; - if (WARN_ON(!resource || resource->data != mc_dev)) + if (!resource || resource->data != mc_dev) goto out; mc_bus_dev = to_fsl_mc_device(mc_dev->dev.parent); mc_bus = to_fsl_mc_bus(mc_bus_dev); res_pool = resource->parent_pool; - if (WARN_ON(res_pool != &mc_bus->resource_pools[resource->type])) + if (res_pool != &mc_bus->resource_pools[resource->type]) goto out; mutex_lock(&res_pool->mutex); - if (WARN_ON(res_pool->max_count <= 0)) + if (res_pool->max_count <= 0) goto out_unlock; - if (WARN_ON(res_pool->free_count <= 0 || - res_pool->free_count > res_pool->max_count)) + if (res_pool->free_count <= 0 || + res_pool->free_count > res_pool->max_count) goto out_unlock; /* @@ -187,11 +185,11 @@ int __must_check fsl_mc_resource_allocate(struct fsl_mc_bus *mc_bus, FSL_MC_NUM_POOL_TYPES); *new_resource = NULL; - if (WARN_ON(pool_type < 0 || pool_type >= FSL_MC_NUM_POOL_TYPES)) + if (pool_type < 0 || pool_type >= FSL_MC_NUM_POOL_TYPES) goto out; res_pool = &mc_bus->resource_pools[pool_type]; - if (WARN_ON(res_pool->mc_bus != mc_bus)) + if (res_pool->mc_bus != mc_bus) goto out; mutex_lock(&res_pool->mutex); @@ -199,7 +197,6 @@ int __must_check fsl_mc_resource_allocate(struct fsl_mc_bus *mc_bus, struct fsl_mc_resource, node); if (!resource) { - WARN_ON(res_pool->free_count != 0); error = -ENXIO; dev_err(&mc_bus_dev->dev, "No more resources of type %s left\n", @@ -207,12 +204,12 @@ int __must_check fsl_mc_resource_allocate(struct fsl_mc_bus *mc_bus, goto out_unlock; } - if (WARN_ON(resource->type != pool_type)) + if (resource->type != pool_type) goto out_unlock; - if (WARN_ON(resource->parent_pool != res_pool)) + if (resource->parent_pool != res_pool) goto out_unlock; - if (WARN_ON(res_pool->free_count <= 0 || - res_pool->free_count > res_pool->max_count)) + if (res_pool->free_count <= 0 || + res_pool->free_count > res_pool->max_count) goto out_unlock; list_del_init(&resource->node); @@ -232,15 +229,15 @@ void fsl_mc_resource_free(struct fsl_mc_resource *resource) struct fsl_mc_resource_pool *res_pool; res_pool = resource->parent_pool; - if (WARN_ON(resource->type != res_pool->type)) + if (resource->type != res_pool->type) return; mutex_lock(&res_pool->mutex); - if (WARN_ON(res_pool->free_count < 0 || - res_pool->free_count >= res_pool->max_count)) + if (res_pool->free_count < 0 || + res_pool->free_count >= res_pool->max_count) goto out_unlock; - if (WARN_ON(!list_empty(&resource->node))) + if (!list_empty(&resource->node)) goto out_unlock; list_add_tail(&resource->node, &res_pool->free_list); @@ -279,13 +276,13 @@ int __must_check fsl_mc_object_allocate(struct fsl_mc_device *mc_dev, struct fsl_mc_resource *resource = NULL; *new_mc_adev = NULL; - if (WARN_ON(mc_dev->flags & FSL_MC_IS_DPRC)) + if (mc_dev->flags & FSL_MC_IS_DPRC) goto error; - if (WARN_ON(!dev_is_fsl_mc(mc_dev->dev.parent))) + if (!dev_is_fsl_mc(mc_dev->dev.parent)) goto error; - if (WARN_ON(pool_type == FSL_MC_POOL_DPMCP)) + if (pool_type == FSL_MC_POOL_DPMCP) goto error; mc_bus_dev = to_fsl_mc_device(mc_dev->dev.parent); @@ -295,7 +292,7 @@ int __must_check fsl_mc_object_allocate(struct fsl_mc_device *mc_dev, goto error; mc_adev = resource->data; - if (WARN_ON(!mc_adev)) + if (!mc_adev) goto error; *new_mc_adev = mc_adev; @@ -318,9 +315,9 @@ void fsl_mc_object_free(struct fsl_mc_device *mc_adev) struct fsl_mc_resource *resource; resource = mc_adev->resource; - if (WARN_ON(resource->type == FSL_MC_POOL_DPMCP)) + if (resource->type == FSL_MC_POOL_DPMCP) return; - if (WARN_ON(resource->data != mc_adev)) + if (resource->data != mc_adev) return; fsl_mc_resource_free(resource); @@ -349,8 +346,8 @@ int fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus, struct fsl_mc_resource_pool *res_pool = &mc_bus->resource_pools[FSL_MC_POOL_IRQ]; - if (WARN_ON(irq_count == 0 || - irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS)) + if (irq_count == 0 || + irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) return -EINVAL; error = fsl_mc_msi_domain_alloc_irqs(&mc_bus_dev->dev, irq_count); @@ -406,13 +403,13 @@ void fsl_mc_cleanup_irq_pool(struct fsl_mc_bus *mc_bus) struct fsl_mc_resource_pool *res_pool = &mc_bus->resource_pools[FSL_MC_POOL_IRQ]; - if (WARN_ON(!mc_bus->irq_resources)) + if (!mc_bus->irq_resources) return; - if (WARN_ON(res_pool->max_count == 0)) + if (res_pool->max_count == 0) return; - if (WARN_ON(res_pool->free_count != res_pool->max_count)) + if (res_pool->free_count != res_pool->max_count) return; INIT_LIST_HEAD(&res_pool->free_list); @@ -436,19 +433,19 @@ int __must_check fsl_mc_allocate_irqs(struct fsl_mc_device *mc_dev) struct fsl_mc_bus *mc_bus; struct fsl_mc_resource_pool *res_pool; - if (WARN_ON(mc_dev->irqs)) + if (mc_dev->irqs) return -EINVAL; irq_count = mc_dev->obj_desc.irq_count; - if (WARN_ON(irq_count == 0)) + if (irq_count == 0) return -EINVAL; - if (strcmp(mc_dev->obj_desc.type, "dprc") == 0) + if (is_fsl_mc_bus_dprc(mc_dev)) mc_bus = to_fsl_mc_bus(mc_dev); else mc_bus = to_fsl_mc_bus(to_fsl_mc_device(mc_dev->dev.parent)); - if (WARN_ON(!mc_bus->irq_resources)) + if (!mc_bus->irq_resources) return -EINVAL; res_pool = &mc_bus->resource_pools[FSL_MC_POOL_IRQ]; @@ -474,7 +471,6 @@ int __must_check fsl_mc_allocate_irqs(struct fsl_mc_device *mc_dev) irqs[i] = to_fsl_mc_irq(resource); res_allocated_count++; - WARN_ON(irqs[i]->mc_dev); irqs[i]->mc_dev = mc_dev; irqs[i]->dev_irq_index = i; } @@ -502,21 +498,20 @@ void fsl_mc_free_irqs(struct fsl_mc_device *mc_dev) struct fsl_mc_bus *mc_bus; struct fsl_mc_device_irq **irqs = mc_dev->irqs; - if (WARN_ON(!irqs)) + if (!irqs) return; irq_count = mc_dev->obj_desc.irq_count; - if (strcmp(mc_dev->obj_desc.type, "dprc") == 0) + if (is_fsl_mc_bus_dprc(mc_dev)) mc_bus = to_fsl_mc_bus(mc_dev); else mc_bus = to_fsl_mc_bus(to_fsl_mc_device(mc_dev->dev.parent)); - if (WARN_ON(!mc_bus->irq_resources)) + if (!mc_bus->irq_resources) return; for (i = 0; i < irq_count; i++) { - WARN_ON(!irqs[i]->mc_dev); irqs[i]->mc_dev = NULL; fsl_mc_resource_free(&irqs[i]->resource); } @@ -553,17 +548,10 @@ static void fsl_mc_cleanup_resource_pool(struct fsl_mc_device *mc_bus_dev, &mc_bus->resource_pools[pool_type]; int free_count = 0; - WARN_ON(res_pool->type != pool_type); - WARN_ON(res_pool->free_count != res_pool->max_count); - list_for_each_entry_safe(resource, next, &res_pool->free_list, node) { free_count++; - WARN_ON(resource->type != res_pool->type); - WARN_ON(resource->parent_pool != res_pool); devm_kfree(&mc_bus_dev->dev, resource); } - - WARN_ON(free_count != res_pool->free_count); } void fsl_mc_cleanup_all_resource_pools(struct fsl_mc_device *mc_bus_dev) @@ -585,11 +573,11 @@ static int fsl_mc_allocator_probe(struct fsl_mc_device *mc_dev) struct fsl_mc_bus *mc_bus; int error; - if (WARN_ON(!fsl_mc_is_allocatable(mc_dev->obj_desc.type))) + if (!fsl_mc_is_allocatable(mc_dev)) return -EINVAL; mc_bus_dev = to_fsl_mc_device(mc_dev->dev.parent); - if (WARN_ON(!dev_is_fsl_mc(&mc_bus_dev->dev))) + if (!dev_is_fsl_mc(&mc_bus_dev->dev)) return -EINVAL; mc_bus = to_fsl_mc_bus(mc_bus_dev); @@ -614,7 +602,7 @@ static int fsl_mc_allocator_remove(struct fsl_mc_device *mc_dev) { int error; - if (WARN_ON(!fsl_mc_is_allocatable(mc_dev->obj_desc.type))) + if (!fsl_mc_is_allocatable(mc_dev)) return -EINVAL; if (mc_dev->resource) { @@ -658,8 +646,3 @@ int __init fsl_mc_allocator_driver_init(void) { return fsl_mc_driver_register(&fsl_mc_allocator_driver); } - -void fsl_mc_allocator_driver_exit(void) -{ - fsl_mc_driver_unregister(&fsl_mc_allocator_driver); -} diff --git a/drivers/staging/fsl-mc/bus/fsl-mc-bus.c b/drivers/staging/fsl-mc/bus/fsl-mc-bus.c index 409f2b9e70ff..1b333c43aae9 100644 --- a/drivers/staging/fsl-mc/bus/fsl-mc-bus.c +++ b/drivers/staging/fsl-mc/bus/fsl-mc-bus.c @@ -1,12 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Freescale Management Complex (MC) bus driver * * Copyright (C) 2014-2016 Freescale Semiconductor, Inc. * Author: German Rivera <German.Rivera@freescale.com> * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #define pr_fmt(fmt) "fsl-mc: " fmt @@ -22,8 +20,6 @@ #include <linux/dma-mapping.h> #include "fsl-mc-private.h" -#include "dprc-cmd.h" -#include "dpmng-cmd.h" /** * Default DMA mask for devices on a fsl-mc bus @@ -156,22 +152,80 @@ struct bus_type fsl_mc_bus_type = { }; EXPORT_SYMBOL_GPL(fsl_mc_bus_type); +struct device_type fsl_mc_bus_dprc_type = { + .name = "fsl_mc_bus_dprc" +}; + +struct device_type fsl_mc_bus_dpni_type = { + .name = "fsl_mc_bus_dpni" +}; + +struct device_type fsl_mc_bus_dpio_type = { + .name = "fsl_mc_bus_dpio" +}; + +struct device_type fsl_mc_bus_dpsw_type = { + .name = "fsl_mc_bus_dpsw" +}; + +struct device_type fsl_mc_bus_dpbp_type = { + .name = "fsl_mc_bus_dpbp" +}; + +struct device_type fsl_mc_bus_dpcon_type = { + .name = "fsl_mc_bus_dpcon" +}; + +struct device_type fsl_mc_bus_dpmcp_type = { + .name = "fsl_mc_bus_dpmcp" +}; + +struct device_type fsl_mc_bus_dpmac_type = { + .name = "fsl_mc_bus_dpmac" +}; + +struct device_type fsl_mc_bus_dprtc_type = { + .name = "fsl_mc_bus_dprtc" +}; + +static struct device_type *fsl_mc_get_device_type(const char *type) +{ + static const struct { + struct device_type *dev_type; + const char *type; + } dev_types[] = { + { &fsl_mc_bus_dprc_type, "dprc" }, + { &fsl_mc_bus_dpni_type, "dpni" }, + { &fsl_mc_bus_dpio_type, "dpio" }, + { &fsl_mc_bus_dpsw_type, "dpsw" }, + { &fsl_mc_bus_dpbp_type, "dpbp" }, + { &fsl_mc_bus_dpcon_type, "dpcon" }, + { &fsl_mc_bus_dpmcp_type, "dpmcp" }, + { &fsl_mc_bus_dpmac_type, "dpmac" }, + { &fsl_mc_bus_dprtc_type, "dprtc" }, + { NULL, NULL } + }; + int i; + + for (i = 0; dev_types[i].dev_type; i++) + if (!strcmp(dev_types[i].type, type)) + return dev_types[i].dev_type; + + return NULL; +} + static int fsl_mc_driver_probe(struct device *dev) { struct fsl_mc_driver *mc_drv; struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); int error; - if (WARN_ON(!dev->driver)) - return -EINVAL; - mc_drv = to_fsl_mc_driver(dev->driver); - if (WARN_ON(!mc_drv->probe)) - return -EINVAL; error = mc_drv->probe(mc_dev); if (error < 0) { - dev_err(dev, "%s failed: %d\n", __func__, error); + if (error != -EPROBE_DEFER) + dev_err(dev, "%s failed: %d\n", __func__, error); return error; } @@ -184,9 +238,6 @@ static int fsl_mc_driver_remove(struct device *dev) struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); int error; - if (WARN_ON(!dev->driver)) - return -EINVAL; - error = mc_drv->remove(mc_dev); if (error < 0) { dev_err(dev, "%s failed: %d\n", __func__, error); @@ -292,9 +343,9 @@ static int mc_get_version(struct fsl_mc_io *mc_io, static void fsl_mc_get_root_dprc(struct device *dev, struct device **root_dprc_dev) { - if (WARN_ON(!dev)) { + if (!dev) { *root_dprc_dev = NULL; - } else if (WARN_ON(!dev_is_fsl_mc(dev))) { + } else if (!dev_is_fsl_mc(dev)) { *root_dprc_dev = NULL; } else { *root_dprc_dev = dev; @@ -352,8 +403,6 @@ static int translate_mc_addr(struct fsl_mc_device *mc_dev, struct fsl_mc *mc; fsl_mc_get_root_dprc(&mc_dev->dev, &root_dprc_dev); - if (WARN_ON(!root_dprc_dev)) - return -EINVAL; mc = dev_get_drvdata(root_dprc_dev->parent); if (mc->num_translation_ranges == 0) { @@ -390,10 +439,10 @@ static int fsl_mc_device_get_mmio_regions(struct fsl_mc_device *mc_dev, struct device *parent_dev = mc_dev->dev.parent; enum dprc_region_type mc_region_type; - if (strcmp(obj_desc->type, "dprc") == 0 || - strcmp(obj_desc->type, "dpmcp") == 0) { + if (is_fsl_mc_bus_dprc(mc_dev) || + is_fsl_mc_bus_dpmcp(mc_dev)) { mc_region_type = DPRC_REGION_TYPE_MC_PORTAL; - } else if (strcmp(obj_desc->type, "dpio") == 0) { + } else if (is_fsl_mc_bus_dpio(mc_dev)) { mc_region_type = DPRC_REGION_TYPE_QBMAN_PORTAL; } else { /* @@ -401,7 +450,6 @@ static int fsl_mc_device_get_mmio_regions(struct fsl_mc_device *mc_dev, * type, as this object type is not supposed to have MMIO * regions */ - WARN_ON(true); return -EINVAL; } @@ -424,7 +472,6 @@ static int fsl_mc_device_get_mmio_regions(struct fsl_mc_device *mc_dev, goto error_cleanup_regions; } - WARN_ON(region_desc.size == 0); error = translate_mc_addr(mc_dev, mc_region_type, region_desc.base_offset, ®ions[i].start); @@ -470,7 +517,7 @@ static void fsl_mc_device_release(struct device *dev) kfree(mc_dev->regions); - if (strcmp(mc_dev->obj_desc.type, "dprc") == 0) + if (is_fsl_mc_bus_dprc(mc_dev)) kfree(to_fsl_mc_bus(mc_dev)); else kfree(mc_dev); @@ -518,6 +565,12 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc, mc_dev->dev.parent = parent_dev; mc_dev->dev.bus = &fsl_mc_bus_type; mc_dev->dev.release = fsl_mc_device_release; + mc_dev->dev.type = fsl_mc_get_device_type(obj_desc->type); + if (!mc_dev->dev.type) { + error = -ENODEV; + dev_err(parent_dev, "unknown device type %s\n", obj_desc->type); + goto error_cleanup_dev; + } dev_set_name(&mc_dev->dev, "%s.%d", obj_desc->type, obj_desc->id); if (strcmp(obj_desc->type, "dprc") == 0) { @@ -544,7 +597,7 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc, /* * device being added is the root DPRC device */ - if (WARN_ON(!mc_io)) { + if (!mc_io) { error = -EINVAL; goto error_cleanup_dev; } @@ -826,7 +879,7 @@ static int fsl_mc_bus_remove(struct platform_device *pdev) { struct fsl_mc *mc = platform_get_drvdata(pdev); - if (WARN_ON(!fsl_mc_is_root_dprc(&mc->root_mc_bus_dev->dev))) + if (!fsl_mc_is_root_dprc(&mc->root_mc_bus_dev->dev)) return -EINVAL; fsl_mc_device_remove(mc->root_mc_bus_dev); @@ -878,15 +931,8 @@ static int __init fsl_mc_bus_driver_init(void) if (error < 0) goto error_cleanup_dprc_driver; - error = its_fsl_mc_msi_init(); - if (error < 0) - goto error_cleanup_mc_allocator; - return 0; -error_cleanup_mc_allocator: - fsl_mc_allocator_driver_exit(); - error_cleanup_dprc_driver: dprc_driver_exit(); diff --git a/drivers/staging/fsl-mc/bus/fsl-mc-msi.c b/drivers/staging/fsl-mc/bus/fsl-mc-msi.c index f74a6f1764bb..971ad87c584c 100644 --- a/drivers/staging/fsl-mc/bus/fsl-mc-msi.c +++ b/drivers/staging/fsl-mc/bus/fsl-mc-msi.c @@ -1,12 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Freescale Management Complex (MC) bus driver MSI support * * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. * Author: German Rivera <German.Rivera@freescale.com> * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #include <linux/of_device.h> @@ -47,7 +45,7 @@ static void fsl_mc_msi_update_dom_ops(struct msi_domain_info *info) { struct msi_domain_ops *ops = info->ops; - if (WARN_ON(!ops)) + if (!ops) return; /* @@ -73,7 +71,7 @@ static void __fsl_mc_msi_write_msg(struct fsl_mc_device *mc_bus_dev, if (msi_desc->msg.address_lo == 0x0 && msi_desc->msg.address_hi == 0x0) return; - if (WARN_ON(!owner_mc_dev)) + if (!owner_mc_dev) return; irq_cfg.paddr = ((u64)msi_desc->msg.address_hi << 32) | @@ -124,7 +122,6 @@ static void fsl_mc_msi_write_msg(struct irq_data *irq_data, struct fsl_mc_device_irq *mc_dev_irq = &mc_bus->irq_resources[msi_desc->fsl_mc.msi_index]; - WARN_ON(mc_dev_irq->msi_desc != msi_desc); msi_desc->msg = *msg; /* @@ -137,7 +134,7 @@ static void fsl_mc_msi_update_chip_ops(struct msi_domain_info *info) { struct irq_chip *chip = info->chip; - if (WARN_ON(!chip)) + if (!chip) return; /* @@ -239,7 +236,7 @@ int fsl_mc_msi_domain_alloc_irqs(struct device *dev, struct irq_domain *msi_domain; int error; - if (WARN_ON(!list_empty(dev_to_msi_list(dev)))) + if (!list_empty(dev_to_msi_list(dev))) return -EINVAL; error = fsl_mc_msi_alloc_descs(dev, irq_count); @@ -247,7 +244,7 @@ int fsl_mc_msi_domain_alloc_irqs(struct device *dev, return error; msi_domain = dev_get_msi_domain(dev); - if (WARN_ON(!msi_domain)) { + if (!msi_domain) { error = -EINVAL; goto cleanup_msi_descs; } @@ -275,12 +272,12 @@ void fsl_mc_msi_domain_free_irqs(struct device *dev) struct irq_domain *msi_domain; msi_domain = dev_get_msi_domain(dev); - if (WARN_ON(!msi_domain)) + if (!msi_domain) return; msi_domain_free_irqs(msi_domain, dev); - if (WARN_ON(list_empty(dev_to_msi_list(dev)))) + if (list_empty(dev_to_msi_list(dev))) return; fsl_mc_msi_free_descs(dev); diff --git a/drivers/staging/fsl-mc/bus/fsl-mc-private.h b/drivers/staging/fsl-mc/bus/fsl-mc-private.h index 62d398947605..83b89d6241f2 100644 --- a/drivers/staging/fsl-mc/bus/fsl-mc-private.h +++ b/drivers/staging/fsl-mc/bus/fsl-mc-private.h @@ -1,19 +1,384 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Freescale Management Complex (MC) bus private declarations * * Copyright (C) 2016 Freescale Semiconductor, Inc. * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #ifndef _FSL_MC_PRIVATE_H_ #define _FSL_MC_PRIVATE_H_ #include "../include/mc.h" -#include "dprc.h" #include <linux/mutex.h> +/* + * Data Path Management Complex (DPMNG) General API + */ + +/* DPMNG command versioning */ +#define DPMNG_CMD_BASE_VERSION 1 +#define DPMNG_CMD_ID_OFFSET 4 + +#define DPMNG_CMD(id) (((id) << DPMNG_CMD_ID_OFFSET) | DPMNG_CMD_BASE_VERSION) + +/* DPMNG command IDs */ +#define DPMNG_CMDID_GET_VERSION DPMNG_CMD(0x831) + +struct dpmng_rsp_get_version { + __le32 revision; + __le32 version_major; + __le32 version_minor; +}; + +/* + * Data Path Management Command Portal (DPMCP) API + */ + +/* Minimal supported DPMCP Version */ +#define DPMCP_MIN_VER_MAJOR 3 +#define DPMCP_MIN_VER_MINOR 0 + +/* DPMCP command versioning */ +#define DPMCP_CMD_BASE_VERSION 1 +#define DPMCP_CMD_ID_OFFSET 4 + +#define DPMCP_CMD(id) (((id) << DPMCP_CMD_ID_OFFSET) | DPMCP_CMD_BASE_VERSION) + +/* DPMCP command IDs */ +#define DPMCP_CMDID_CLOSE DPMCP_CMD(0x800) +#define DPMCP_CMDID_OPEN DPMCP_CMD(0x80b) +#define DPMCP_CMDID_RESET DPMCP_CMD(0x005) + +struct dpmcp_cmd_open { + __le32 dpmcp_id; +}; + +/* + * Initialization and runtime control APIs for DPMCP + */ +int dpmcp_open(struct fsl_mc_io *mc_io, + u32 cmd_flags, + int dpmcp_id, + u16 *token); + +int dpmcp_close(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token); + +int dpmcp_reset(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token); + +/* + * Data Path Resource Container (DPRC) API + */ + +/* Minimal supported DPRC Version */ +#define DPRC_MIN_VER_MAJOR 6 +#define DPRC_MIN_VER_MINOR 0 + +/* DPRC command versioning */ +#define DPRC_CMD_BASE_VERSION 1 +#define DPRC_CMD_ID_OFFSET 4 + +#define DPRC_CMD(id) (((id) << DPRC_CMD_ID_OFFSET) | DPRC_CMD_BASE_VERSION) + +/* DPRC command IDs */ +#define DPRC_CMDID_CLOSE DPRC_CMD(0x800) +#define DPRC_CMDID_OPEN DPRC_CMD(0x805) +#define DPRC_CMDID_GET_API_VERSION DPRC_CMD(0xa05) + +#define DPRC_CMDID_GET_ATTR DPRC_CMD(0x004) + +#define DPRC_CMDID_SET_IRQ DPRC_CMD(0x010) +#define DPRC_CMDID_SET_IRQ_ENABLE DPRC_CMD(0x012) +#define DPRC_CMDID_SET_IRQ_MASK DPRC_CMD(0x014) +#define DPRC_CMDID_GET_IRQ_STATUS DPRC_CMD(0x016) +#define DPRC_CMDID_CLEAR_IRQ_STATUS DPRC_CMD(0x017) + +#define DPRC_CMDID_GET_CONT_ID DPRC_CMD(0x830) +#define DPRC_CMDID_GET_OBJ_COUNT DPRC_CMD(0x159) +#define DPRC_CMDID_GET_OBJ DPRC_CMD(0x15A) +#define DPRC_CMDID_GET_OBJ_REG DPRC_CMD(0x15E) +#define DPRC_CMDID_SET_OBJ_IRQ DPRC_CMD(0x15F) + +struct dprc_cmd_open { + __le32 container_id; +}; + +struct dprc_cmd_set_irq { + /* cmd word 0 */ + __le32 irq_val; + u8 irq_index; + u8 pad[3]; + /* cmd word 1 */ + __le64 irq_addr; + /* cmd word 2 */ + __le32 irq_num; +}; + +#define DPRC_ENABLE 0x1 + +struct dprc_cmd_set_irq_enable { + u8 enable; + u8 pad[3]; + u8 irq_index; +}; + +struct dprc_cmd_set_irq_mask { + __le32 mask; + u8 irq_index; +}; + +struct dprc_cmd_get_irq_status { + __le32 status; + u8 irq_index; +}; + +struct dprc_rsp_get_irq_status { + __le32 status; +}; + +struct dprc_cmd_clear_irq_status { + __le32 status; + u8 irq_index; +}; + +struct dprc_rsp_get_attributes { + /* response word 0 */ + __le32 container_id; + __le16 icid; + __le16 pad; + /* response word 1 */ + __le32 options; + __le32 portal_id; +}; + +struct dprc_rsp_get_obj_count { + __le32 pad; + __le32 obj_count; +}; + +struct dprc_cmd_get_obj { + __le32 obj_index; +}; + +struct dprc_rsp_get_obj { + /* response word 0 */ + __le32 pad0; + __le32 id; + /* response word 1 */ + __le16 vendor; + u8 irq_count; + u8 region_count; + __le32 state; + /* response word 2 */ + __le16 version_major; + __le16 version_minor; + __le16 flags; + __le16 pad1; + /* response word 3-4 */ + u8 type[16]; + /* response word 5-6 */ + u8 label[16]; +}; + +struct dprc_cmd_get_obj_region { + /* cmd word 0 */ + __le32 obj_id; + __le16 pad0; + u8 region_index; + u8 pad1; + /* cmd word 1-2 */ + __le64 pad2[2]; + /* cmd word 3-4 */ + u8 obj_type[16]; +}; + +struct dprc_rsp_get_obj_region { + /* response word 0 */ + __le64 pad; + /* response word 1 */ + __le64 base_addr; + /* response word 2 */ + __le32 size; +}; + +struct dprc_cmd_set_obj_irq { + /* cmd word 0 */ + __le32 irq_val; + u8 irq_index; + u8 pad[3]; + /* cmd word 1 */ + __le64 irq_addr; + /* cmd word 2 */ + __le32 irq_num; + __le32 obj_id; + /* cmd word 3-4 */ + u8 obj_type[16]; +}; + +/* + * DPRC API for managing and querying DPAA resources + */ +int dprc_open(struct fsl_mc_io *mc_io, + u32 cmd_flags, + int container_id, + u16 *token); + +int dprc_close(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token); + +/* DPRC IRQ events */ + +/* IRQ event - Indicates that a new object added to the container */ +#define DPRC_IRQ_EVENT_OBJ_ADDED 0x00000001 +/* IRQ event - Indicates that an object was removed from the container */ +#define DPRC_IRQ_EVENT_OBJ_REMOVED 0x00000002 +/* + * IRQ event - Indicates that one of the descendant containers that opened by + * this container is destroyed + */ +#define DPRC_IRQ_EVENT_CONTAINER_DESTROYED 0x00000010 + +/* + * IRQ event - Indicates that on one of the container's opened object is + * destroyed + */ +#define DPRC_IRQ_EVENT_OBJ_DESTROYED 0x00000020 + +/* Irq event - Indicates that object is created at the container */ +#define DPRC_IRQ_EVENT_OBJ_CREATED 0x00000040 + +/** + * struct dprc_irq_cfg - IRQ configuration + * @paddr: Address that must be written to signal a message-based interrupt + * @val: Value to write into irq_addr address + * @irq_num: A user defined number associated with this IRQ + */ +struct dprc_irq_cfg { + phys_addr_t paddr; + u32 val; + int irq_num; +}; + +int dprc_set_irq(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token, + u8 irq_index, + struct dprc_irq_cfg *irq_cfg); + +int dprc_set_irq_enable(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token, + u8 irq_index, + u8 en); + +int dprc_set_irq_mask(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token, + u8 irq_index, + u32 mask); + +int dprc_get_irq_status(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token, + u8 irq_index, + u32 *status); + +int dprc_clear_irq_status(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token, + u8 irq_index, + u32 status); + +/** + * struct dprc_attributes - Container attributes + * @container_id: Container's ID + * @icid: Container's ICID + * @portal_id: Container's portal ID + * @options: Container's options as set at container's creation + */ +struct dprc_attributes { + int container_id; + u16 icid; + int portal_id; + u64 options; +}; + +int dprc_get_attributes(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token, + struct dprc_attributes *attributes); + +int dprc_get_obj_count(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token, + int *obj_count); + +int dprc_get_obj(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token, + int obj_index, + struct fsl_mc_obj_desc *obj_desc); + +int dprc_set_obj_irq(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token, + char *obj_type, + int obj_id, + u8 irq_index, + struct dprc_irq_cfg *irq_cfg); + +/* Region flags */ +/* Cacheable - Indicates that region should be mapped as cacheable */ +#define DPRC_REGION_CACHEABLE 0x00000001 + +/** + * enum dprc_region_type - Region type + * @DPRC_REGION_TYPE_MC_PORTAL: MC portal region + * @DPRC_REGION_TYPE_QBMAN_PORTAL: Qbman portal region + */ +enum dprc_region_type { + DPRC_REGION_TYPE_MC_PORTAL, + DPRC_REGION_TYPE_QBMAN_PORTAL +}; + +/** + * struct dprc_region_desc - Mappable region descriptor + * @base_offset: Region offset from region's base address. + * For DPMCP and DPRC objects, region base is offset from SoC MC portals + * base address; For DPIO, region base is offset from SoC QMan portals + * base address + * @size: Region size (in bytes) + * @flags: Region attributes + * @type: Portal region type + */ +struct dprc_region_desc { + u32 base_offset; + u32 size; + u32 flags; + enum dprc_region_type type; +}; + +int dprc_get_obj_region(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 token, + char *obj_type, + int obj_id, + u8 region_index, + struct dprc_region_desc *region_desc); + +int dprc_get_api_version(struct fsl_mc_io *mc_io, + u32 cmd_flags, + u16 *major_ver, + u16 *minor_ver); + +int dprc_get_container_id(struct fsl_mc_io *mc_io, + u32 cmd_flags, + int *container_id); + /** * Maximum number of total IRQs that can be pre-allocated for an MC bus' * IRQ pool @@ -73,8 +438,6 @@ void dprc_driver_exit(void); int __init fsl_mc_allocator_driver_init(void); -void fsl_mc_allocator_driver_exit(void); - void fsl_mc_init_all_resource_pools(struct fsl_mc_device *mc_bus_dev); void fsl_mc_cleanup_all_resource_pools(struct fsl_mc_device *mc_bus_dev); @@ -91,10 +454,6 @@ int fsl_mc_msi_domain_alloc_irqs(struct device *dev, void fsl_mc_msi_domain_free_irqs(struct device *dev); -int __init its_fsl_mc_msi_init(void); - -void its_fsl_mc_msi_cleanup(void); - int fsl_mc_find_msi_domain(struct device *mc_platform_dev, struct irq_domain **mc_msi_domain); diff --git a/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c b/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c index 123e4af58408..5064d5ddf581 100644 --- a/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c +++ b/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c @@ -1,12 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Freescale Management Complex (MC) bus driver MSI support * * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. * Author: German Rivera <German.Rivera@freescale.com> * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #include <linux/of_device.h> @@ -15,7 +13,7 @@ #include <linux/msi.h> #include <linux/of.h> #include <linux/of_irq.h> -#include "fsl-mc-private.h" +#include "../include/mc.h" static struct irq_chip its_msi_irq_chip = { .name = "ITS-fMSI", @@ -32,11 +30,11 @@ static int its_fsl_mc_msi_prepare(struct irq_domain *msi_domain, struct fsl_mc_device *mc_bus_dev; struct msi_domain_info *msi_info; - if (WARN_ON(!dev_is_fsl_mc(dev))) + if (!dev_is_fsl_mc(dev)) return -EINVAL; mc_bus_dev = to_fsl_mc_device(dev); - if (WARN_ON(!(mc_bus_dev->flags & FSL_MC_IS_DPRC))) + if (!(mc_bus_dev->flags & FSL_MC_IS_DPRC)) return -EINVAL; /* @@ -67,7 +65,7 @@ static const struct of_device_id its_device_id[] = { {}, }; -int __init its_fsl_mc_msi_init(void) +static int __init its_fsl_mc_msi_init(void) { struct device_node *np; struct irq_domain *parent; @@ -93,30 +91,10 @@ int __init its_fsl_mc_msi_init(void) continue; } - WARN_ON(mc_msi_domain->host_data != - &its_fsl_mc_msi_domain_info); - pr_info("fsl-mc MSI: %pOF domain created\n", np); } return 0; } -void its_fsl_mc_msi_cleanup(void) -{ - struct device_node *np; - - for (np = of_find_matching_node(NULL, its_device_id); np; - np = of_find_matching_node(np, its_device_id)) { - struct irq_domain *mc_msi_domain = irq_find_matching_host( - np, - DOMAIN_BUS_FSL_MC_MSI); - - if (!of_property_read_bool(np, "msi-controller")) - continue; - - if (mc_msi_domain && - mc_msi_domain->host_data == &its_fsl_mc_msi_domain_info) - irq_domain_remove(mc_msi_domain); - } -} +early_initcall(its_fsl_mc_msi_init); diff --git a/drivers/staging/fsl-mc/bus/mc-io.c b/drivers/staging/fsl-mc/bus/mc-io.c index f65c23ce83f1..7e6fb360ef12 100644 --- a/drivers/staging/fsl-mc/bus/mc-io.c +++ b/drivers/staging/fsl-mc/bus/mc-io.c @@ -1,54 +1,23 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* * Copyright 2013-2016 Freescale Semiconductor Inc. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ #include <linux/io.h> #include "../include/mc.h" #include "fsl-mc-private.h" -#include "dpmcp.h" -#include "dpmcp-cmd.h" static int fsl_mc_io_set_dpmcp(struct fsl_mc_io *mc_io, struct fsl_mc_device *dpmcp_dev) { int error; - if (WARN_ON(!dpmcp_dev)) - return -EINVAL; - - if (WARN_ON(mc_io->dpmcp_dev)) + if (mc_io->dpmcp_dev) return -EINVAL; - if (WARN_ON(dpmcp_dev->mc_io)) + if (dpmcp_dev->mc_io) return -EINVAL; error = dpmcp_open(mc_io, @@ -68,12 +37,6 @@ static void fsl_mc_io_unset_dpmcp(struct fsl_mc_io *mc_io) int error; struct fsl_mc_device *dpmcp_dev = mc_io->dpmcp_dev; - if (WARN_ON(!dpmcp_dev)) - return; - - if (WARN_ON(dpmcp_dev->mc_io != mc_io)) - return; - error = dpmcp_close(mc_io, 0, dpmcp_dev->mc_handle); @@ -210,7 +173,7 @@ int __must_check fsl_mc_portal_allocate(struct fsl_mc_device *mc_dev, if (mc_dev->flags & FSL_MC_IS_DPRC) { mc_bus_dev = mc_dev; } else { - if (WARN_ON(!dev_is_fsl_mc(mc_dev->dev.parent))) + if (!dev_is_fsl_mc(mc_dev->dev.parent)) return error; mc_bus_dev = to_fsl_mc_device(mc_dev->dev.parent); @@ -224,8 +187,6 @@ int __must_check fsl_mc_portal_allocate(struct fsl_mc_device *mc_dev, error = -EINVAL; dpmcp_dev = resource->data; - if (WARN_ON(!dpmcp_dev)) - goto error_cleanup_resource; if (dpmcp_dev->obj_desc.ver_major < DPMCP_MIN_VER_MAJOR || (dpmcp_dev->obj_desc.ver_major == DPMCP_MIN_VER_MAJOR && @@ -238,15 +199,9 @@ int __must_check fsl_mc_portal_allocate(struct fsl_mc_device *mc_dev, goto error_cleanup_resource; } - if (WARN_ON(dpmcp_dev->obj_desc.region_count == 0)) - goto error_cleanup_resource; - mc_portal_phys_addr = dpmcp_dev->regions[0].start; mc_portal_size = resource_size(dpmcp_dev->regions); - if (WARN_ON(mc_portal_size != mc_bus_dev->mc_io->portal_size)) - goto error_cleanup_resource; - error = fsl_create_mc_io(&mc_bus_dev->dev, mc_portal_phys_addr, mc_portal_size, dpmcp_dev, @@ -279,14 +234,12 @@ void fsl_mc_portal_free(struct fsl_mc_io *mc_io) * to have a DPMCP object associated with. */ dpmcp_dev = mc_io->dpmcp_dev; - if (WARN_ON(!dpmcp_dev)) - return; resource = dpmcp_dev->resource; - if (WARN_ON(!resource || resource->type != FSL_MC_POOL_DPMCP)) + if (!resource || resource->type != FSL_MC_POOL_DPMCP) return; - if (WARN_ON(resource->data != dpmcp_dev)) + if (resource->data != dpmcp_dev) return; fsl_destroy_mc_io(mc_io); @@ -304,9 +257,6 @@ int fsl_mc_portal_reset(struct fsl_mc_io *mc_io) int error; struct fsl_mc_device *dpmcp_dev = mc_io->dpmcp_dev; - if (WARN_ON(!dpmcp_dev)) - return -EINVAL; - error = dpmcp_reset(mc_io, 0, dpmcp_dev->mc_handle); if (error < 0) { dev_err(&dpmcp_dev->dev, "dpmcp_reset() failed: %d\n", error); diff --git a/drivers/staging/fsl-mc/bus/mc-sys.c b/drivers/staging/fsl-mc/bus/mc-sys.c index 7ce105bd3977..f09d75d9a976 100644 --- a/drivers/staging/fsl-mc/bus/mc-sys.c +++ b/drivers/staging/fsl-mc/bus/mc-sys.c @@ -1,35 +1,9 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) /* * Copyright 2013-2016 Freescale Semiconductor Inc. * * I/O services to send MC commands to the MC hardware * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ #include <linux/delay.h> @@ -40,7 +14,7 @@ #include <linux/io-64-nonatomic-hi-lo.h> #include "../include/mc.h" -#include "dpmcp.h" +#include "fsl-mc-private.h" /** * Timeout in milliseconds to wait for the completion of an MC command @@ -85,7 +59,7 @@ static int mc_status_to_error(enum mc_cmd_status status) [MC_CMD_STATUS_INVALID_STATE] = -ENODEV, }; - if (WARN_ON((u32)status >= ARRAY_SIZE(mc_status_to_error_map))) + if ((u32)status >= ARRAY_SIZE(mc_status_to_error_map)) return -EINVAL; return mc_status_to_error_map[status]; @@ -273,8 +247,7 @@ int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd) enum mc_cmd_status status; unsigned long irq_flags = 0; - if (WARN_ON(in_irq() && - !(mc_io->flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL))) + if (in_irq() && !(mc_io->flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL)) return -EINVAL; if (mc_io->flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL) @@ -320,4 +293,4 @@ common_exit: return error; } -EXPORT_SYMBOL(mc_send_command); +EXPORT_SYMBOL_GPL(mc_send_command); diff --git a/drivers/staging/fsl-mc/include/dpaa2-fd.h b/drivers/staging/fsl-mc/include/dpaa2-fd.h index cf7857f00a5c..3e022001f0b1 100644 --- a/drivers/staging/fsl-mc/include/dpaa2-fd.h +++ b/drivers/staging/fsl-mc/include/dpaa2-fd.h @@ -1,33 +1,8 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ /* * Copyright 2014-2016 Freescale Semiconductor Inc. * Copyright 2016 NXP * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __FSL_DPAA2_FD_H #define __FSL_DPAA2_FD_H diff --git a/drivers/staging/fsl-mc/include/dpaa2-global.h b/drivers/staging/fsl-mc/include/dpaa2-global.h index 0326447fde4e..9bc0713346a8 100644 --- a/drivers/staging/fsl-mc/include/dpaa2-global.h +++ b/drivers/staging/fsl-mc/include/dpaa2-global.h @@ -1,33 +1,8 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ /* * Copyright 2014-2016 Freescale Semiconductor Inc. * Copyright 2016 NXP * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __FSL_DPAA2_GLOBAL_H #define __FSL_DPAA2_GLOBAL_H diff --git a/drivers/staging/fsl-mc/include/dpaa2-io.h b/drivers/staging/fsl-mc/include/dpaa2-io.h index afc2d060d077..9cb1eec87a9c 100644 --- a/drivers/staging/fsl-mc/include/dpaa2-io.h +++ b/drivers/staging/fsl-mc/include/dpaa2-io.h @@ -1,33 +1,8 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ /* * Copyright 2014-2016 Freescale Semiconductor Inc. * Copyright NXP * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __FSL_DPAA2_IO_H #define __FSL_DPAA2_IO_H @@ -88,6 +63,8 @@ void dpaa2_io_down(struct dpaa2_io *d); irqreturn_t dpaa2_io_irq(struct dpaa2_io *obj); +struct dpaa2_io *dpaa2_io_service_select(int cpu); + /** * struct dpaa2_io_notification_ctx - The DPIO notification context structure * @cb: The callback to be invoked when the notification arrives @@ -120,13 +97,9 @@ void dpaa2_io_service_deregister(struct dpaa2_io *service, int dpaa2_io_service_rearm(struct dpaa2_io *service, struct dpaa2_io_notification_ctx *ctx); -int dpaa2_io_service_pull_fq(struct dpaa2_io *d, u32 fqid, - struct dpaa2_io_store *s); int dpaa2_io_service_pull_channel(struct dpaa2_io *d, u32 channelid, struct dpaa2_io_store *s); -int dpaa2_io_service_enqueue_fq(struct dpaa2_io *d, u32 fqid, - const struct dpaa2_fd *fd); int dpaa2_io_service_enqueue_qd(struct dpaa2_io *d, u32 qdid, u8 prio, u16 qdbin, const struct dpaa2_fd *fd); int dpaa2_io_service_release(struct dpaa2_io *d, u32 bpid, diff --git a/drivers/staging/fsl-mc/include/dpbp.h b/drivers/staging/fsl-mc/include/dpbp.h index e9e04ccea82b..4a1809604319 100644 --- a/drivers/staging/fsl-mc/include/dpbp.h +++ b/drivers/staging/fsl-mc/include/dpbp.h @@ -1,34 +1,7 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ /* * Copyright 2013-2016 Freescale Semiconductor Inc. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __FSL_DPBP_H #define __FSL_DPBP_H diff --git a/drivers/staging/fsl-mc/include/dpcon.h b/drivers/staging/fsl-mc/include/dpcon.h index efa23906b364..062e90ad929b 100644 --- a/drivers/staging/fsl-mc/include/dpcon.h +++ b/drivers/staging/fsl-mc/include/dpcon.h @@ -1,33 +1,7 @@ -/* Copyright 2013-2016 Freescale Semiconductor Inc. +/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ +/* + * Copyright 2013-2016 Freescale Semiconductor Inc. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the above-listed copyright holders nor the - * names of any contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __FSL_DPCON_H #define __FSL_DPCON_H @@ -62,11 +36,6 @@ int dpcon_disable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token); -int dpcon_is_enabled(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 token, - int *en); - int dpcon_reset(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token); @@ -107,9 +76,4 @@ int dpcon_set_notification(struct fsl_mc_io *mc_io, u16 token, struct dpcon_notification_cfg *cfg); -int dpcon_get_api_version(struct fsl_mc_io *mc_io, - u32 cmd_flags, - u16 *major_ver, - u16 *minor_ver); - #endif /* __FSL_DPCON_H */ diff --git a/drivers/staging/fsl-mc/include/mc.h b/drivers/staging/fsl-mc/include/mc.h index aafe63a21f49..765ba41f5987 100644 --- a/drivers/staging/fsl-mc/include/mc.h +++ b/drivers/staging/fsl-mc/include/mc.h @@ -1,12 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Freescale Management Complex (MC) bus public interface * * Copyright (C) 2014-2016 Freescale Semiconductor, Inc. * Author: German Rivera <German.Rivera@freescale.com> * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #ifndef _FSL_MC_H_ #define _FSL_MC_H_ @@ -325,7 +323,7 @@ static inline void mc_cmd_read_api_version(struct mc_command *cmd, struct fsl_mc_io { struct device *dev; u16 flags; - u16 portal_size; + u32 portal_size; phys_addr_t portal_phys_addr; void __iomem *portal_virt_addr; struct fsl_mc_device *dpmcp_dev; @@ -398,4 +396,59 @@ void fsl_mc_free_irqs(struct fsl_mc_device *mc_dev); extern struct bus_type fsl_mc_bus_type; +extern struct device_type fsl_mc_bus_dprc_type; +extern struct device_type fsl_mc_bus_dpni_type; +extern struct device_type fsl_mc_bus_dpio_type; +extern struct device_type fsl_mc_bus_dpsw_type; +extern struct device_type fsl_mc_bus_dpbp_type; +extern struct device_type fsl_mc_bus_dpcon_type; +extern struct device_type fsl_mc_bus_dpmcp_type; +extern struct device_type fsl_mc_bus_dpmac_type; +extern struct device_type fsl_mc_bus_dprtc_type; + +static inline bool is_fsl_mc_bus_dprc(const struct fsl_mc_device *mc_dev) +{ + return mc_dev->dev.type == &fsl_mc_bus_dprc_type; +} + +static inline bool is_fsl_mc_bus_dpni(const struct fsl_mc_device *mc_dev) +{ + return mc_dev->dev.type == &fsl_mc_bus_dpni_type; +} + +static inline bool is_fsl_mc_bus_dpio(const struct fsl_mc_device *mc_dev) +{ + return mc_dev->dev.type == &fsl_mc_bus_dpio_type; +} + +static inline bool is_fsl_mc_bus_dpsw(const struct fsl_mc_device *mc_dev) +{ + return mc_dev->dev.type == &fsl_mc_bus_dpsw_type; +} + +static inline bool is_fsl_mc_bus_dpbp(const struct fsl_mc_device *mc_dev) +{ + return mc_dev->dev.type == &fsl_mc_bus_dpbp_type; +} + +static inline bool is_fsl_mc_bus_dpcon(const struct fsl_mc_device *mc_dev) +{ + return mc_dev->dev.type == &fsl_mc_bus_dpcon_type; +} + +static inline bool is_fsl_mc_bus_dpmcp(const struct fsl_mc_device *mc_dev) +{ + return mc_dev->dev.type == &fsl_mc_bus_dpmcp_type; +} + +static inline bool is_fsl_mc_bus_dpmac(const struct fsl_mc_device *mc_dev) +{ + return mc_dev->dev.type == &fsl_mc_bus_dpmac_type; +} + +static inline bool is_fsl_mc_bus_dprtc(const struct fsl_mc_device *mc_dev) +{ + return mc_dev->dev.type == &fsl_mc_bus_dprtc_type; +} + #endif /* _FSL_MC_H_ */ diff --git a/drivers/staging/fsl-mc/overview.rst b/drivers/staging/fsl-mc/overview.rst new file mode 100644 index 000000000000..79fede4447d6 --- /dev/null +++ b/drivers/staging/fsl-mc/overview.rst @@ -0,0 +1,404 @@ +.. include:: <isonum.txt> + +DPAA2 (Data Path Acceleration Architecture Gen2) Overview +========================================================= + +:Copyright: |copy| 2015 Freescale Semiconductor Inc. +:Copyright: |copy| 2018 NXP + +This document provides an overview of the Freescale DPAA2 architecture +and how it is integrated into the Linux kernel. + +Introduction +============ + +DPAA2 is a hardware architecture designed for high-speeed network +packet processing. DPAA2 consists of sophisticated mechanisms for +processing Ethernet packets, queue management, buffer management, +autonomous L2 switching, virtual Ethernet bridging, and accelerator +(e.g. crypto) sharing. + +A DPAA2 hardware component called the Management Complex (or MC) manages the +DPAA2 hardware resources. The MC provides an object-based abstraction for +software drivers to use the DPAA2 hardware. +The MC uses DPAA2 hardware resources such as queues, buffer pools, and +network ports to create functional objects/devices such as network +interfaces, an L2 switch, or accelerator instances. +The MC provides memory-mapped I/O command interfaces (MC portals) +which DPAA2 software drivers use to operate on DPAA2 objects. + +The diagram below shows an overview of the DPAA2 resource management +architecture:: + + +--------------------------------------+ + | OS | + | DPAA2 drivers | + | | | + +-----------------------------|--------+ + | + | (create,discover,connect + | config,use,destroy) + | + DPAA2 | + +------------------------| mc portal |-+ + | | | + | +- - - - - - - - - - - - -V- - -+ | + | | | | + | | Management Complex (MC) | | + | | | | + | +- - - - - - - - - - - - - - - -+ | + | | + | Hardware Hardware | + | Resources Objects | + | --------- ------- | + | -queues -DPRC | + | -buffer pools -DPMCP | + | -Eth MACs/ports -DPIO | + | -network interface -DPNI | + | profiles -DPMAC | + | -queue portals -DPBP | + | -MC portals ... | + | ... | + | | + +--------------------------------------+ + + +The MC mediates operations such as create, discover, +connect, configuration, and destroy. Fast-path operations +on data, such as packet transmit/receive, are not mediated by +the MC and are done directly using memory mapped regions in +DPIO objects. + +Overview of DPAA2 Objects +========================= + +The section provides a brief overview of some key DPAA2 objects. +A simple scenario is described illustrating the objects involved +in creating a network interfaces. + +DPRC (Datapath Resource Container) +---------------------------------- + +A DPRC is a container object that holds all the other +types of DPAA2 objects. In the example diagram below there +are 8 objects of 5 types (DPMCP, DPIO, DPBP, DPNI, and DPMAC) +in the container. + +:: + + +---------------------------------------------------------+ + | DPRC | + | | + | +-------+ +-------+ +-------+ +-------+ +-------+ | + | | DPMCP | | DPIO | | DPBP | | DPNI | | DPMAC | | + | +-------+ +-------+ +-------+ +---+---+ +---+---+ | + | | DPMCP | | DPIO | | + | +-------+ +-------+ | + | | DPMCP | | + | +-------+ | + | | + +---------------------------------------------------------+ + +From the point of view of an OS, a DPRC behaves similar to a plug and +play bus, like PCI. DPRC commands can be used to enumerate the contents +of the DPRC, discover the hardware objects present (including mappable +regions and interrupts). + +:: + + DPRC.1 (bus) + | + +--+--------+-------+-------+-------+ + | | | | | + DPMCP.1 DPIO.1 DPBP.1 DPNI.1 DPMAC.1 + DPMCP.2 DPIO.2 + DPMCP.3 + +Hardware objects can be created and destroyed dynamically, providing +the ability to hot plug/unplug objects in and out of the DPRC. + +A DPRC has a mappable MMIO region (an MC portal) that can be used +to send MC commands. It has an interrupt for status events (like +hotplug). +All objects in a container share the same hardware "isolation context". +This means that with respect to an IOMMU the isolation granularity +is at the DPRC (container) level, not at the individual object +level. + +DPRCs can be defined statically and populated with objects +via a config file passed to the MC when firmware starts it. + +DPAA2 Objects for an Ethernet Network Interface +----------------------------------------------- + +A typical Ethernet NIC is monolithic-- the NIC device contains TX/RX +queuing mechanisms, configuration mechanisms, buffer management, +physical ports, and interrupts. DPAA2 uses a more granular approach +utilizing multiple hardware objects. Each object provides specialized +functions. Groups of these objects are used by software to provide +Ethernet network interface functionality. This approach provides +efficient use of finite hardware resources, flexibility, and +performance advantages. + +The diagram below shows the objects needed for a simple +network interface configuration on a system with 2 CPUs. + +:: + + +---+---+ +---+---+ + CPU0 CPU1 + +---+---+ +---+---+ + | | + +---+---+ +---+---+ + DPIO DPIO + +---+---+ +---+---+ + \ / + \ / + \ / + +---+---+ + DPNI --- DPBP,DPMCP + +---+---+ + | + | + +---+---+ + DPMAC + +---+---+ + | + port/PHY + +Below the objects are described. For each object a brief description +is provided along with a summary of the kinds of operations the object +supports and a summary of key resources of the object (MMIO regions +and IRQs). + +DPMAC (Datapath Ethernet MAC) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Represents an Ethernet MAC, a hardware device that connects to an Ethernet +PHY and allows physical transmission and reception of Ethernet frames. + +- MMIO regions: none +- IRQs: DPNI link change +- commands: set link up/down, link config, get stats, + IRQ config, enable, reset + +DPNI (Datapath Network Interface) +Contains TX/RX queues, network interface configuration, and RX buffer pool +configuration mechanisms. The TX/RX queues are in memory and are identified +by queue number. + +- MMIO regions: none +- IRQs: link state +- commands: port config, offload config, queue config, + parse/classify config, IRQ config, enable, reset + +DPIO (Datapath I/O) +~~~~~~~~~~~~~~~~~~~ +Provides interfaces to enqueue and dequeue +packets and do hardware buffer pool management operations. The DPAA2 +architecture separates the mechanism to access queues (the DPIO object) +from the queues themselves. The DPIO provides an MMIO interface to +enqueue/dequeue packets. To enqueue something a descriptor is written +to the DPIO MMIO region, which includes the target queue number. +There will typically be one DPIO assigned to each CPU. This allows all +CPUs to simultaneously perform enqueue/dequeued operations. DPIOs are +expected to be shared by different DPAA2 drivers. + +- MMIO regions: queue operations, buffer management +- IRQs: data availability, congestion notification, buffer + pool depletion +- commands: IRQ config, enable, reset + +DPBP (Datapath Buffer Pool) +~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Represents a hardware buffer pool. + +- MMIO regions: none +- IRQs: none +- commands: enable, reset + +DPMCP (Datapath MC Portal) +~~~~~~~~~~~~~~~~~~~~~~~~~~ +Provides an MC command portal. +Used by drivers to send commands to the MC to manage +objects. + +- MMIO regions: MC command portal +- IRQs: command completion +- commands: IRQ config, enable, reset + +Object Connections +================== +Some objects have explicit relationships that must +be configured: + +- DPNI <--> DPMAC +- DPNI <--> DPNI +- DPNI <--> L2-switch-port + + A DPNI must be connected to something such as a DPMAC, + another DPNI, or L2 switch port. The DPNI connection + is made via a DPRC command. + +:: + + +-------+ +-------+ + | DPNI | | DPMAC | + +---+---+ +---+---+ + | | + +==========+ + +- DPNI <--> DPBP + + A network interface requires a 'buffer pool' (DPBP + object) which provides a list of pointers to memory + where received Ethernet data is to be copied. The + Ethernet driver configures the DPBPs associated with + the network interface. + +Interrupts +========== +All interrupts generated by DPAA2 objects are message +interrupts. At the hardware level message interrupts +generated by devices will normally have 3 components-- +1) a non-spoofable 'device-id' expressed on the hardware +bus, 2) an address, 3) a data value. + +In the case of DPAA2 devices/objects, all objects in the +same container/DPRC share the same 'device-id'. +For ARM-based SoC this is the same as the stream ID. + + +DPAA2 Linux Drivers Overview +============================ + +This section provides an overview of the Linux kernel drivers for +DPAA2-- 1) the bus driver and associated "DPAA2 infrastructure" +drivers and 2) functional object drivers (such as Ethernet). + +As described previously, a DPRC is a container that holds the other +types of DPAA2 objects. It is functionally similar to a plug-and-play +bus controller. +Each object in the DPRC is a Linux "device" and is bound to a driver. +The diagram below shows the Linux drivers involved in a networking +scenario and the objects bound to each driver. A brief description +of each driver follows. + +:: + + +------------+ + | OS Network | + | Stack | + +------------+ +------------+ + | Allocator |. . . . . . . | Ethernet | + |(DPMCP,DPBP)| | (DPNI) | + +-.----------+ +---+---+----+ + . . ^ | + . . <data avail, | | <enqueue, + . . tx confirm> | | dequeue> + +-------------+ . | | + | DPRC driver | . +---+---V----+ +---------+ + | (DPRC) | . . . . . .| DPIO driver| | MAC | + +----------+--+ | (DPIO) | | (DPMAC) | + | +------+-----+ +-----+---+ + |<dev add/remove> | | + | | | + +--------+----------+ | +--+---+ + | MC-bus driver | | | PHY | + | | | |driver| + | /bus/fsl-mc | | +--+---+ + +-------------------+ | | + | | + ========================= HARDWARE =========|=================|====== + DPIO | + | | + DPNI---DPBP | + | | + DPMAC | + | | + PHY ---------------+ + ============================================|======================== + +A brief description of each driver is provided below. + +MC-bus driver +------------- +The MC-bus driver is a platform driver and is probed from a +node in the device tree (compatible "fsl,qoriq-mc") passed in by boot +firmware. It is responsible for bootstrapping the DPAA2 kernel +infrastructure. +Key functions include: + +- registering a new bus type named "fsl-mc" with the kernel, + and implementing bus call-backs (e.g. match/uevent/dev_groups) +- implementing APIs for DPAA2 driver registration and for device + add/remove +- creates an MSI IRQ domain +- doing a 'device add' to expose the 'root' DPRC, in turn triggering + a bind of the root DPRC to the DPRC driver + +The binding for the MC-bus device-tree node can be consulted at +*Documentation/devicetree/bindings/misc/fsl,qoriq-mc.txt*. +The sysfs bind/unbind interfaces for the MC-bus can be consulted at +*Documentation/ABI/testing/sysfs-bus-fsl-mc*. + +DPRC driver +----------- +The DPRC driver is bound to DPRC objects and does runtime management +of a bus instance. It performs the initial bus scan of the DPRC +and handles interrupts for container events such as hot plug by +re-scanning the DPRC. + +Allocator +--------- +Certain objects such as DPMCP and DPBP are generic and fungible, +and are intended to be used by other drivers. For example, +the DPAA2 Ethernet driver needs: + +- DPMCPs to send MC commands, to configure network interfaces +- DPBPs for network buffer pools + +The allocator driver registers for these allocatable object types +and those objects are bound to the allocator when the bus is probed. +The allocator maintains a pool of objects that are available for +allocation by other DPAA2 drivers. + +DPIO driver +----------- +The DPIO driver is bound to DPIO objects and provides services that allow +other drivers such as the Ethernet driver to enqueue and dequeue data for +their respective objects. +Key services include: + +- data availability notifications +- hardware queuing operations (enqueue and dequeue of data) +- hardware buffer pool management + +To transmit a packet the Ethernet driver puts data on a queue and +invokes a DPIO API. For receive, the Ethernet driver registers +a data availability notification callback. To dequeue a packet +a DPIO API is used. +There is typically one DPIO object per physical CPU for optimum +performance, allowing different CPUs to simultaneously enqueue +and dequeue data. + +The DPIO driver operates on behalf of all DPAA2 drivers +active in the kernel-- Ethernet, crypto, compression, +etc. + +Ethernet driver +--------------- +The Ethernet driver is bound to a DPNI and implements the kernel +interfaces needed to connect the DPAA2 network interface to +the network stack. +Each DPNI corresponds to a Linux network interface. + +MAC driver +---------- +An Ethernet PHY is an off-chip, board specific component and is managed +by the appropriate PHY driver via an mdio bus. The MAC driver +plays a role of being a proxy between the PHY driver and the +MC. It does this proxy via the MC commands to a DPMAC object. +If the PHY driver signals a link change, the MAC driver notifies +the MC via a DPMAC command. If a network interface is brought +up or down, the MC notifies the DPMAC driver via an interrupt and +the driver can take appropriate action. diff --git a/drivers/staging/fwserial/dma_fifo.c b/drivers/staging/fwserial/dma_fifo.c index 8b23a553fd4a..5dcbab6fd622 100644 --- a/drivers/staging/fwserial/dma_fifo.c +++ b/drivers/staging/fwserial/dma_fifo.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * DMA-able FIFO implementation * * Copyright (C) 2012 Peter Hurley <peter@hurleysoftware.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/kernel.h> diff --git a/drivers/staging/fwserial/dma_fifo.h b/drivers/staging/fwserial/dma_fifo.h index 37a91c6a1709..c46a06336975 100644 --- a/drivers/staging/fwserial/dma_fifo.h +++ b/drivers/staging/fwserial/dma_fifo.h @@ -1,17 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * DMA-able FIFO interface * * Copyright (C) 2012 Peter Hurley <peter@hurleysoftware.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _DMA_FIFO_H_ diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c index bba7e9c888b3..1993b03a6f2d 100644 --- a/drivers/staging/fwserial/fwserial.c +++ b/drivers/staging/fwserial/fwserial.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * FireWire Serial driver * * Copyright (C) 2012 Peter Hurley <peter@hurleysoftware.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt diff --git a/drivers/staging/greybus/arche-apb-ctrl.c b/drivers/staging/greybus/arche-apb-ctrl.c index b0c66112eb18..cc8d6fc831b4 100644 --- a/drivers/staging/greybus/arche-apb-ctrl.c +++ b/drivers/staging/greybus/arche-apb-ctrl.c @@ -72,14 +72,14 @@ static int coldboot_seq(struct platform_device *pdev) int ret; if (apb->init_disabled || - apb->state == ARCHE_PLATFORM_STATE_ACTIVE) + apb->state == ARCHE_PLATFORM_STATE_ACTIVE) return 0; /* Hold APB in reset state */ assert_reset(apb->resetn_gpio); if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && - gpio_is_valid(apb->spi_en_gpio)) + gpio_is_valid(apb->spi_en_gpio)) devm_gpio_free(dev, apb->spi_en_gpio); /* Enable power to APB */ @@ -122,7 +122,7 @@ static int fw_flashing_seq(struct platform_device *pdev) int ret; if (apb->init_disabled || - apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING) + apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING) return 0; ret = regulator_enable(apb->vcore); @@ -146,7 +146,7 @@ static int fw_flashing_seq(struct platform_device *pdev) flags = GPIOF_OUT_INIT_LOW; ret = devm_gpio_request_one(dev, apb->spi_en_gpio, - flags, "apb_spi_en"); + flags, "apb_spi_en"); if (ret) { dev_err(dev, "Failed requesting SPI bus en gpio %d\n", apb->spi_en_gpio); @@ -174,11 +174,11 @@ static int standby_boot_seq(struct platform_device *pdev) * then we do not want to change the state */ if (apb->state == ARCHE_PLATFORM_STATE_STANDBY || - apb->state == ARCHE_PLATFORM_STATE_OFF) + apb->state == ARCHE_PLATFORM_STATE_OFF) return 0; if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && - gpio_is_valid(apb->spi_en_gpio)) + gpio_is_valid(apb->spi_en_gpio)) devm_gpio_free(dev, apb->spi_en_gpio); /* @@ -203,7 +203,7 @@ static void poweroff_seq(struct platform_device *pdev) return; if (apb->state == ARCHE_PLATFORM_STATE_FW_FLASHING && - gpio_is_valid(apb->spi_en_gpio)) + gpio_is_valid(apb->spi_en_gpio)) devm_gpio_free(dev, apb->spi_en_gpio); /* disable the clock */ @@ -251,7 +251,8 @@ void apb_ctrl_poweroff(struct device *dev) } static ssize_t state_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) + struct device_attribute *attr, + const char *buf, size_t count) { struct platform_device *pdev = to_platform_device(dev); struct arche_apb_ctrl_drvdata *apb = platform_get_drvdata(pdev); @@ -297,7 +298,7 @@ static ssize_t state_store(struct device *dev, } static ssize_t state_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, char *buf) { struct arche_apb_ctrl_drvdata *apb = dev_get_drvdata(dev); @@ -319,7 +320,7 @@ static ssize_t state_show(struct device *dev, static DEVICE_ATTR_RW(state); static int apb_ctrl_get_devtree_data(struct platform_device *pdev, - struct arche_apb_ctrl_drvdata *apb) + struct arche_apb_ctrl_drvdata *apb) { struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; @@ -331,10 +332,10 @@ static int apb_ctrl_get_devtree_data(struct platform_device *pdev, return apb->resetn_gpio; } ret = devm_gpio_request_one(dev, apb->resetn_gpio, - GPIOF_OUT_INIT_LOW, "apb-reset"); + GPIOF_OUT_INIT_LOW, "apb-reset"); if (ret) { dev_err(dev, "Failed requesting reset gpio %d\n", - apb->resetn_gpio); + apb->resetn_gpio); return ret; } @@ -344,10 +345,10 @@ static int apb_ctrl_get_devtree_data(struct platform_device *pdev, return apb->boot_ret_gpio; } ret = devm_gpio_request_one(dev, apb->boot_ret_gpio, - GPIOF_OUT_INIT_LOW, "boot retention"); + GPIOF_OUT_INIT_LOW, "boot retention"); if (ret) { dev_err(dev, "Failed requesting bootret gpio %d\n", - apb->boot_ret_gpio); + apb->boot_ret_gpio); return ret; } @@ -358,10 +359,10 @@ static int apb_ctrl_get_devtree_data(struct platform_device *pdev, return apb->pwroff_gpio; } ret = devm_gpio_request_one(dev, apb->pwroff_gpio, - GPIOF_IN, "pwroff_n"); + GPIOF_IN, "pwroff_n"); if (ret) { dev_err(dev, "Failed requesting pwroff_n gpio %d\n", - apb->pwroff_gpio); + apb->pwroff_gpio); return ret; } @@ -371,10 +372,10 @@ static int apb_ctrl_get_devtree_data(struct platform_device *pdev, dev_warn(dev, "failed to get clock en gpio\n"); } else if (gpio_is_valid(apb->clk_en_gpio)) { ret = devm_gpio_request_one(dev, apb->clk_en_gpio, - GPIOF_OUT_INIT_LOW, "apb_clk_en"); + GPIOF_OUT_INIT_LOW, "apb_clk_en"); if (ret) { dev_warn(dev, "Failed requesting APB clock en gpio %d\n", - apb->clk_en_gpio); + apb->clk_en_gpio); return ret; } } @@ -407,7 +408,7 @@ static int apb_ctrl_get_devtree_data(struct platform_device *pdev, apb->spi_en_gpio = of_get_named_gpio(np, "spi-en-gpio", 0); if (apb->spi_en_gpio >= 0) { if (of_property_read_bool(pdev->dev.of_node, - "spi-en-active-high")) + "spi-en-active-high")) apb->spi_en_polarity_high = true; } diff --git a/drivers/staging/greybus/arche-platform.c b/drivers/staging/greybus/arche-platform.c index ace4eb365c0e..83254a72a7bb 100644 --- a/drivers/staging/greybus/arche-platform.c +++ b/drivers/staging/greybus/arche-platform.c @@ -233,7 +233,7 @@ arche_platform_coldboot_seq(struct arche_platform_drvdata *arche_pdata) ret = clk_prepare_enable(arche_pdata->svc_ref_clk); if (ret) { dev_err(arche_pdata->dev, "failed to enable svc_ref_clk: %d\n", - ret); + ret); return ret; } @@ -269,7 +269,7 @@ arche_platform_fw_flashing_seq(struct arche_platform_drvdata *arche_pdata) ret = clk_prepare_enable(arche_pdata->svc_ref_clk); if (ret) { dev_err(arche_pdata->dev, "failed to enable svc_ref_clk: %d\n", - ret); + ret); return ret; } @@ -312,7 +312,8 @@ arche_platform_poweroff_seq(struct arche_platform_drvdata *arche_pdata) } static ssize_t state_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) + struct device_attribute *attr, + const char *buf, size_t count) { struct platform_device *pdev = to_platform_device(dev); struct arche_platform_drvdata *arche_pdata = platform_get_drvdata(pdev); @@ -376,7 +377,7 @@ exit: } static ssize_t state_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, char *buf) { struct arche_platform_drvdata *arche_pdata = dev_get_drvdata(dev); @@ -443,7 +444,7 @@ static int arche_platform_probe(struct platform_device *pdev) /* setup svc reset gpio */ arche_pdata->is_reset_act_hi = of_property_read_bool(np, - "svc,reset-active-high"); + "svc,reset-active-high"); arche_pdata->svc_reset_gpio = of_get_named_gpio(np, "svc,reset-gpio", 0); @@ -457,7 +458,7 @@ static int arche_platform_probe(struct platform_device *pdev) return ret; } ret = gpio_direction_output(arche_pdata->svc_reset_gpio, - arche_pdata->is_reset_act_hi); + arche_pdata->is_reset_act_hi); if (ret) { dev_err(dev, "failed to set svc-reset gpio dir:%d\n", ret); return ret; @@ -465,7 +466,8 @@ static int arche_platform_probe(struct platform_device *pdev) arche_platform_set_state(arche_pdata, ARCHE_PLATFORM_STATE_OFF); arche_pdata->svc_sysboot_gpio = of_get_named_gpio(np, - "svc,sysboot-gpio", 0); + "svc,sysboot-gpio", + 0); if (arche_pdata->svc_sysboot_gpio < 0) { dev_err(dev, "failed to get sysboot gpio\n"); return arche_pdata->svc_sysboot_gpio; @@ -483,7 +485,8 @@ static int arche_platform_probe(struct platform_device *pdev) /* setup the clock request gpio first */ arche_pdata->svc_refclk_req = of_get_named_gpio(np, - "svc,refclk-req-gpio", 0); + "svc,refclk-req-gpio", + 0); if (arche_pdata->svc_refclk_req < 0) { dev_err(dev, "failed to get svc clock-req gpio\n"); return arche_pdata->svc_refclk_req; @@ -525,7 +528,7 @@ static int arche_platform_probe(struct platform_device *pdev) "wake detect"); if (ret) { dev_err(dev, "Failed requesting wake_detect gpio %d\n", - arche_pdata->wake_detect_gpio); + arche_pdata->wake_detect_gpio); return ret; } diff --git a/drivers/staging/greybus/audio_codec.c b/drivers/staging/greybus/audio_codec.c index fdb9e83cc34b..35acd55ca5ab 100644 --- a/drivers/staging/greybus/audio_codec.c +++ b/drivers/staging/greybus/audio_codec.c @@ -47,7 +47,7 @@ static int gbaudio_module_enable_tx(struct gbaudio_codec_info *codec, int module_state, ret = 0; u16 data_cport, i2s_port, cportid; u8 sig_bits, channels; - uint32_t format, rate; + u32 format, rate; struct gbaudio_data_connection *data; struct gbaudio_stream_params *params; @@ -182,7 +182,7 @@ static int gbaudio_module_enable_rx(struct gbaudio_codec_info *codec, int module_state, ret = 0; u16 data_cport, i2s_port, cportid; u8 sig_bits, channels; - uint32_t format, rate; + u32 format, rate; struct gbaudio_data_connection *data; struct gbaudio_stream_params *params; @@ -319,7 +319,7 @@ int gbaudio_module_update(struct gbaudio_codec_info *codec, char intf_name[NAME_SIZE], dir[NAME_SIZE]; dev_dbg(module->dev, "%s:Module update %s sequence\n", w->name, - enable ? "Enable":"Disable"); + enable ? "Enable" : "Disable"); if ((w->id != snd_soc_dapm_aif_in) && (w->id != snd_soc_dapm_aif_out)) { dev_dbg(codec->dev, "No action required for %s\n", w->name); @@ -412,7 +412,7 @@ static int gbcodec_hw_params(struct snd_pcm_substream *substream, { int ret; u8 sig_bits, channels; - uint32_t format, rate; + u32 format, rate; struct gbaudio_module_info *module; struct gbaudio_data_connection *data; struct gb_bundle *bundle; @@ -567,7 +567,7 @@ static int gbcodec_prepare(struct snd_pcm_substream *substream, if (ret) { mutex_unlock(&codec->lock); dev_err_ratelimited(dai->dev, "set_data_size failed:%d\n", - ret); + ret); return ret; } @@ -587,9 +587,8 @@ static int gbcodec_mute_stream(struct snd_soc_dai *dai, int mute, int stream) struct gbaudio_codec_info *codec = dev_get_drvdata(dai->dev); struct gbaudio_stream_params *params; - dev_dbg(dai->dev, "Mute:%d, Direction:%s\n", mute, - stream ? "CAPTURE":"PLAYBACK"); + stream ? "CAPTURE" : "PLAYBACK"); mutex_lock(&codec->lock); @@ -827,7 +826,7 @@ int gbaudio_register_module(struct gbaudio_module_info *module) module->num_dapm_widgets); if (module->controls) snd_soc_add_codec_controls(codec, module->controls, - module->num_controls); + module->num_controls); if (module->dapm_routes) snd_soc_dapm_add_routes(&codec->dapm, module->dapm_routes, module->num_dapm_routes); @@ -842,8 +841,8 @@ int gbaudio_register_module(struct gbaudio_module_info *module) * from codec->jack_list */ list_for_each_entry(jack, &codec->jack_list, list) { - if ((jack == &module->headset_jack) - || (jack == &module->button_jack)) + if ((jack == &module->headset_jack) || + (jack == &module->button_jack)) snd_device_register(codec->card->snd_card, jack->jack); } @@ -907,7 +906,6 @@ static void gbaudio_codec_clean_data_rx(struct gbaudio_data_connection *data) data->state[1] = GBAUDIO_CODEC_SHUTDOWN; } - static void gbaudio_codec_cleanup(struct gbaudio_module_info *module) { struct gbaudio_data_connection *data; @@ -923,7 +921,6 @@ static void gbaudio_codec_cleanup(struct gbaudio_module_info *module) if (cap_state > GBAUDIO_CODEC_SHUTDOWN) gbaudio_codec_clean_data_rx(data); - } } @@ -972,7 +969,7 @@ void gbaudio_unregister_module(struct gbaudio_module_info *module) dev_dbg(codec->dev, "Removing %d controls\n", module->num_controls); snd_soc_remove_codec_controls(codec, module->controls, - module->num_controls); + module->num_controls); } if (module->dapm_widgets) { dev_dbg(codec->dev, "Removing %d widgets\n", diff --git a/drivers/staging/greybus/audio_codec.h b/drivers/staging/greybus/audio_codec.h index 161b37c8ef17..a1d5440552d4 100644 --- a/drivers/staging/greybus/audio_codec.h +++ b/drivers/staging/greybus/audio_codec.h @@ -53,7 +53,7 @@ enum gbaudio_codec_state { struct gbaudio_stream_params { int state; u8 sig_bits, channels; - uint32_t format, rate; + u32 format, rate; }; struct gbaudio_codec_dai { @@ -159,7 +159,7 @@ struct gbaudio_module_info { }; int gbaudio_tplg_parse_data(struct gbaudio_module_info *module, - struct gb_audio_topology *tplg_data); + struct gb_audio_topology *tplg_data); void gbaudio_tplg_release(struct gbaudio_module_info *module); int gbaudio_module_update(struct gbaudio_codec_info *codec, @@ -183,12 +183,12 @@ extern int gb_audio_gb_enable_widget(struct gb_connection *connection, extern int gb_audio_gb_disable_widget(struct gb_connection *connection, u8 widget_id); extern int gb_audio_gb_get_pcm(struct gb_connection *connection, - u16 data_cport, uint32_t *format, - uint32_t *rate, u8 *channels, + u16 data_cport, u32 *format, + u32 *rate, u8 *channels, u8 *sig_bits); extern int gb_audio_gb_set_pcm(struct gb_connection *connection, - u16 data_cport, uint32_t format, - uint32_t rate, u8 channels, + u16 data_cport, u32 format, + u32 rate, u8 channels, u8 sig_bits); extern int gb_audio_gb_set_tx_data_size(struct gb_connection *connection, u16 data_cport, u16 size); diff --git a/drivers/staging/greybus/authentication.c b/drivers/staging/greybus/authentication.c index 16cc65e1472b..a5d7c53df987 100644 --- a/drivers/staging/greybus/authentication.c +++ b/drivers/staging/greybus/authentication.c @@ -202,7 +202,7 @@ static int cap_release(struct inode *inode, struct file *file) } static int cap_ioctl(struct gb_cap *cap, unsigned int cmd, - void __user *buf) + void __user *buf) { struct cap_ioc_get_endpoint_uid endpoint_uid; struct cap_ioc_get_ims_certificate *ims_cert; diff --git a/drivers/staging/greybus/camera.c b/drivers/staging/greybus/camera.c index f13f16b63d7e..07ebfb88db9b 100644 --- a/drivers/staging/greybus/camera.c +++ b/drivers/staging/greybus/camera.c @@ -918,7 +918,7 @@ static ssize_t gb_camera_debugfs_configure_streams(struct gb_camera *gcam, /* Retrieve number of streams to configure */ token = strsep(&buf, ";"); - if (token == NULL) + if (!token) return -EINVAL; ret = kstrtouint(token, 10, &nstreams); @@ -929,7 +929,7 @@ static ssize_t gb_camera_debugfs_configure_streams(struct gb_camera *gcam, return -EINVAL; token = strsep(&buf, ";"); - if (token == NULL) + if (!token) return -EINVAL; ret = kstrtouint(token, 10, &flags); @@ -946,7 +946,7 @@ static ssize_t gb_camera_debugfs_configure_streams(struct gb_camera *gcam, /* width */ token = strsep(&buf, ";"); - if (token == NULL) { + if (!token) { ret = -EINVAL; goto done; } @@ -956,7 +956,7 @@ static ssize_t gb_camera_debugfs_configure_streams(struct gb_camera *gcam, /* height */ token = strsep(&buf, ";"); - if (token == NULL) + if (!token) goto done; ret = kstrtouint(token, 10, &stream->height); @@ -965,7 +965,7 @@ static ssize_t gb_camera_debugfs_configure_streams(struct gb_camera *gcam, /* Image format code */ token = strsep(&buf, ";"); - if (token == NULL) + if (!token) goto done; ret = kstrtouint(token, 16, &stream->format); @@ -1009,7 +1009,7 @@ static ssize_t gb_camera_debugfs_capture(struct gb_camera *gcam, /* Request id */ token = strsep(&buf, ";"); - if (token == NULL) + if (!token) return -EINVAL; ret = kstrtouint(token, 10, &request_id); if (ret < 0) @@ -1017,7 +1017,7 @@ static ssize_t gb_camera_debugfs_capture(struct gb_camera *gcam, /* Stream mask */ token = strsep(&buf, ";"); - if (token == NULL) + if (!token) return -EINVAL; ret = kstrtouint(token, 16, &streams_mask); if (ret < 0) @@ -1025,7 +1025,7 @@ static ssize_t gb_camera_debugfs_capture(struct gb_camera *gcam, /* number of frames */ token = strsep(&buf, ";"); - if (token == NULL) + if (!token) return -EINVAL; ret = kstrtouint(token, 10, &num_frames); if (ret < 0) diff --git a/drivers/staging/gs_fpgaboot/io.h b/drivers/staging/gs_fpgaboot/io.h index 5e839b1fc884..bc5d99cbda8f 100644 --- a/drivers/staging/gs_fpgaboot/io.h +++ b/drivers/staging/gs_fpgaboot/io.h @@ -7,12 +7,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define GPDIR 0 diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index cadfb96734ed..f01595593ce2 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c @@ -271,7 +271,7 @@ static int ad7192_setup(struct ad7192_state *st, if (pdata->sinc3_en) st->mode |= AD7192_MODE_SINC3; - if (pdata->refin2_en && (st->devid != ID_AD7195)) + if (pdata->refin2_en && st->devid != ID_AD7195) st->conf |= AD7192_CONF_REFSEL; if (pdata->chop_en) { diff --git a/drivers/staging/iio/cdc/ad7152.c b/drivers/staging/iio/cdc/ad7152.c index 61377ca444de..19dc896603a1 100644 --- a/drivers/staging/iio/cdc/ad7152.c +++ b/drivers/staging/iio/cdc/ad7152.c @@ -47,7 +47,7 @@ #define AD7152_STATUS_PWDN BIT(7) /* Setup Register Bit Designations (AD7152_REG_CHx_SETUP) */ -#define AD7152_SETUP_CAPDIFF (1 << 5) +#define AD7152_SETUP_CAPDIFF BIT(5) #define AD7152_SETUP_RANGE_2pF (0 << 6) #define AD7152_SETUP_RANGE_0_5pF (1 << 6) #define AD7152_SETUP_RANGE_1pF (2 << 6) @@ -55,8 +55,8 @@ #define AD7152_SETUP_RANGE(x) ((x) << 6) /* Config Register Bit Designations (AD7152_REG_CFG) */ -#define AD7152_CONF_CH2EN (1 << 3) -#define AD7152_CONF_CH1EN (1 << 4) +#define AD7152_CONF_CH2EN BIT(3) +#define AD7152_CONF_CH1EN BIT(4) #define AD7152_CONF_MODE_IDLE (0 << 0) #define AD7152_CONF_MODE_CONT_CONV (1 << 0) #define AD7152_CONF_MODE_SINGLE_CONV (2 << 0) @@ -64,7 +64,7 @@ #define AD7152_CONF_MODE_GAIN_CAL (6 << 0) /* Capdac Register Bit Designations (AD7152_REG_CAPDAC_XXX) */ -#define AD7152_CAPDAC_DACEN (1 << 7) +#define AD7152_CAPDAC_DACEN BIT(7) #define AD7152_CAPDAC_DACP(x) ((x) & 0x1F) /* CFG2 Register Bit Designations (AD7152_REG_CFG2) */ @@ -118,22 +118,23 @@ static inline ssize_t ad7152_start_calib(struct device *dev, mutex_lock(&chip->state_lock); ret = i2c_smbus_write_byte_data(chip->client, AD7152_REG_CFG, regval); - if (ret < 0) { - mutex_unlock(&chip->state_lock); - return ret; - } + if (ret < 0) + goto unlock; do { mdelay(20); ret = i2c_smbus_read_byte_data(chip->client, AD7152_REG_CFG); - if (ret < 0) { - mutex_unlock(&chip->state_lock); - return ret; - } + if (ret < 0) + goto unlock; + } while ((ret == regval) && timeout--); mutex_unlock(&chip->state_lock); return len; + +unlock: + mutex_unlock(&chip->state_lock); + return ret; } static ssize_t ad7152_start_offset_calib(struct device *dev, diff --git a/drivers/staging/iio/cdc/ad7746.c b/drivers/staging/iio/cdc/ad7746.c index a124853a05f0..c4a864725376 100644 --- a/drivers/staging/iio/cdc/ad7746.c +++ b/drivers/staging/iio/cdc/ad7746.c @@ -302,23 +302,24 @@ static inline ssize_t ad7746_start_calib(struct device *dev, mutex_lock(&chip->lock); regval |= chip->config; ret = i2c_smbus_write_byte_data(chip->client, AD7746_REG_CFG, regval); - if (ret < 0) { - mutex_unlock(&chip->lock); - return ret; - } + if (ret < 0) + goto unlock; do { msleep(20); ret = i2c_smbus_read_byte_data(chip->client, AD7746_REG_CFG); - if (ret < 0) { - mutex_unlock(&chip->lock); - return ret; - } + if (ret < 0) + goto unlock; + } while ((ret == regval) && timeout--); mutex_unlock(&chip->lock); return len; + +unlock: + mutex_unlock(&chip->lock); + return ret; } static ssize_t ad7746_start_offset_calib(struct device *dev, diff --git a/drivers/staging/iio/light/tsl2x7x.c b/drivers/staging/iio/light/tsl2x7x.c index 42ed9c015aaf..126e11530ce0 100644 --- a/drivers/staging/iio/light/tsl2x7x.c +++ b/drivers/staging/iio/light/tsl2x7x.c @@ -1441,7 +1441,8 @@ static irqreturn_t tsl2x7x_event_handler(int irq, void *private) static struct attribute *tsl2x7x_ALS_device_attrs[] = { &dev_attr_in_illuminance0_calibscale_available.attr, - &iio_const_attr_in_illuminance0_integration_time_available.dev_attr.attr, + &iio_const_attr_in_illuminance0_integration_time_available + .dev_attr.attr, &dev_attr_in_illuminance0_target_input.attr, &dev_attr_in_illuminance0_calibrate.attr, &dev_attr_in_illuminance0_lux_table.attr, @@ -1455,7 +1456,8 @@ static struct attribute *tsl2x7x_PRX_device_attrs[] = { static struct attribute *tsl2x7x_ALSPRX_device_attrs[] = { &dev_attr_in_illuminance0_calibscale_available.attr, - &iio_const_attr_in_illuminance0_integration_time_available.dev_attr.attr, + &iio_const_attr_in_illuminance0_integration_time_available + .dev_attr.attr, &dev_attr_in_illuminance0_target_input.attr, &dev_attr_in_illuminance0_calibrate.attr, &dev_attr_in_illuminance0_lux_table.attr, @@ -1471,7 +1473,8 @@ static struct attribute *tsl2x7x_PRX2_device_attrs[] = { static struct attribute *tsl2x7x_ALSPRX2_device_attrs[] = { &dev_attr_in_illuminance0_calibscale_available.attr, - &iio_const_attr_in_illuminance0_integration_time_available.dev_attr.attr, + &iio_const_attr_in_illuminance0_integration_time_available + .dev_attr.attr, &dev_attr_in_illuminance0_target_input.attr, &dev_attr_in_illuminance0_calibrate.attr, &dev_attr_in_illuminance0_lux_table.attr, diff --git a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c index d80dcf82eba9..71f11d7472c0 100644 --- a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c +++ b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c @@ -78,9 +78,9 @@ static int iio_bfin_tmr_set_state(struct iio_trigger *trig, bool state) return 0; } -static ssize_t iio_bfin_tmr_frequency_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t frequency_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { struct iio_trigger *trig = to_iio_trigger(dev); struct bfin_tmr_state *st = iio_trigger_get_drvdata(trig); @@ -116,9 +116,9 @@ static ssize_t iio_bfin_tmr_frequency_store(struct device *dev, return count; } -static ssize_t iio_bfin_tmr_frequency_show(struct device *dev, - struct device_attribute *attr, - char *buf) +static ssize_t frequency_show(struct device *dev, + struct device_attribute *attr, + char *buf) { struct iio_trigger *trig = to_iio_trigger(dev); struct bfin_tmr_state *st = iio_trigger_get_drvdata(trig); @@ -133,8 +133,7 @@ static ssize_t iio_bfin_tmr_frequency_show(struct device *dev, return sprintf(buf, "%lu\n", val); } -static DEVICE_ATTR(frequency, 0644, iio_bfin_tmr_frequency_show, - iio_bfin_tmr_frequency_store); +static DEVICE_ATTR_RW(frequency); static struct attribute *iio_bfin_tmr_trigger_attrs[] = { &dev_attr_frequency.attr, @@ -187,9 +186,9 @@ static int iio_bfin_tmr_trigger_probe(struct platform_device *pdev) return -ENOMEM; st->irq = platform_get_irq(pdev, 0); - if (!st->irq) { + if (st->irq < 0) { dev_err(&pdev->dev, "No IRQs specified"); - return -ENODEV; + return st->irq; } ret = iio_bfin_tmr_get_number(st->irq); diff --git a/drivers/staging/ipx/Kconfig b/drivers/staging/ipx/Kconfig new file mode 100644 index 000000000000..cdff083d0ee6 --- /dev/null +++ b/drivers/staging/ipx/Kconfig @@ -0,0 +1,61 @@ +# +# IPX configuration +# +config IPX + tristate "The IPX protocol" + depends on NET + select LLC + ---help--- + This is support for the Novell networking protocol, IPX, commonly + used for local networks of Windows machines. You need it if you + want to access Novell NetWare file or print servers using the Linux + Novell client ncpfs (available from + <ftp://platan.vc.cvut.cz/pub/linux/ncpfs/>) or from + within the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, + available from <http://www.tldp.org/docs.html#howto>). In order + to do the former, you'll also have to say Y to "NCP file system + support", below. + + IPX is similar in scope to IP, while SPX, which runs on top of IPX, + is similar to TCP. + + To turn your Linux box into a fully featured NetWare file server and + IPX router, say Y here and fetch either lwared from + <ftp://ibiblio.org/pub/Linux/system/network/daemons/> or + mars_nwe from <ftp://www.compu-art.de/mars_nwe/>. For more + information, read the IPX-HOWTO available from + <http://www.tldp.org/docs.html#howto>. + + The IPX driver would enlarge your kernel by about 16 KB. To compile + this driver as a module, choose M here: the module will be called ipx. + Unless you want to integrate your Linux box with a local Novell + network, say N. + +config IPX_INTERN + bool "IPX: Full internal IPX network" + depends on IPX + ---help--- + Every IPX network has an address that identifies it. Sometimes it is + useful to give an IPX "network" address to your Linux box as well + (for example if your box is acting as a file server for different + IPX networks: it will then be accessible from everywhere using the + same address). The way this is done is to create a virtual internal + "network" inside your box and to assign an IPX address to this + network. Say Y here if you want to do this; read the IPX-HOWTO at + <http://www.tldp.org/docs.html#howto> for details. + + The full internal IPX network enables you to allocate sockets on + different virtual nodes of the internal network. This is done by + evaluating the field sipx_node of the socket address given to the + bind call. So applications should always initialize the node field + to 0 when binding a socket on the primary network. In this case the + socket is assigned the default node that has been given to the + kernel when the internal network was created. By enabling the full + internal IPX network the cross-forwarding of packets targeted at + 'special' sockets to sockets listening on the primary network is + disabled. This might break existing applications, especially RIP/SAP + daemons. A RIP/SAP daemon that works well with the full internal net + can be found on <ftp://ftp.gwdg.de/pub/linux/misc/ncpfs/>. + + If you don't know what you are doing, say N. + diff --git a/drivers/staging/ipx/Makefile b/drivers/staging/ipx/Makefile new file mode 100644 index 000000000000..440fafa9fd07 --- /dev/null +++ b/drivers/staging/ipx/Makefile @@ -0,0 +1,8 @@ +# +# Makefile for the Linux IPX layer. +# + +obj-$(CONFIG_IPX) += ipx.o + +ipx-y := af_ipx.o ipx_route.o ipx_proc.o pe2.o +ipx-$(CONFIG_SYSCTL) += sysctl_net_ipx.o diff --git a/drivers/staging/ipx/TODO b/drivers/staging/ipx/TODO new file mode 100644 index 000000000000..80db5d968264 --- /dev/null +++ b/drivers/staging/ipx/TODO @@ -0,0 +1,4 @@ +The ipx code will be removed soon from the kernel tree as it is old and +obsolete and broken. + +Don't worry about fixing up anything here, it's not needed. diff --git a/drivers/staging/ipx/af_ipx.c b/drivers/staging/ipx/af_ipx.c new file mode 100644 index 000000000000..d21a9d128d3e --- /dev/null +++ b/drivers/staging/ipx/af_ipx.c @@ -0,0 +1,2084 @@ +/* + * Implements an IPX socket layer. + * + * This code is derived from work by + * Ross Biro : Writing the original IP stack + * Fred Van Kempen : Tidying up the TCP/IP + * + * Many thanks go to Keith Baker, Institute For Industrial Information + * Technology Ltd, Swansea University for allowing me to work on this + * in my own time even though it was in some ways related to commercial + * work I am currently employed to do there. + * + * All the material in this file is subject to the Gnu license version 2. + * Neither Alan Cox nor the Swansea University Computer Society admit + * liability nor provide warranty for any of this software. This material + * is provided as is and at no charge. + * + * Portions Copyright (c) 2000-2003 Conectiva, Inc. <acme@conectiva.com.br> + * Neither Arnaldo Carvalho de Melo nor Conectiva, Inc. admit liability nor + * provide warranty for any of this software. This material is provided + * "AS-IS" and at no charge. + * + * Portions Copyright (c) 1995 Caldera, Inc. <greg@caldera.com> + * Neither Greg Page nor Caldera, Inc. admit liability nor provide + * warranty for any of this software. This material is provided + * "AS-IS" and at no charge. + * + * See net/ipx/ChangeLog. + */ + +#include <linux/capability.h> +#include <linux/errno.h> +#include <linux/if_arp.h> +#include <linux/if_ether.h> +#include <linux/init.h> +#include <linux/ipx.h> +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/module.h> +#include <linux/net.h> +#include <linux/netdevice.h> +#include <linux/uio.h> +#include <linux/slab.h> +#include <linux/skbuff.h> +#include <linux/socket.h> +#include <linux/sockios.h> +#include <linux/string.h> +#include <linux/types.h> +#include <linux/termios.h> + +#include <net/ipx.h> +#include <net/p8022.h> +#include <net/psnap.h> +#include <net/sock.h> +#include <net/datalink.h> +#include <net/tcp_states.h> +#include <net/net_namespace.h> + +#include <linux/uaccess.h> + +/* Configuration Variables */ +static unsigned char ipxcfg_max_hops = 16; +static char ipxcfg_auto_select_primary; +static char ipxcfg_auto_create_interfaces; +int sysctl_ipx_pprop_broadcasting = 1; + +/* Global Variables */ +static struct datalink_proto *p8022_datalink; +static struct datalink_proto *pEII_datalink; +static struct datalink_proto *p8023_datalink; +static struct datalink_proto *pSNAP_datalink; + +static const struct proto_ops ipx_dgram_ops; + +LIST_HEAD(ipx_interfaces); +DEFINE_SPINLOCK(ipx_interfaces_lock); + +struct ipx_interface *ipx_primary_net; +struct ipx_interface *ipx_internal_net; + +struct ipx_interface *ipx_interfaces_head(void) +{ + struct ipx_interface *rc = NULL; + + if (!list_empty(&ipx_interfaces)) + rc = list_entry(ipx_interfaces.next, + struct ipx_interface, node); + return rc; +} + +static void ipxcfg_set_auto_select(char val) +{ + ipxcfg_auto_select_primary = val; + if (val && !ipx_primary_net) + ipx_primary_net = ipx_interfaces_head(); +} + +static int ipxcfg_get_config_data(struct ipx_config_data __user *arg) +{ + struct ipx_config_data vals; + + vals.ipxcfg_auto_create_interfaces = ipxcfg_auto_create_interfaces; + vals.ipxcfg_auto_select_primary = ipxcfg_auto_select_primary; + + return copy_to_user(arg, &vals, sizeof(vals)) ? -EFAULT : 0; +} + +/* + * Note: Sockets may not be removed _during_ an interrupt or inet_bh + * handler using this technique. They can be added although we do not + * use this facility. + */ + +static void ipx_remove_socket(struct sock *sk) +{ + /* Determine interface with which socket is associated */ + struct ipx_interface *intrfc = ipx_sk(sk)->intrfc; + + if (!intrfc) + goto out; + + ipxitf_hold(intrfc); + spin_lock_bh(&intrfc->if_sklist_lock); + sk_del_node_init(sk); + spin_unlock_bh(&intrfc->if_sklist_lock); + ipxitf_put(intrfc); +out: + return; +} + +static void ipx_destroy_socket(struct sock *sk) +{ + ipx_remove_socket(sk); + skb_queue_purge(&sk->sk_receive_queue); + sk_refcnt_debug_dec(sk); +} + +/* + * The following code is used to support IPX Interfaces (IPXITF). An + * IPX interface is defined by a physical device and a frame type. + */ + +/* ipxitf_clear_primary_net has to be called with ipx_interfaces_lock held */ + +static void ipxitf_clear_primary_net(void) +{ + ipx_primary_net = NULL; + if (ipxcfg_auto_select_primary) + ipx_primary_net = ipx_interfaces_head(); +} + +static struct ipx_interface *__ipxitf_find_using_phys(struct net_device *dev, + __be16 datalink) +{ + struct ipx_interface *i; + + list_for_each_entry(i, &ipx_interfaces, node) + if (i->if_dev == dev && i->if_dlink_type == datalink) + goto out; + i = NULL; +out: + return i; +} + +static struct ipx_interface *ipxitf_find_using_phys(struct net_device *dev, + __be16 datalink) +{ + struct ipx_interface *i; + + spin_lock_bh(&ipx_interfaces_lock); + i = __ipxitf_find_using_phys(dev, datalink); + if (i) + ipxitf_hold(i); + spin_unlock_bh(&ipx_interfaces_lock); + return i; +} + +struct ipx_interface *ipxitf_find_using_net(__be32 net) +{ + struct ipx_interface *i; + + spin_lock_bh(&ipx_interfaces_lock); + if (net) { + list_for_each_entry(i, &ipx_interfaces, node) + if (i->if_netnum == net) + goto hold; + i = NULL; + goto unlock; + } + + i = ipx_primary_net; + if (i) +hold: + ipxitf_hold(i); +unlock: + spin_unlock_bh(&ipx_interfaces_lock); + return i; +} + +/* Sockets are bound to a particular IPX interface. */ +static void ipxitf_insert_socket(struct ipx_interface *intrfc, struct sock *sk) +{ + ipxitf_hold(intrfc); + spin_lock_bh(&intrfc->if_sklist_lock); + ipx_sk(sk)->intrfc = intrfc; + sk_add_node(sk, &intrfc->if_sklist); + spin_unlock_bh(&intrfc->if_sklist_lock); + ipxitf_put(intrfc); +} + +/* caller must hold intrfc->if_sklist_lock */ +static struct sock *__ipxitf_find_socket(struct ipx_interface *intrfc, + __be16 port) +{ + struct sock *s; + + sk_for_each(s, &intrfc->if_sklist) + if (ipx_sk(s)->port == port) + goto found; + s = NULL; +found: + return s; +} + +/* caller must hold a reference to intrfc */ +static struct sock *ipxitf_find_socket(struct ipx_interface *intrfc, + __be16 port) +{ + struct sock *s; + + spin_lock_bh(&intrfc->if_sklist_lock); + s = __ipxitf_find_socket(intrfc, port); + if (s) + sock_hold(s); + spin_unlock_bh(&intrfc->if_sklist_lock); + + return s; +} + +#ifdef CONFIG_IPX_INTERN +static struct sock *ipxitf_find_internal_socket(struct ipx_interface *intrfc, + unsigned char *ipx_node, + __be16 port) +{ + struct sock *s; + + ipxitf_hold(intrfc); + spin_lock_bh(&intrfc->if_sklist_lock); + + sk_for_each(s, &intrfc->if_sklist) { + struct ipx_sock *ipxs = ipx_sk(s); + + if (ipxs->port == port && + !memcmp(ipx_node, ipxs->node, IPX_NODE_LEN)) + goto found; + } + s = NULL; +found: + spin_unlock_bh(&intrfc->if_sklist_lock); + ipxitf_put(intrfc); + return s; +} +#endif + +static void __ipxitf_down(struct ipx_interface *intrfc) +{ + struct sock *s; + struct hlist_node *t; + + /* Delete all routes associated with this interface */ + ipxrtr_del_routes(intrfc); + + spin_lock_bh(&intrfc->if_sklist_lock); + /* error sockets */ + sk_for_each_safe(s, t, &intrfc->if_sklist) { + struct ipx_sock *ipxs = ipx_sk(s); + + s->sk_err = ENOLINK; + s->sk_error_report(s); + ipxs->intrfc = NULL; + ipxs->port = 0; + sock_set_flag(s, SOCK_ZAPPED); /* Indicates it is no longer bound */ + sk_del_node_init(s); + } + INIT_HLIST_HEAD(&intrfc->if_sklist); + spin_unlock_bh(&intrfc->if_sklist_lock); + + /* remove this interface from list */ + list_del(&intrfc->node); + + /* remove this interface from *special* networks */ + if (intrfc == ipx_primary_net) + ipxitf_clear_primary_net(); + if (intrfc == ipx_internal_net) + ipx_internal_net = NULL; + + if (intrfc->if_dev) + dev_put(intrfc->if_dev); + kfree(intrfc); +} + +void ipxitf_down(struct ipx_interface *intrfc) +{ + spin_lock_bh(&ipx_interfaces_lock); + __ipxitf_down(intrfc); + spin_unlock_bh(&ipx_interfaces_lock); +} + +static void __ipxitf_put(struct ipx_interface *intrfc) +{ + if (refcount_dec_and_test(&intrfc->refcnt)) + __ipxitf_down(intrfc); +} + +static int ipxitf_device_event(struct notifier_block *notifier, + unsigned long event, void *ptr) +{ + struct net_device *dev = netdev_notifier_info_to_dev(ptr); + struct ipx_interface *i, *tmp; + + if (!net_eq(dev_net(dev), &init_net)) + return NOTIFY_DONE; + + if (event != NETDEV_DOWN && event != NETDEV_UP) + goto out; + + spin_lock_bh(&ipx_interfaces_lock); + list_for_each_entry_safe(i, tmp, &ipx_interfaces, node) + if (i->if_dev == dev) { + if (event == NETDEV_UP) + ipxitf_hold(i); + else + __ipxitf_put(i); + } + spin_unlock_bh(&ipx_interfaces_lock); +out: + return NOTIFY_DONE; +} + + +static __exit void ipxitf_cleanup(void) +{ + struct ipx_interface *i, *tmp; + + spin_lock_bh(&ipx_interfaces_lock); + list_for_each_entry_safe(i, tmp, &ipx_interfaces, node) + __ipxitf_put(i); + spin_unlock_bh(&ipx_interfaces_lock); +} + +static void ipxitf_def_skb_handler(struct sock *sock, struct sk_buff *skb) +{ + if (sock_queue_rcv_skb(sock, skb) < 0) + kfree_skb(skb); +} + +/* + * On input skb->sk is NULL. Nobody is charged for the memory. + */ + +/* caller must hold a reference to intrfc */ + +#ifdef CONFIG_IPX_INTERN +static int ipxitf_demux_socket(struct ipx_interface *intrfc, + struct sk_buff *skb, int copy) +{ + struct ipxhdr *ipx = ipx_hdr(skb); + int is_broadcast = !memcmp(ipx->ipx_dest.node, ipx_broadcast_node, + IPX_NODE_LEN); + struct sock *s; + int rc; + + spin_lock_bh(&intrfc->if_sklist_lock); + + sk_for_each(s, &intrfc->if_sklist) { + struct ipx_sock *ipxs = ipx_sk(s); + + if (ipxs->port == ipx->ipx_dest.sock && + (is_broadcast || !memcmp(ipx->ipx_dest.node, + ipxs->node, IPX_NODE_LEN))) { + /* We found a socket to which to send */ + struct sk_buff *skb1; + + if (copy) { + skb1 = skb_clone(skb, GFP_ATOMIC); + rc = -ENOMEM; + if (!skb1) + goto out; + } else { + skb1 = skb; + copy = 1; /* skb may only be used once */ + } + ipxitf_def_skb_handler(s, skb1); + + /* On an external interface, one socket can listen */ + if (intrfc != ipx_internal_net) + break; + } + } + + /* skb was solely for us, and we did not make a copy, so free it. */ + if (!copy) + kfree_skb(skb); + + rc = 0; +out: + spin_unlock_bh(&intrfc->if_sklist_lock); + return rc; +} +#else +static struct sock *ncp_connection_hack(struct ipx_interface *intrfc, + struct ipxhdr *ipx) +{ + /* The packet's target is a NCP connection handler. We want to hand it + * to the correct socket directly within the kernel, so that the + * mars_nwe packet distribution process does not have to do it. Here we + * only care about NCP and BURST packets. + * + * You might call this a hack, but believe me, you do not want a + * complete NCP layer in the kernel, and this is VERY fast as well. */ + struct sock *sk = NULL; + int connection = 0; + u8 *ncphdr = (u8 *)(ipx + 1); + + if (*ncphdr == 0x22 && *(ncphdr + 1) == 0x22) /* NCP request */ + connection = (((int) *(ncphdr + 5)) << 8) | (int) *(ncphdr + 3); + else if (*ncphdr == 0x77 && *(ncphdr + 1) == 0x77) /* BURST packet */ + connection = (((int) *(ncphdr + 9)) << 8) | (int) *(ncphdr + 8); + + if (connection) { + /* Now we have to look for a special NCP connection handling + * socket. Only these sockets have ipx_ncp_conn != 0, set by + * SIOCIPXNCPCONN. */ + spin_lock_bh(&intrfc->if_sklist_lock); + sk_for_each(sk, &intrfc->if_sklist) + if (ipx_sk(sk)->ipx_ncp_conn == connection) { + sock_hold(sk); + goto found; + } + sk = NULL; + found: + spin_unlock_bh(&intrfc->if_sklist_lock); + } + return sk; +} + +static int ipxitf_demux_socket(struct ipx_interface *intrfc, + struct sk_buff *skb, int copy) +{ + struct ipxhdr *ipx = ipx_hdr(skb); + struct sock *sock1 = NULL, *sock2 = NULL; + struct sk_buff *skb1 = NULL, *skb2 = NULL; + int rc; + + if (intrfc == ipx_primary_net && ntohs(ipx->ipx_dest.sock) == 0x451) + sock1 = ncp_connection_hack(intrfc, ipx); + if (!sock1) + /* No special socket found, forward the packet the normal way */ + sock1 = ipxitf_find_socket(intrfc, ipx->ipx_dest.sock); + + /* + * We need to check if there is a primary net and if + * this is addressed to one of the *SPECIAL* sockets because + * these need to be propagated to the primary net. + * The *SPECIAL* socket list contains: 0x452(SAP), 0x453(RIP) and + * 0x456(Diagnostic). + */ + + if (ipx_primary_net && intrfc != ipx_primary_net) { + const int dsock = ntohs(ipx->ipx_dest.sock); + + if (dsock == 0x452 || dsock == 0x453 || dsock == 0x456) + /* The appropriate thing to do here is to dup the + * packet and route to the primary net interface via + * ipxitf_send; however, we'll cheat and just demux it + * here. */ + sock2 = ipxitf_find_socket(ipx_primary_net, + ipx->ipx_dest.sock); + } + + /* + * If there is nothing to do return. The kfree will cancel any charging. + */ + rc = 0; + if (!sock1 && !sock2) { + if (!copy) + kfree_skb(skb); + goto out; + } + + /* + * This next segment of code is a little awkward, but it sets it up + * so that the appropriate number of copies of the SKB are made and + * that skb1 and skb2 point to it (them) so that it (they) can be + * demuxed to sock1 and/or sock2. If we are unable to make enough + * copies, we do as much as is possible. + */ + + if (copy) + skb1 = skb_clone(skb, GFP_ATOMIC); + else + skb1 = skb; + + rc = -ENOMEM; + if (!skb1) + goto out_put; + + /* Do we need 2 SKBs? */ + if (sock1 && sock2) + skb2 = skb_clone(skb1, GFP_ATOMIC); + else + skb2 = skb1; + + if (sock1) + ipxitf_def_skb_handler(sock1, skb1); + + if (!skb2) + goto out_put; + + if (sock2) + ipxitf_def_skb_handler(sock2, skb2); + + rc = 0; +out_put: + if (sock1) + sock_put(sock1); + if (sock2) + sock_put(sock2); +out: + return rc; +} +#endif /* CONFIG_IPX_INTERN */ + +static struct sk_buff *ipxitf_adjust_skbuff(struct ipx_interface *intrfc, + struct sk_buff *skb) +{ + struct sk_buff *skb2; + int in_offset = (unsigned char *)ipx_hdr(skb) - skb->head; + int out_offset = intrfc->if_ipx_offset; + int len; + + /* Hopefully, most cases */ + if (in_offset >= out_offset) + return skb; + + /* Need new SKB */ + len = skb->len + out_offset; + skb2 = alloc_skb(len, GFP_ATOMIC); + if (skb2) { + skb_reserve(skb2, out_offset); + skb_reset_network_header(skb2); + skb_reset_transport_header(skb2); + skb_put(skb2, skb->len); + memcpy(ipx_hdr(skb2), ipx_hdr(skb), skb->len); + memcpy(skb2->cb, skb->cb, sizeof(skb->cb)); + } + kfree_skb(skb); + return skb2; +} + +/* caller must hold a reference to intrfc and the skb has to be unshared */ +int ipxitf_send(struct ipx_interface *intrfc, struct sk_buff *skb, char *node) +{ + struct ipxhdr *ipx = ipx_hdr(skb); + struct net_device *dev = intrfc->if_dev; + struct datalink_proto *dl = intrfc->if_dlink; + char dest_node[IPX_NODE_LEN]; + int send_to_wire = 1; + int addr_len; + + ipx->ipx_tctrl = IPX_SKB_CB(skb)->ipx_tctrl; + ipx->ipx_dest.net = IPX_SKB_CB(skb)->ipx_dest_net; + ipx->ipx_source.net = IPX_SKB_CB(skb)->ipx_source_net; + + /* see if we need to include the netnum in the route list */ + if (IPX_SKB_CB(skb)->last_hop.index >= 0) { + __be32 *last_hop = (__be32 *)(((u8 *) skb->data) + + sizeof(struct ipxhdr) + + IPX_SKB_CB(skb)->last_hop.index * + sizeof(__be32)); + *last_hop = IPX_SKB_CB(skb)->last_hop.netnum; + IPX_SKB_CB(skb)->last_hop.index = -1; + } + + /* + * We need to know how many skbuffs it will take to send out this + * packet to avoid unnecessary copies. + */ + + if (!dl || !dev || dev->flags & IFF_LOOPBACK) + send_to_wire = 0; /* No non looped */ + + /* + * See if this should be demuxed to sockets on this interface + * + * We want to ensure the original was eaten or that we only use + * up clones. + */ + + if (ipx->ipx_dest.net == intrfc->if_netnum) { + /* + * To our own node, loop and free the original. + * The internal net will receive on all node address. + */ + if (intrfc == ipx_internal_net || + !memcmp(intrfc->if_node, node, IPX_NODE_LEN)) { + /* Don't charge sender */ + skb_orphan(skb); + + /* Will charge receiver */ + return ipxitf_demux_socket(intrfc, skb, 0); + } + + /* Broadcast, loop and possibly keep to send on. */ + if (!memcmp(ipx_broadcast_node, node, IPX_NODE_LEN)) { + if (!send_to_wire) + skb_orphan(skb); + ipxitf_demux_socket(intrfc, skb, send_to_wire); + if (!send_to_wire) + goto out; + } + } + + /* + * If the originating net is not equal to our net; this is routed + * We are still charging the sender. Which is right - the driver + * free will handle this fairly. + */ + if (ipx->ipx_source.net != intrfc->if_netnum) { + /* + * Unshare the buffer before modifying the count in + * case it's a flood or tcpdump + */ + skb = skb_unshare(skb, GFP_ATOMIC); + if (!skb) + goto out; + if (++ipx->ipx_tctrl > ipxcfg_max_hops) + send_to_wire = 0; + } + + if (!send_to_wire) { + kfree_skb(skb); + goto out; + } + + /* Determine the appropriate hardware address */ + addr_len = dev->addr_len; + if (!memcmp(ipx_broadcast_node, node, IPX_NODE_LEN)) + memcpy(dest_node, dev->broadcast, addr_len); + else + memcpy(dest_node, &(node[IPX_NODE_LEN-addr_len]), addr_len); + + /* Make any compensation for differing physical/data link size */ + skb = ipxitf_adjust_skbuff(intrfc, skb); + if (!skb) + goto out; + + /* set up data link and physical headers */ + skb->dev = dev; + skb->protocol = htons(ETH_P_IPX); + + /* Send it out */ + dl->request(dl, skb, dest_node); +out: + return 0; +} + +static int ipxitf_add_local_route(struct ipx_interface *intrfc) +{ + return ipxrtr_add_route(intrfc->if_netnum, intrfc, NULL); +} + +static void ipxitf_discover_netnum(struct ipx_interface *intrfc, + struct sk_buff *skb); +static int ipxitf_pprop(struct ipx_interface *intrfc, struct sk_buff *skb); + +static int ipxitf_rcv(struct ipx_interface *intrfc, struct sk_buff *skb) +{ + struct ipxhdr *ipx = ipx_hdr(skb); + int rc = 0; + + ipxitf_hold(intrfc); + + /* See if we should update our network number */ + if (!intrfc->if_netnum) /* net number of intrfc not known yet */ + ipxitf_discover_netnum(intrfc, skb); + + IPX_SKB_CB(skb)->last_hop.index = -1; + if (ipx->ipx_type == IPX_TYPE_PPROP) { + rc = ipxitf_pprop(intrfc, skb); + if (rc) + goto out_free_skb; + } + + /* local processing follows */ + if (!IPX_SKB_CB(skb)->ipx_dest_net) + IPX_SKB_CB(skb)->ipx_dest_net = intrfc->if_netnum; + if (!IPX_SKB_CB(skb)->ipx_source_net) + IPX_SKB_CB(skb)->ipx_source_net = intrfc->if_netnum; + + /* it doesn't make sense to route a pprop packet, there's no meaning + * in the ipx_dest_net for such packets */ + if (ipx->ipx_type != IPX_TYPE_PPROP && + intrfc->if_netnum != IPX_SKB_CB(skb)->ipx_dest_net) { + /* We only route point-to-point packets. */ + if (skb->pkt_type == PACKET_HOST) { + skb = skb_unshare(skb, GFP_ATOMIC); + if (skb) + rc = ipxrtr_route_skb(skb); + goto out_intrfc; + } + + goto out_free_skb; + } + + /* see if we should keep it */ + if (!memcmp(ipx_broadcast_node, ipx->ipx_dest.node, IPX_NODE_LEN) || + !memcmp(intrfc->if_node, ipx->ipx_dest.node, IPX_NODE_LEN)) { + rc = ipxitf_demux_socket(intrfc, skb, 0); + goto out_intrfc; + } + + /* we couldn't pawn it off so unload it */ +out_free_skb: + kfree_skb(skb); +out_intrfc: + ipxitf_put(intrfc); + return rc; +} + +static void ipxitf_discover_netnum(struct ipx_interface *intrfc, + struct sk_buff *skb) +{ + const struct ipx_cb *cb = IPX_SKB_CB(skb); + + /* see if this is an intra packet: source_net == dest_net */ + if (cb->ipx_source_net == cb->ipx_dest_net && cb->ipx_source_net) { + struct ipx_interface *i = + ipxitf_find_using_net(cb->ipx_source_net); + /* NB: NetWare servers lie about their hop count so we + * dropped the test based on it. This is the best way + * to determine this is a 0 hop count packet. */ + if (!i) { + intrfc->if_netnum = cb->ipx_source_net; + ipxitf_add_local_route(intrfc); + } else { + printk(KERN_WARNING "IPX: Network number collision " + "%lx\n %s %s and %s %s\n", + (unsigned long) ntohl(cb->ipx_source_net), + ipx_device_name(i), + ipx_frame_name(i->if_dlink_type), + ipx_device_name(intrfc), + ipx_frame_name(intrfc->if_dlink_type)); + ipxitf_put(i); + } + } +} + +/** + * ipxitf_pprop - Process packet propagation IPX packet type 0x14, used for + * NetBIOS broadcasts + * @intrfc: IPX interface receiving this packet + * @skb: Received packet + * + * Checks if packet is valid: if its more than %IPX_MAX_PPROP_HOPS hops or if it + * is smaller than a IPX header + the room for %IPX_MAX_PPROP_HOPS hops we drop + * it, not even processing it locally, if it has exact %IPX_MAX_PPROP_HOPS we + * don't broadcast it, but process it locally. See chapter 5 of Novell's "IPX + * RIP and SAP Router Specification", Part Number 107-000029-001. + * + * If it is valid, check if we have pprop broadcasting enabled by the user, + * if not, just return zero for local processing. + * + * If it is enabled check the packet and don't broadcast it if we have already + * seen this packet. + * + * Broadcast: send it to the interfaces that aren't on the packet visited nets + * array, just after the IPX header. + * + * Returns -EINVAL for invalid packets, so that the calling function drops + * the packet without local processing. 0 if packet is to be locally processed. + */ +static int ipxitf_pprop(struct ipx_interface *intrfc, struct sk_buff *skb) +{ + struct ipxhdr *ipx = ipx_hdr(skb); + int i, rc = -EINVAL; + struct ipx_interface *ifcs; + char *c; + __be32 *l; + + /* Illegal packet - too many hops or too short */ + /* We decide to throw it away: no broadcasting, no local processing. + * NetBIOS unaware implementations route them as normal packets - + * tctrl <= 15, any data payload... */ + if (IPX_SKB_CB(skb)->ipx_tctrl > IPX_MAX_PPROP_HOPS || + ntohs(ipx->ipx_pktsize) < sizeof(struct ipxhdr) + + IPX_MAX_PPROP_HOPS * sizeof(u32)) + goto out; + /* are we broadcasting this damn thing? */ + rc = 0; + if (!sysctl_ipx_pprop_broadcasting) + goto out; + /* We do broadcast packet on the IPX_MAX_PPROP_HOPS hop, but we + * process it locally. All previous hops broadcasted it, and process it + * locally. */ + if (IPX_SKB_CB(skb)->ipx_tctrl == IPX_MAX_PPROP_HOPS) + goto out; + + c = ((u8 *) ipx) + sizeof(struct ipxhdr); + l = (__be32 *) c; + + /* Don't broadcast packet if already seen this net */ + for (i = 0; i < IPX_SKB_CB(skb)->ipx_tctrl; i++) + if (*l++ == intrfc->if_netnum) + goto out; + + /* < IPX_MAX_PPROP_HOPS hops && input interface not in list. Save the + * position where we will insert recvd netnum into list, later on, + * in ipxitf_send */ + IPX_SKB_CB(skb)->last_hop.index = i; + IPX_SKB_CB(skb)->last_hop.netnum = intrfc->if_netnum; + /* xmit on all other interfaces... */ + spin_lock_bh(&ipx_interfaces_lock); + list_for_each_entry(ifcs, &ipx_interfaces, node) { + /* Except unconfigured interfaces */ + if (!ifcs->if_netnum) + continue; + + /* That aren't in the list */ + if (ifcs == intrfc) + continue; + l = (__be32 *) c; + /* don't consider the last entry in the packet list, + * it is our netnum, and it is not there yet */ + for (i = 0; i < IPX_SKB_CB(skb)->ipx_tctrl; i++) + if (ifcs->if_netnum == *l++) + break; + if (i == IPX_SKB_CB(skb)->ipx_tctrl) { + struct sk_buff *s = skb_copy(skb, GFP_ATOMIC); + + if (s) { + IPX_SKB_CB(s)->ipx_dest_net = ifcs->if_netnum; + ipxrtr_route_skb(s); + } + } + } + spin_unlock_bh(&ipx_interfaces_lock); +out: + return rc; +} + +static void ipxitf_insert(struct ipx_interface *intrfc) +{ + spin_lock_bh(&ipx_interfaces_lock); + list_add_tail(&intrfc->node, &ipx_interfaces); + spin_unlock_bh(&ipx_interfaces_lock); + + if (ipxcfg_auto_select_primary && !ipx_primary_net) + ipx_primary_net = intrfc; +} + +static struct ipx_interface *ipxitf_alloc(struct net_device *dev, __be32 netnum, + __be16 dlink_type, + struct datalink_proto *dlink, + unsigned char internal, + int ipx_offset) +{ + struct ipx_interface *intrfc = kmalloc(sizeof(*intrfc), GFP_ATOMIC); + + if (intrfc) { + intrfc->if_dev = dev; + intrfc->if_netnum = netnum; + intrfc->if_dlink_type = dlink_type; + intrfc->if_dlink = dlink; + intrfc->if_internal = internal; + intrfc->if_ipx_offset = ipx_offset; + intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET; + INIT_HLIST_HEAD(&intrfc->if_sklist); + refcount_set(&intrfc->refcnt, 1); + spin_lock_init(&intrfc->if_sklist_lock); + } + + return intrfc; +} + +static int ipxitf_create_internal(struct ipx_interface_definition *idef) +{ + struct ipx_interface *intrfc; + int rc = -EEXIST; + + /* Only one primary network allowed */ + if (ipx_primary_net) + goto out; + + /* Must have a valid network number */ + rc = -EADDRNOTAVAIL; + if (!idef->ipx_network) + goto out; + intrfc = ipxitf_find_using_net(idef->ipx_network); + rc = -EADDRINUSE; + if (intrfc) { + ipxitf_put(intrfc); + goto out; + } + intrfc = ipxitf_alloc(NULL, idef->ipx_network, 0, NULL, 1, 0); + rc = -EAGAIN; + if (!intrfc) + goto out; + memcpy((char *)&(intrfc->if_node), idef->ipx_node, IPX_NODE_LEN); + ipx_internal_net = ipx_primary_net = intrfc; + ipxitf_hold(intrfc); + ipxitf_insert(intrfc); + + rc = ipxitf_add_local_route(intrfc); + ipxitf_put(intrfc); +out: + return rc; +} + +static __be16 ipx_map_frame_type(unsigned char type) +{ + __be16 rc = 0; + + switch (type) { + case IPX_FRAME_ETHERII: rc = htons(ETH_P_IPX); break; + case IPX_FRAME_8022: rc = htons(ETH_P_802_2); break; + case IPX_FRAME_SNAP: rc = htons(ETH_P_SNAP); break; + case IPX_FRAME_8023: rc = htons(ETH_P_802_3); break; + } + + return rc; +} + +static int ipxitf_create(struct ipx_interface_definition *idef) +{ + struct net_device *dev; + __be16 dlink_type = 0; + struct datalink_proto *datalink = NULL; + struct ipx_interface *intrfc; + int rc; + + if (idef->ipx_special == IPX_INTERNAL) { + rc = ipxitf_create_internal(idef); + goto out; + } + + rc = -EEXIST; + if (idef->ipx_special == IPX_PRIMARY && ipx_primary_net) + goto out; + + intrfc = ipxitf_find_using_net(idef->ipx_network); + rc = -EADDRINUSE; + if (idef->ipx_network && intrfc) { + ipxitf_put(intrfc); + goto out; + } + + if (intrfc) + ipxitf_put(intrfc); + + dev = dev_get_by_name(&init_net, idef->ipx_device); + rc = -ENODEV; + if (!dev) + goto out; + + switch (idef->ipx_dlink_type) { + case IPX_FRAME_8022: + dlink_type = htons(ETH_P_802_2); + datalink = p8022_datalink; + break; + case IPX_FRAME_ETHERII: + if (dev->type != ARPHRD_IEEE802) { + dlink_type = htons(ETH_P_IPX); + datalink = pEII_datalink; + break; + } + /* fall through */ + case IPX_FRAME_SNAP: + dlink_type = htons(ETH_P_SNAP); + datalink = pSNAP_datalink; + break; + case IPX_FRAME_8023: + dlink_type = htons(ETH_P_802_3); + datalink = p8023_datalink; + break; + case IPX_FRAME_NONE: + default: + rc = -EPROTONOSUPPORT; + goto out_dev; + } + + rc = -ENETDOWN; + if (!(dev->flags & IFF_UP)) + goto out_dev; + + /* Check addresses are suitable */ + rc = -EINVAL; + if (dev->addr_len > IPX_NODE_LEN) + goto out_dev; + + intrfc = ipxitf_find_using_phys(dev, dlink_type); + if (!intrfc) { + /* Ok now create */ + intrfc = ipxitf_alloc(dev, idef->ipx_network, dlink_type, + datalink, 0, dev->hard_header_len + + datalink->header_length); + rc = -EAGAIN; + if (!intrfc) + goto out_dev; + /* Setup primary if necessary */ + if (idef->ipx_special == IPX_PRIMARY) + ipx_primary_net = intrfc; + if (!memcmp(idef->ipx_node, "\000\000\000\000\000\000", + IPX_NODE_LEN)) { + memset(intrfc->if_node, 0, IPX_NODE_LEN); + memcpy(intrfc->if_node + IPX_NODE_LEN - dev->addr_len, + dev->dev_addr, dev->addr_len); + } else + memcpy(intrfc->if_node, idef->ipx_node, IPX_NODE_LEN); + ipxitf_hold(intrfc); + ipxitf_insert(intrfc); + } + + + /* If the network number is known, add a route */ + rc = 0; + if (!intrfc->if_netnum) + goto out_intrfc; + + rc = ipxitf_add_local_route(intrfc); +out_intrfc: + ipxitf_put(intrfc); + goto out; +out_dev: + dev_put(dev); +out: + return rc; +} + +static int ipxitf_delete(struct ipx_interface_definition *idef) +{ + struct net_device *dev = NULL; + __be16 dlink_type = 0; + struct ipx_interface *intrfc; + int rc = 0; + + spin_lock_bh(&ipx_interfaces_lock); + if (idef->ipx_special == IPX_INTERNAL) { + if (ipx_internal_net) { + __ipxitf_put(ipx_internal_net); + goto out; + } + rc = -ENOENT; + goto out; + } + + dlink_type = ipx_map_frame_type(idef->ipx_dlink_type); + rc = -EPROTONOSUPPORT; + if (!dlink_type) + goto out; + + dev = __dev_get_by_name(&init_net, idef->ipx_device); + rc = -ENODEV; + if (!dev) + goto out; + + intrfc = __ipxitf_find_using_phys(dev, dlink_type); + rc = -EINVAL; + if (!intrfc) + goto out; + __ipxitf_put(intrfc); + + rc = 0; +out: + spin_unlock_bh(&ipx_interfaces_lock); + return rc; +} + +static struct ipx_interface *ipxitf_auto_create(struct net_device *dev, + __be16 dlink_type) +{ + struct ipx_interface *intrfc = NULL; + struct datalink_proto *datalink; + + if (!dev) + goto out; + + /* Check addresses are suitable */ + if (dev->addr_len > IPX_NODE_LEN) + goto out; + + switch (ntohs(dlink_type)) { + case ETH_P_IPX: datalink = pEII_datalink; break; + case ETH_P_802_2: datalink = p8022_datalink; break; + case ETH_P_SNAP: datalink = pSNAP_datalink; break; + case ETH_P_802_3: datalink = p8023_datalink; break; + default: goto out; + } + + intrfc = ipxitf_alloc(dev, 0, dlink_type, datalink, 0, + dev->hard_header_len + datalink->header_length); + + if (intrfc) { + memset(intrfc->if_node, 0, IPX_NODE_LEN); + memcpy((char *)&(intrfc->if_node[IPX_NODE_LEN-dev->addr_len]), + dev->dev_addr, dev->addr_len); + spin_lock_init(&intrfc->if_sklist_lock); + refcount_set(&intrfc->refcnt, 1); + ipxitf_insert(intrfc); + dev_hold(dev); + } + +out: + return intrfc; +} + +static int ipxitf_ioctl(unsigned int cmd, void __user *arg) +{ + int rc = -EINVAL; + struct ifreq ifr; + int val; + + switch (cmd) { + case SIOCSIFADDR: { + struct sockaddr_ipx *sipx; + struct ipx_interface_definition f; + + rc = -EFAULT; + if (copy_from_user(&ifr, arg, sizeof(ifr))) + break; + sipx = (struct sockaddr_ipx *)&ifr.ifr_addr; + rc = -EINVAL; + if (sipx->sipx_family != AF_IPX) + break; + f.ipx_network = sipx->sipx_network; + memcpy(f.ipx_device, ifr.ifr_name, + sizeof(f.ipx_device)); + memcpy(f.ipx_node, sipx->sipx_node, IPX_NODE_LEN); + f.ipx_dlink_type = sipx->sipx_type; + f.ipx_special = sipx->sipx_special; + + if (sipx->sipx_action == IPX_DLTITF) + rc = ipxitf_delete(&f); + else + rc = ipxitf_create(&f); + break; + } + case SIOCGIFADDR: { + struct sockaddr_ipx *sipx; + struct ipx_interface *ipxif; + struct net_device *dev; + + rc = -EFAULT; + if (copy_from_user(&ifr, arg, sizeof(ifr))) + break; + sipx = (struct sockaddr_ipx *)&ifr.ifr_addr; + dev = __dev_get_by_name(&init_net, ifr.ifr_name); + rc = -ENODEV; + if (!dev) + break; + ipxif = ipxitf_find_using_phys(dev, + ipx_map_frame_type(sipx->sipx_type)); + rc = -EADDRNOTAVAIL; + if (!ipxif) + break; + + sipx->sipx_family = AF_IPX; + sipx->sipx_network = ipxif->if_netnum; + memcpy(sipx->sipx_node, ipxif->if_node, + sizeof(sipx->sipx_node)); + rc = 0; + if (copy_to_user(arg, &ifr, sizeof(ifr))) + rc = -EFAULT; + ipxitf_put(ipxif); + break; + } + case SIOCAIPXITFCRT: + rc = -EFAULT; + if (get_user(val, (unsigned char __user *) arg)) + break; + rc = 0; + ipxcfg_auto_create_interfaces = val; + break; + case SIOCAIPXPRISLT: + rc = -EFAULT; + if (get_user(val, (unsigned char __user *) arg)) + break; + rc = 0; + ipxcfg_set_auto_select(val); + break; + } + + return rc; +} + +/* + * Checksum routine for IPX + */ + +/* Note: We assume ipx_tctrl==0 and htons(length)==ipx_pktsize */ +/* This functions should *not* mess with packet contents */ + +__be16 ipx_cksum(struct ipxhdr *packet, int length) +{ + /* + * NOTE: sum is a net byte order quantity, which optimizes the + * loop. This only works on big and little endian machines. (I + * don't know of a machine that isn't.) + */ + /* handle the first 3 words separately; checksum should be skipped + * and ipx_tctrl masked out */ + __u16 *p = (__u16 *)packet; + __u32 sum = p[1] + (p[2] & (__force u16)htons(0x00ff)); + __u32 i = (length >> 1) - 3; /* Number of remaining complete words */ + + /* Loop through them */ + p += 3; + while (i--) + sum += *p++; + + /* Add on the last part word if it exists */ + if (packet->ipx_pktsize & htons(1)) + sum += (__force u16)htons(0xff00) & *p; + + /* Do final fixup */ + sum = (sum & 0xffff) + (sum >> 16); + + /* It's a pity there's no concept of carry in C */ + if (sum >= 0x10000) + sum++; + + /* + * Leave 0 alone; we don't want 0xffff here. Note that we can't get + * here with 0x10000, so this check is the same as ((__u16)sum) + */ + if (sum) + sum = ~sum; + + return (__force __be16)sum; +} + +const char *ipx_frame_name(__be16 frame) +{ + char* rc = "None"; + + switch (ntohs(frame)) { + case ETH_P_IPX: rc = "EtherII"; break; + case ETH_P_802_2: rc = "802.2"; break; + case ETH_P_SNAP: rc = "SNAP"; break; + case ETH_P_802_3: rc = "802.3"; break; + } + + return rc; +} + +const char *ipx_device_name(struct ipx_interface *intrfc) +{ + return intrfc->if_internal ? "Internal" : + intrfc->if_dev ? intrfc->if_dev->name : "Unknown"; +} + +/* Handling for system calls applied via the various interfaces to an IPX + * socket object. */ + +static int ipx_setsockopt(struct socket *sock, int level, int optname, + char __user *optval, unsigned int optlen) +{ + struct sock *sk = sock->sk; + int opt; + int rc = -EINVAL; + + lock_sock(sk); + if (optlen != sizeof(int)) + goto out; + + rc = -EFAULT; + if (get_user(opt, (unsigned int __user *)optval)) + goto out; + + rc = -ENOPROTOOPT; + if (!(level == SOL_IPX && optname == IPX_TYPE)) + goto out; + + ipx_sk(sk)->type = opt; + rc = 0; +out: + release_sock(sk); + return rc; +} + +static int ipx_getsockopt(struct socket *sock, int level, int optname, + char __user *optval, int __user *optlen) +{ + struct sock *sk = sock->sk; + int val = 0; + int len; + int rc = -ENOPROTOOPT; + + lock_sock(sk); + if (!(level == SOL_IPX && optname == IPX_TYPE)) + goto out; + + val = ipx_sk(sk)->type; + + rc = -EFAULT; + if (get_user(len, optlen)) + goto out; + + len = min_t(unsigned int, len, sizeof(int)); + rc = -EINVAL; + if(len < 0) + goto out; + + rc = -EFAULT; + if (put_user(len, optlen) || copy_to_user(optval, &val, len)) + goto out; + + rc = 0; +out: + release_sock(sk); + return rc; +} + +static struct proto ipx_proto = { + .name = "IPX", + .owner = THIS_MODULE, + .obj_size = sizeof(struct ipx_sock), +}; + +static int ipx_create(struct net *net, struct socket *sock, int protocol, + int kern) +{ + int rc = -ESOCKTNOSUPPORT; + struct sock *sk; + + if (!net_eq(net, &init_net)) + return -EAFNOSUPPORT; + + /* + * SPX support is not anymore in the kernel sources. If you want to + * ressurrect it, completing it and making it understand shared skbs, + * be fully multithreaded, etc, grab the sources in an early 2.5 kernel + * tree. + */ + if (sock->type != SOCK_DGRAM) + goto out; + + rc = -ENOMEM; + sk = sk_alloc(net, PF_IPX, GFP_KERNEL, &ipx_proto, kern); + if (!sk) + goto out; + + sk_refcnt_debug_inc(sk); + sock_init_data(sock, sk); + sk->sk_no_check_tx = 1; /* Checksum off by default */ + sock->ops = &ipx_dgram_ops; + rc = 0; +out: + return rc; +} + +static int ipx_release(struct socket *sock) +{ + struct sock *sk = sock->sk; + + if (!sk) + goto out; + + lock_sock(sk); + sk->sk_shutdown = SHUTDOWN_MASK; + if (!sock_flag(sk, SOCK_DEAD)) + sk->sk_state_change(sk); + + sock_set_flag(sk, SOCK_DEAD); + sock->sk = NULL; + sk_refcnt_debug_release(sk); + ipx_destroy_socket(sk); + release_sock(sk); + sock_put(sk); +out: + return 0; +} + +/* caller must hold a reference to intrfc */ + +static __be16 ipx_first_free_socketnum(struct ipx_interface *intrfc) +{ + unsigned short socketNum = intrfc->if_sknum; + + spin_lock_bh(&intrfc->if_sklist_lock); + + if (socketNum < IPX_MIN_EPHEMERAL_SOCKET) + socketNum = IPX_MIN_EPHEMERAL_SOCKET; + + while (__ipxitf_find_socket(intrfc, htons(socketNum))) + if (socketNum > IPX_MAX_EPHEMERAL_SOCKET) + socketNum = IPX_MIN_EPHEMERAL_SOCKET; + else + socketNum++; + + spin_unlock_bh(&intrfc->if_sklist_lock); + intrfc->if_sknum = socketNum; + + return htons(socketNum); +} + +static int __ipx_bind(struct socket *sock, + struct sockaddr *uaddr, int addr_len) +{ + struct sock *sk = sock->sk; + struct ipx_sock *ipxs = ipx_sk(sk); + struct ipx_interface *intrfc; + struct sockaddr_ipx *addr = (struct sockaddr_ipx *)uaddr; + int rc = -EINVAL; + + if (!sock_flag(sk, SOCK_ZAPPED) || addr_len != sizeof(struct sockaddr_ipx)) + goto out; + + intrfc = ipxitf_find_using_net(addr->sipx_network); + rc = -EADDRNOTAVAIL; + if (!intrfc) + goto out; + + if (!addr->sipx_port) { + addr->sipx_port = ipx_first_free_socketnum(intrfc); + rc = -EINVAL; + if (!addr->sipx_port) + goto out_put; + } + + /* protect IPX system stuff like routing/sap */ + rc = -EACCES; + if (ntohs(addr->sipx_port) < IPX_MIN_EPHEMERAL_SOCKET && + !capable(CAP_NET_ADMIN)) + goto out_put; + + ipxs->port = addr->sipx_port; + +#ifdef CONFIG_IPX_INTERN + if (intrfc == ipx_internal_net) { + /* The source address is to be set explicitly if the + * socket is to be bound on the internal network. If a + * node number 0 was specified, the default is used. + */ + + rc = -EINVAL; + if (!memcmp(addr->sipx_node, ipx_broadcast_node, IPX_NODE_LEN)) + goto out_put; + if (!memcmp(addr->sipx_node, ipx_this_node, IPX_NODE_LEN)) + memcpy(ipxs->node, intrfc->if_node, IPX_NODE_LEN); + else + memcpy(ipxs->node, addr->sipx_node, IPX_NODE_LEN); + + rc = -EADDRINUSE; + if (ipxitf_find_internal_socket(intrfc, ipxs->node, + ipxs->port)) { + SOCK_DEBUG(sk, + "IPX: bind failed because port %X in use.\n", + ntohs(addr->sipx_port)); + goto out_put; + } + } else { + /* Source addresses are easy. It must be our + * network:node pair for an interface routed to IPX + * with the ipx routing ioctl() + */ + + memcpy(ipxs->node, intrfc->if_node, IPX_NODE_LEN); + + rc = -EADDRINUSE; + if (ipxitf_find_socket(intrfc, addr->sipx_port)) { + SOCK_DEBUG(sk, + "IPX: bind failed because port %X in use.\n", + ntohs(addr->sipx_port)); + goto out_put; + } + } + +#else /* !def CONFIG_IPX_INTERN */ + + /* Source addresses are easy. It must be our network:node pair for + an interface routed to IPX with the ipx routing ioctl() */ + + rc = -EADDRINUSE; + if (ipxitf_find_socket(intrfc, addr->sipx_port)) { + SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n", + ntohs((int)addr->sipx_port)); + goto out_put; + } + +#endif /* CONFIG_IPX_INTERN */ + + ipxitf_insert_socket(intrfc, sk); + sock_reset_flag(sk, SOCK_ZAPPED); + + rc = 0; +out_put: + ipxitf_put(intrfc); +out: + return rc; +} + +static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) +{ + struct sock *sk = sock->sk; + int rc; + + lock_sock(sk); + rc = __ipx_bind(sock, uaddr, addr_len); + release_sock(sk); + + return rc; +} + +static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, + int addr_len, int flags) +{ + struct sock *sk = sock->sk; + struct ipx_sock *ipxs = ipx_sk(sk); + struct sockaddr_ipx *addr; + int rc = -EINVAL; + struct ipx_route *rt; + + sk->sk_state = TCP_CLOSE; + sock->state = SS_UNCONNECTED; + + lock_sock(sk); + if (addr_len != sizeof(*addr)) + goto out; + addr = (struct sockaddr_ipx *)uaddr; + + /* put the autobinding in */ + if (!ipxs->port) { + struct sockaddr_ipx uaddr; + + uaddr.sipx_port = 0; + uaddr.sipx_network = 0; + +#ifdef CONFIG_IPX_INTERN + rc = -ENETDOWN; + if (!ipxs->intrfc) + goto out; /* Someone zonked the iface */ + memcpy(uaddr.sipx_node, ipxs->intrfc->if_node, + IPX_NODE_LEN); +#endif /* CONFIG_IPX_INTERN */ + + rc = __ipx_bind(sock, (struct sockaddr *)&uaddr, + sizeof(struct sockaddr_ipx)); + if (rc) + goto out; + } + + /* We can either connect to primary network or somewhere + * we can route to */ + rt = ipxrtr_lookup(addr->sipx_network); + rc = -ENETUNREACH; + if (!rt && !(!addr->sipx_network && ipx_primary_net)) + goto out; + + ipxs->dest_addr.net = addr->sipx_network; + ipxs->dest_addr.sock = addr->sipx_port; + memcpy(ipxs->dest_addr.node, addr->sipx_node, IPX_NODE_LEN); + ipxs->type = addr->sipx_type; + + if (sock->type == SOCK_DGRAM) { + sock->state = SS_CONNECTED; + sk->sk_state = TCP_ESTABLISHED; + } + + if (rt) + ipxrtr_put(rt); + rc = 0; +out: + release_sock(sk); + return rc; +} + + +static int ipx_getname(struct socket *sock, struct sockaddr *uaddr, + int *uaddr_len, int peer) +{ + struct ipx_address *addr; + struct sockaddr_ipx sipx; + struct sock *sk = sock->sk; + struct ipx_sock *ipxs = ipx_sk(sk); + int rc; + + *uaddr_len = sizeof(struct sockaddr_ipx); + + lock_sock(sk); + if (peer) { + rc = -ENOTCONN; + if (sk->sk_state != TCP_ESTABLISHED) + goto out; + + addr = &ipxs->dest_addr; + sipx.sipx_network = addr->net; + sipx.sipx_port = addr->sock; + memcpy(sipx.sipx_node, addr->node, IPX_NODE_LEN); + } else { + if (ipxs->intrfc) { + sipx.sipx_network = ipxs->intrfc->if_netnum; +#ifdef CONFIG_IPX_INTERN + memcpy(sipx.sipx_node, ipxs->node, IPX_NODE_LEN); +#else + memcpy(sipx.sipx_node, ipxs->intrfc->if_node, + IPX_NODE_LEN); +#endif /* CONFIG_IPX_INTERN */ + + } else { + sipx.sipx_network = 0; + memset(sipx.sipx_node, '\0', IPX_NODE_LEN); + } + + sipx.sipx_port = ipxs->port; + } + + sipx.sipx_family = AF_IPX; + sipx.sipx_type = ipxs->type; + sipx.sipx_zero = 0; + memcpy(uaddr, &sipx, sizeof(sipx)); + + rc = 0; +out: + release_sock(sk); + return rc; +} + +static int ipx_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) +{ + /* NULL here for pt means the packet was looped back */ + struct ipx_interface *intrfc; + struct ipxhdr *ipx; + u16 ipx_pktsize; + int rc = 0; + + if (!net_eq(dev_net(dev), &init_net)) + goto drop; + + /* Not ours */ + if (skb->pkt_type == PACKET_OTHERHOST) + goto drop; + + if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) + goto out; + + if (!pskb_may_pull(skb, sizeof(struct ipxhdr))) + goto drop; + + ipx_pktsize = ntohs(ipx_hdr(skb)->ipx_pktsize); + + /* Too small or invalid header? */ + if (ipx_pktsize < sizeof(struct ipxhdr) || + !pskb_may_pull(skb, ipx_pktsize)) + goto drop; + + ipx = ipx_hdr(skb); + if (ipx->ipx_checksum != IPX_NO_CHECKSUM && + ipx->ipx_checksum != ipx_cksum(ipx, ipx_pktsize)) + goto drop; + + IPX_SKB_CB(skb)->ipx_tctrl = ipx->ipx_tctrl; + IPX_SKB_CB(skb)->ipx_dest_net = ipx->ipx_dest.net; + IPX_SKB_CB(skb)->ipx_source_net = ipx->ipx_source.net; + + /* Determine what local ipx endpoint this is */ + intrfc = ipxitf_find_using_phys(dev, pt->type); + if (!intrfc) { + if (ipxcfg_auto_create_interfaces && + IPX_SKB_CB(skb)->ipx_dest_net) { + intrfc = ipxitf_auto_create(dev, pt->type); + if (intrfc) + ipxitf_hold(intrfc); + } + + if (!intrfc) /* Not one of ours */ + /* or invalid packet for auto creation */ + goto drop; + } + + rc = ipxitf_rcv(intrfc, skb); + ipxitf_put(intrfc); + goto out; +drop: + kfree_skb(skb); +out: + return rc; +} + +static int ipx_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) +{ + struct sock *sk = sock->sk; + struct ipx_sock *ipxs = ipx_sk(sk); + DECLARE_SOCKADDR(struct sockaddr_ipx *, usipx, msg->msg_name); + struct sockaddr_ipx local_sipx; + int rc = -EINVAL; + int flags = msg->msg_flags; + + lock_sock(sk); + /* Socket gets bound below anyway */ +/* if (sk->sk_zapped) + return -EIO; */ /* Socket not bound */ + if (flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) + goto out; + + /* Max possible packet size limited by 16 bit pktsize in header */ + if (len >= 65535 - sizeof(struct ipxhdr)) + goto out; + + if (usipx) { + if (!ipxs->port) { + struct sockaddr_ipx uaddr; + + uaddr.sipx_port = 0; + uaddr.sipx_network = 0; +#ifdef CONFIG_IPX_INTERN + rc = -ENETDOWN; + if (!ipxs->intrfc) + goto out; /* Someone zonked the iface */ + memcpy(uaddr.sipx_node, ipxs->intrfc->if_node, + IPX_NODE_LEN); +#endif + rc = __ipx_bind(sock, (struct sockaddr *)&uaddr, + sizeof(struct sockaddr_ipx)); + if (rc) + goto out; + } + + rc = -EINVAL; + if (msg->msg_namelen < sizeof(*usipx) || + usipx->sipx_family != AF_IPX) + goto out; + } else { + rc = -ENOTCONN; + if (sk->sk_state != TCP_ESTABLISHED) + goto out; + + usipx = &local_sipx; + usipx->sipx_family = AF_IPX; + usipx->sipx_type = ipxs->type; + usipx->sipx_port = ipxs->dest_addr.sock; + usipx->sipx_network = ipxs->dest_addr.net; + memcpy(usipx->sipx_node, ipxs->dest_addr.node, IPX_NODE_LEN); + } + + rc = ipxrtr_route_packet(sk, usipx, msg, len, flags & MSG_DONTWAIT); + if (rc >= 0) + rc = len; +out: + release_sock(sk); + return rc; +} + + +static int ipx_recvmsg(struct socket *sock, struct msghdr *msg, size_t size, + int flags) +{ + struct sock *sk = sock->sk; + struct ipx_sock *ipxs = ipx_sk(sk); + DECLARE_SOCKADDR(struct sockaddr_ipx *, sipx, msg->msg_name); + struct ipxhdr *ipx = NULL; + struct sk_buff *skb; + int copied, rc; + bool locked = true; + + lock_sock(sk); + /* put the autobinding in */ + if (!ipxs->port) { + struct sockaddr_ipx uaddr; + + uaddr.sipx_port = 0; + uaddr.sipx_network = 0; + +#ifdef CONFIG_IPX_INTERN + rc = -ENETDOWN; + if (!ipxs->intrfc) + goto out; /* Someone zonked the iface */ + memcpy(uaddr.sipx_node, ipxs->intrfc->if_node, IPX_NODE_LEN); +#endif /* CONFIG_IPX_INTERN */ + + rc = __ipx_bind(sock, (struct sockaddr *)&uaddr, + sizeof(struct sockaddr_ipx)); + if (rc) + goto out; + } + + rc = -ENOTCONN; + if (sock_flag(sk, SOCK_ZAPPED)) + goto out; + + release_sock(sk); + locked = false; + skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, + flags & MSG_DONTWAIT, &rc); + if (!skb) { + if (rc == -EAGAIN && (sk->sk_shutdown & RCV_SHUTDOWN)) + rc = 0; + goto out; + } + + ipx = ipx_hdr(skb); + copied = ntohs(ipx->ipx_pktsize) - sizeof(struct ipxhdr); + if (copied > size) { + copied = size; + msg->msg_flags |= MSG_TRUNC; + } + + rc = skb_copy_datagram_msg(skb, sizeof(struct ipxhdr), msg, copied); + if (rc) + goto out_free; + if (skb->tstamp) + sk->sk_stamp = skb->tstamp; + + if (sipx) { + sipx->sipx_family = AF_IPX; + sipx->sipx_port = ipx->ipx_source.sock; + memcpy(sipx->sipx_node, ipx->ipx_source.node, IPX_NODE_LEN); + sipx->sipx_network = IPX_SKB_CB(skb)->ipx_source_net; + sipx->sipx_type = ipx->ipx_type; + sipx->sipx_zero = 0; + msg->msg_namelen = sizeof(*sipx); + } + rc = copied; + +out_free: + skb_free_datagram(sk, skb); +out: + if (locked) + release_sock(sk); + return rc; +} + + +static int ipx_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) +{ + int rc = 0; + long amount = 0; + struct sock *sk = sock->sk; + void __user *argp = (void __user *)arg; + + lock_sock(sk); + switch (cmd) { + case TIOCOUTQ: + amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); + if (amount < 0) + amount = 0; + rc = put_user(amount, (int __user *)argp); + break; + case TIOCINQ: { + struct sk_buff *skb = skb_peek(&sk->sk_receive_queue); + /* These two are safe on a single CPU system as only + * user tasks fiddle here */ + if (skb) + amount = skb->len - sizeof(struct ipxhdr); + rc = put_user(amount, (int __user *)argp); + break; + } + case SIOCADDRT: + case SIOCDELRT: + rc = -EPERM; + if (capable(CAP_NET_ADMIN)) + rc = ipxrtr_ioctl(cmd, argp); + break; + case SIOCSIFADDR: + case SIOCAIPXITFCRT: + case SIOCAIPXPRISLT: + rc = -EPERM; + if (!capable(CAP_NET_ADMIN)) + break; + /* fall through */ + case SIOCGIFADDR: + rc = ipxitf_ioctl(cmd, argp); + break; + case SIOCIPXCFGDATA: + rc = ipxcfg_get_config_data(argp); + break; + case SIOCIPXNCPCONN: + /* + * This socket wants to take care of the NCP connection + * handed to us in arg. + */ + rc = -EPERM; + if (!capable(CAP_NET_ADMIN)) + break; + rc = get_user(ipx_sk(sk)->ipx_ncp_conn, + (const unsigned short __user *)argp); + break; + case SIOCGSTAMP: + rc = sock_get_timestamp(sk, argp); + break; + case SIOCGIFDSTADDR: + case SIOCSIFDSTADDR: + case SIOCGIFBRDADDR: + case SIOCSIFBRDADDR: + case SIOCGIFNETMASK: + case SIOCSIFNETMASK: + rc = -EINVAL; + break; + default: + rc = -ENOIOCTLCMD; + break; + } + release_sock(sk); + + return rc; +} + + +#ifdef CONFIG_COMPAT +static int ipx_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) +{ + /* + * These 4 commands use same structure on 32bit and 64bit. Rest of IPX + * commands is handled by generic ioctl code. As these commands are + * SIOCPROTOPRIVATE..SIOCPROTOPRIVATE+3, they cannot be handled by generic + * code. + */ + switch (cmd) { + case SIOCAIPXITFCRT: + case SIOCAIPXPRISLT: + case SIOCIPXCFGDATA: + case SIOCIPXNCPCONN: + return ipx_ioctl(sock, cmd, arg); + default: + return -ENOIOCTLCMD; + } +} +#endif + +static int ipx_shutdown(struct socket *sock, int mode) +{ + struct sock *sk = sock->sk; + + if (mode < SHUT_RD || mode > SHUT_RDWR) + return -EINVAL; + /* This maps: + * SHUT_RD (0) -> RCV_SHUTDOWN (1) + * SHUT_WR (1) -> SEND_SHUTDOWN (2) + * SHUT_RDWR (2) -> SHUTDOWN_MASK (3) + */ + ++mode; + + lock_sock(sk); + sk->sk_shutdown |= mode; + release_sock(sk); + sk->sk_state_change(sk); + + return 0; +} + +/* + * Socket family declarations + */ + +static const struct net_proto_family ipx_family_ops = { + .family = PF_IPX, + .create = ipx_create, + .owner = THIS_MODULE, +}; + +static const struct proto_ops ipx_dgram_ops = { + .family = PF_IPX, + .owner = THIS_MODULE, + .release = ipx_release, + .bind = ipx_bind, + .connect = ipx_connect, + .socketpair = sock_no_socketpair, + .accept = sock_no_accept, + .getname = ipx_getname, + .poll = datagram_poll, + .ioctl = ipx_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ipx_compat_ioctl, +#endif + .listen = sock_no_listen, + .shutdown = ipx_shutdown, + .setsockopt = ipx_setsockopt, + .getsockopt = ipx_getsockopt, + .sendmsg = ipx_sendmsg, + .recvmsg = ipx_recvmsg, + .mmap = sock_no_mmap, + .sendpage = sock_no_sendpage, +}; + +static struct packet_type ipx_8023_packet_type __read_mostly = { + .type = cpu_to_be16(ETH_P_802_3), + .func = ipx_rcv, +}; + +static struct packet_type ipx_dix_packet_type __read_mostly = { + .type = cpu_to_be16(ETH_P_IPX), + .func = ipx_rcv, +}; + +static struct notifier_block ipx_dev_notifier = { + .notifier_call = ipxitf_device_event, +}; + +static const unsigned char ipx_8022_type = 0xE0; +static const unsigned char ipx_snap_id[5] = { 0x0, 0x0, 0x0, 0x81, 0x37 }; +static const char ipx_EII_err_msg[] __initconst = + KERN_CRIT "IPX: Unable to register with Ethernet II\n"; +static const char ipx_8023_err_msg[] __initconst = + KERN_CRIT "IPX: Unable to register with 802.3\n"; +static const char ipx_llc_err_msg[] __initconst = + KERN_CRIT "IPX: Unable to register with 802.2\n"; +static const char ipx_snap_err_msg[] __initconst = + KERN_CRIT "IPX: Unable to register with SNAP\n"; + +static int __init ipx_init(void) +{ + int rc = proto_register(&ipx_proto, 1); + + if (rc != 0) + goto out; + + sock_register(&ipx_family_ops); + + pEII_datalink = make_EII_client(); + if (pEII_datalink) + dev_add_pack(&ipx_dix_packet_type); + else + printk(ipx_EII_err_msg); + + p8023_datalink = make_8023_client(); + if (p8023_datalink) + dev_add_pack(&ipx_8023_packet_type); + else + printk(ipx_8023_err_msg); + + p8022_datalink = register_8022_client(ipx_8022_type, ipx_rcv); + if (!p8022_datalink) + printk(ipx_llc_err_msg); + + pSNAP_datalink = register_snap_client(ipx_snap_id, ipx_rcv); + if (!pSNAP_datalink) + printk(ipx_snap_err_msg); + + register_netdevice_notifier(&ipx_dev_notifier); + ipx_register_sysctl(); + ipx_proc_init(); +out: + return rc; +} + +static void __exit ipx_proto_finito(void) +{ + ipx_proc_exit(); + ipx_unregister_sysctl(); + + unregister_netdevice_notifier(&ipx_dev_notifier); + + ipxitf_cleanup(); + + if (pSNAP_datalink) { + unregister_snap_client(pSNAP_datalink); + pSNAP_datalink = NULL; + } + + if (p8022_datalink) { + unregister_8022_client(p8022_datalink); + p8022_datalink = NULL; + } + + dev_remove_pack(&ipx_8023_packet_type); + if (p8023_datalink) { + destroy_8023_client(p8023_datalink); + p8023_datalink = NULL; + } + + dev_remove_pack(&ipx_dix_packet_type); + if (pEII_datalink) { + destroy_EII_client(pEII_datalink); + pEII_datalink = NULL; + } + + proto_unregister(&ipx_proto); + sock_unregister(ipx_family_ops.family); +} + +module_init(ipx_init); +module_exit(ipx_proto_finito); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_NETPROTO(PF_IPX); diff --git a/drivers/staging/ipx/ipx_proc.c b/drivers/staging/ipx/ipx_proc.c new file mode 100644 index 000000000000..b9232e4e2ed4 --- /dev/null +++ b/drivers/staging/ipx/ipx_proc.c @@ -0,0 +1,338 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * IPX proc routines + * + * Copyright(C) Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 2002 + */ + +#include <linux/init.h> +#ifdef CONFIG_PROC_FS +#include <linux/proc_fs.h> +#include <linux/spinlock.h> +#include <linux/seq_file.h> +#include <linux/export.h> +#include <net/net_namespace.h> +#include <net/tcp_states.h> +#include <net/ipx.h> + +static void *ipx_seq_interface_start(struct seq_file *seq, loff_t *pos) +{ + spin_lock_bh(&ipx_interfaces_lock); + return seq_list_start_head(&ipx_interfaces, *pos); +} + +static void *ipx_seq_interface_next(struct seq_file *seq, void *v, loff_t *pos) +{ + return seq_list_next(v, &ipx_interfaces, pos); +} + +static void ipx_seq_interface_stop(struct seq_file *seq, void *v) +{ + spin_unlock_bh(&ipx_interfaces_lock); +} + +static int ipx_seq_interface_show(struct seq_file *seq, void *v) +{ + struct ipx_interface *i; + + if (v == &ipx_interfaces) { + seq_puts(seq, "Network Node_Address Primary Device " + "Frame_Type"); +#ifdef IPX_REFCNT_DEBUG + seq_puts(seq, " refcnt"); +#endif + seq_puts(seq, "\n"); + goto out; + } + + i = list_entry(v, struct ipx_interface, node); + seq_printf(seq, "%08X ", ntohl(i->if_netnum)); + seq_printf(seq, "%02X%02X%02X%02X%02X%02X ", + i->if_node[0], i->if_node[1], i->if_node[2], + i->if_node[3], i->if_node[4], i->if_node[5]); + seq_printf(seq, "%-9s", i == ipx_primary_net ? "Yes" : "No"); + seq_printf(seq, "%-11s", ipx_device_name(i)); + seq_printf(seq, "%-9s", ipx_frame_name(i->if_dlink_type)); +#ifdef IPX_REFCNT_DEBUG + seq_printf(seq, "%6d", refcount_read(&i->refcnt)); +#endif + seq_puts(seq, "\n"); +out: + return 0; +} + +static void *ipx_seq_route_start(struct seq_file *seq, loff_t *pos) +{ + read_lock_bh(&ipx_routes_lock); + return seq_list_start_head(&ipx_routes, *pos); +} + +static void *ipx_seq_route_next(struct seq_file *seq, void *v, loff_t *pos) +{ + return seq_list_next(v, &ipx_routes, pos); +} + +static void ipx_seq_route_stop(struct seq_file *seq, void *v) +{ + read_unlock_bh(&ipx_routes_lock); +} + +static int ipx_seq_route_show(struct seq_file *seq, void *v) +{ + struct ipx_route *rt; + + if (v == &ipx_routes) { + seq_puts(seq, "Network Router_Net Router_Node\n"); + goto out; + } + + rt = list_entry(v, struct ipx_route, node); + + seq_printf(seq, "%08X ", ntohl(rt->ir_net)); + if (rt->ir_routed) + seq_printf(seq, "%08X %02X%02X%02X%02X%02X%02X\n", + ntohl(rt->ir_intrfc->if_netnum), + rt->ir_router_node[0], rt->ir_router_node[1], + rt->ir_router_node[2], rt->ir_router_node[3], + rt->ir_router_node[4], rt->ir_router_node[5]); + else + seq_puts(seq, "Directly Connected\n"); +out: + return 0; +} + +static __inline__ struct sock *ipx_get_socket_idx(loff_t pos) +{ + struct sock *s = NULL; + struct ipx_interface *i; + + list_for_each_entry(i, &ipx_interfaces, node) { + spin_lock_bh(&i->if_sklist_lock); + sk_for_each(s, &i->if_sklist) { + if (!pos) + break; + --pos; + } + spin_unlock_bh(&i->if_sklist_lock); + if (!pos) { + if (s) + goto found; + break; + } + } + s = NULL; +found: + return s; +} + +static void *ipx_seq_socket_start(struct seq_file *seq, loff_t *pos) +{ + loff_t l = *pos; + + spin_lock_bh(&ipx_interfaces_lock); + return l ? ipx_get_socket_idx(--l) : SEQ_START_TOKEN; +} + +static void *ipx_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos) +{ + struct sock* sk, *next; + struct ipx_interface *i; + struct ipx_sock *ipxs; + + ++*pos; + if (v == SEQ_START_TOKEN) { + sk = NULL; + i = ipx_interfaces_head(); + if (!i) + goto out; + sk = sk_head(&i->if_sklist); + if (sk) + spin_lock_bh(&i->if_sklist_lock); + goto out; + } + sk = v; + next = sk_next(sk); + if (next) { + sk = next; + goto out; + } + ipxs = ipx_sk(sk); + i = ipxs->intrfc; + spin_unlock_bh(&i->if_sklist_lock); + sk = NULL; + for (;;) { + if (i->node.next == &ipx_interfaces) + break; + i = list_entry(i->node.next, struct ipx_interface, node); + spin_lock_bh(&i->if_sklist_lock); + if (!hlist_empty(&i->if_sklist)) { + sk = sk_head(&i->if_sklist); + break; + } + spin_unlock_bh(&i->if_sklist_lock); + } +out: + return sk; +} + +static int ipx_seq_socket_show(struct seq_file *seq, void *v) +{ + struct sock *s; + struct ipx_sock *ipxs; + + if (v == SEQ_START_TOKEN) { +#ifdef CONFIG_IPX_INTERN + seq_puts(seq, "Local_Address " + "Remote_Address Tx_Queue " + "Rx_Queue State Uid\n"); +#else + seq_puts(seq, "Local_Address Remote_Address " + "Tx_Queue Rx_Queue State Uid\n"); +#endif + goto out; + } + + s = v; + ipxs = ipx_sk(s); +#ifdef CONFIG_IPX_INTERN + seq_printf(seq, "%08X:%02X%02X%02X%02X%02X%02X:%04X ", + ntohl(ipxs->intrfc->if_netnum), + ipxs->node[0], ipxs->node[1], ipxs->node[2], ipxs->node[3], + ipxs->node[4], ipxs->node[5], ntohs(ipxs->port)); +#else + seq_printf(seq, "%08X:%04X ", ntohl(ipxs->intrfc->if_netnum), + ntohs(ipxs->port)); +#endif /* CONFIG_IPX_INTERN */ + if (s->sk_state != TCP_ESTABLISHED) + seq_printf(seq, "%-28s", "Not_Connected"); + else { + seq_printf(seq, "%08X:%02X%02X%02X%02X%02X%02X:%04X ", + ntohl(ipxs->dest_addr.net), + ipxs->dest_addr.node[0], ipxs->dest_addr.node[1], + ipxs->dest_addr.node[2], ipxs->dest_addr.node[3], + ipxs->dest_addr.node[4], ipxs->dest_addr.node[5], + ntohs(ipxs->dest_addr.sock)); + } + + seq_printf(seq, "%08X %08X %02X %03u\n", + sk_wmem_alloc_get(s), + sk_rmem_alloc_get(s), + s->sk_state, + from_kuid_munged(seq_user_ns(seq), sock_i_uid(s))); +out: + return 0; +} + +static const struct seq_operations ipx_seq_interface_ops = { + .start = ipx_seq_interface_start, + .next = ipx_seq_interface_next, + .stop = ipx_seq_interface_stop, + .show = ipx_seq_interface_show, +}; + +static const struct seq_operations ipx_seq_route_ops = { + .start = ipx_seq_route_start, + .next = ipx_seq_route_next, + .stop = ipx_seq_route_stop, + .show = ipx_seq_route_show, +}; + +static const struct seq_operations ipx_seq_socket_ops = { + .start = ipx_seq_socket_start, + .next = ipx_seq_socket_next, + .stop = ipx_seq_interface_stop, + .show = ipx_seq_socket_show, +}; + +static int ipx_seq_route_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &ipx_seq_route_ops); +} + +static int ipx_seq_interface_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &ipx_seq_interface_ops); +} + +static int ipx_seq_socket_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &ipx_seq_socket_ops); +} + +static const struct file_operations ipx_seq_interface_fops = { + .open = ipx_seq_interface_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static const struct file_operations ipx_seq_route_fops = { + .open = ipx_seq_route_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static const struct file_operations ipx_seq_socket_fops = { + .open = ipx_seq_socket_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static struct proc_dir_entry *ipx_proc_dir; + +int __init ipx_proc_init(void) +{ + struct proc_dir_entry *p; + int rc = -ENOMEM; + + ipx_proc_dir = proc_mkdir("ipx", init_net.proc_net); + + if (!ipx_proc_dir) + goto out; + p = proc_create("interface", S_IRUGO, + ipx_proc_dir, &ipx_seq_interface_fops); + if (!p) + goto out_interface; + + p = proc_create("route", S_IRUGO, ipx_proc_dir, &ipx_seq_route_fops); + if (!p) + goto out_route; + + p = proc_create("socket", S_IRUGO, ipx_proc_dir, &ipx_seq_socket_fops); + if (!p) + goto out_socket; + + rc = 0; +out: + return rc; +out_socket: + remove_proc_entry("route", ipx_proc_dir); +out_route: + remove_proc_entry("interface", ipx_proc_dir); +out_interface: + remove_proc_entry("ipx", init_net.proc_net); + goto out; +} + +void __exit ipx_proc_exit(void) +{ + remove_proc_entry("interface", ipx_proc_dir); + remove_proc_entry("route", ipx_proc_dir); + remove_proc_entry("socket", ipx_proc_dir); + remove_proc_entry("ipx", init_net.proc_net); +} + +#else /* CONFIG_PROC_FS */ + +int __init ipx_proc_init(void) +{ + return 0; +} + +void __exit ipx_proc_exit(void) +{ +} + +#endif /* CONFIG_PROC_FS */ diff --git a/drivers/staging/ipx/ipx_route.c b/drivers/staging/ipx/ipx_route.c new file mode 100644 index 000000000000..3cf93aa9f284 --- /dev/null +++ b/drivers/staging/ipx/ipx_route.c @@ -0,0 +1,293 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Implements the IPX routing routines. + * Code moved from af_ipx.c. + * + * Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 2003 + * + * See net/ipx/ChangeLog. + */ + +#include <linux/list.h> +#include <linux/route.h> +#include <linux/slab.h> +#include <linux/spinlock.h> + +#include <net/ipx.h> +#include <net/sock.h> + +LIST_HEAD(ipx_routes); +DEFINE_RWLOCK(ipx_routes_lock); + +extern struct ipx_interface *ipx_internal_net; + +extern struct ipx_interface *ipxitf_find_using_net(__be32 net); +extern int ipxitf_demux_socket(struct ipx_interface *intrfc, + struct sk_buff *skb, int copy); +extern int ipxitf_demux_socket(struct ipx_interface *intrfc, + struct sk_buff *skb, int copy); + +struct ipx_route *ipxrtr_lookup(__be32 net) +{ + struct ipx_route *r; + + read_lock_bh(&ipx_routes_lock); + list_for_each_entry(r, &ipx_routes, node) + if (r->ir_net == net) { + ipxrtr_hold(r); + goto unlock; + } + r = NULL; +unlock: + read_unlock_bh(&ipx_routes_lock); + return r; +} + +/* + * Caller must hold a reference to intrfc + */ +int ipxrtr_add_route(__be32 network, struct ipx_interface *intrfc, + unsigned char *node) +{ + struct ipx_route *rt; + int rc; + + /* Get a route structure; either existing or create */ + rt = ipxrtr_lookup(network); + if (!rt) { + rt = kmalloc(sizeof(*rt), GFP_ATOMIC); + rc = -EAGAIN; + if (!rt) + goto out; + + refcount_set(&rt->refcnt, 1); + ipxrtr_hold(rt); + write_lock_bh(&ipx_routes_lock); + list_add(&rt->node, &ipx_routes); + write_unlock_bh(&ipx_routes_lock); + } else { + rc = -EEXIST; + if (intrfc == ipx_internal_net) + goto out_put; + } + + rt->ir_net = network; + rt->ir_intrfc = intrfc; + if (!node) { + memset(rt->ir_router_node, '\0', IPX_NODE_LEN); + rt->ir_routed = 0; + } else { + memcpy(rt->ir_router_node, node, IPX_NODE_LEN); + rt->ir_routed = 1; + } + + rc = 0; +out_put: + ipxrtr_put(rt); +out: + return rc; +} + +void ipxrtr_del_routes(struct ipx_interface *intrfc) +{ + struct ipx_route *r, *tmp; + + write_lock_bh(&ipx_routes_lock); + list_for_each_entry_safe(r, tmp, &ipx_routes, node) + if (r->ir_intrfc == intrfc) { + list_del(&r->node); + ipxrtr_put(r); + } + write_unlock_bh(&ipx_routes_lock); +} + +static int ipxrtr_create(struct ipx_route_definition *rd) +{ + struct ipx_interface *intrfc; + int rc = -ENETUNREACH; + + /* Find the appropriate interface */ + intrfc = ipxitf_find_using_net(rd->ipx_router_network); + if (!intrfc) + goto out; + rc = ipxrtr_add_route(rd->ipx_network, intrfc, rd->ipx_router_node); + ipxitf_put(intrfc); +out: + return rc; +} + +static int ipxrtr_delete(__be32 net) +{ + struct ipx_route *r, *tmp; + int rc; + + write_lock_bh(&ipx_routes_lock); + list_for_each_entry_safe(r, tmp, &ipx_routes, node) + if (r->ir_net == net) { + /* Directly connected; can't lose route */ + rc = -EPERM; + if (!r->ir_routed) + goto out; + list_del(&r->node); + ipxrtr_put(r); + rc = 0; + goto out; + } + rc = -ENOENT; +out: + write_unlock_bh(&ipx_routes_lock); + return rc; +} + +/* + * The skb has to be unshared, we'll end up calling ipxitf_send, that'll + * modify the packet + */ +int ipxrtr_route_skb(struct sk_buff *skb) +{ + struct ipxhdr *ipx = ipx_hdr(skb); + struct ipx_route *r = ipxrtr_lookup(IPX_SKB_CB(skb)->ipx_dest_net); + + if (!r) { /* no known route */ + kfree_skb(skb); + return 0; + } + + ipxitf_hold(r->ir_intrfc); + ipxitf_send(r->ir_intrfc, skb, r->ir_routed ? + r->ir_router_node : ipx->ipx_dest.node); + ipxitf_put(r->ir_intrfc); + ipxrtr_put(r); + + return 0; +} + +/* + * Route an outgoing frame from a socket. + */ +int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, + struct msghdr *msg, size_t len, int noblock) +{ + struct sk_buff *skb; + struct ipx_sock *ipxs = ipx_sk(sk); + struct ipx_interface *intrfc; + struct ipxhdr *ipx; + size_t size; + int ipx_offset; + struct ipx_route *rt = NULL; + int rc; + + /* Find the appropriate interface on which to send packet */ + if (!usipx->sipx_network && ipx_primary_net) { + usipx->sipx_network = ipx_primary_net->if_netnum; + intrfc = ipx_primary_net; + } else { + rt = ipxrtr_lookup(usipx->sipx_network); + rc = -ENETUNREACH; + if (!rt) + goto out; + intrfc = rt->ir_intrfc; + } + + ipxitf_hold(intrfc); + ipx_offset = intrfc->if_ipx_offset; + size = sizeof(struct ipxhdr) + len + ipx_offset; + + skb = sock_alloc_send_skb(sk, size, noblock, &rc); + if (!skb) + goto out_put; + + skb_reserve(skb, ipx_offset); + skb->sk = sk; + + /* Fill in IPX header */ + skb_reset_network_header(skb); + skb_reset_transport_header(skb); + skb_put(skb, sizeof(struct ipxhdr)); + ipx = ipx_hdr(skb); + ipx->ipx_pktsize = htons(len + sizeof(struct ipxhdr)); + IPX_SKB_CB(skb)->ipx_tctrl = 0; + ipx->ipx_type = usipx->sipx_type; + + IPX_SKB_CB(skb)->last_hop.index = -1; +#ifdef CONFIG_IPX_INTERN + IPX_SKB_CB(skb)->ipx_source_net = ipxs->intrfc->if_netnum; + memcpy(ipx->ipx_source.node, ipxs->node, IPX_NODE_LEN); +#else + rc = ntohs(ipxs->port); + if (rc == 0x453 || rc == 0x452) { + /* RIP/SAP special handling for mars_nwe */ + IPX_SKB_CB(skb)->ipx_source_net = intrfc->if_netnum; + memcpy(ipx->ipx_source.node, intrfc->if_node, IPX_NODE_LEN); + } else { + IPX_SKB_CB(skb)->ipx_source_net = ipxs->intrfc->if_netnum; + memcpy(ipx->ipx_source.node, ipxs->intrfc->if_node, + IPX_NODE_LEN); + } +#endif /* CONFIG_IPX_INTERN */ + ipx->ipx_source.sock = ipxs->port; + IPX_SKB_CB(skb)->ipx_dest_net = usipx->sipx_network; + memcpy(ipx->ipx_dest.node, usipx->sipx_node, IPX_NODE_LEN); + ipx->ipx_dest.sock = usipx->sipx_port; + + rc = memcpy_from_msg(skb_put(skb, len), msg, len); + if (rc) { + kfree_skb(skb); + goto out_put; + } + + /* Apply checksum. Not allowed on 802.3 links. */ + if (sk->sk_no_check_tx || + intrfc->if_dlink_type == htons(IPX_FRAME_8023)) + ipx->ipx_checksum = htons(0xFFFF); + else + ipx->ipx_checksum = ipx_cksum(ipx, len + sizeof(struct ipxhdr)); + + rc = ipxitf_send(intrfc, skb, (rt && rt->ir_routed) ? + rt->ir_router_node : ipx->ipx_dest.node); +out_put: + ipxitf_put(intrfc); + if (rt) + ipxrtr_put(rt); +out: + return rc; +} + +/* + * We use a normal struct rtentry for route handling + */ +int ipxrtr_ioctl(unsigned int cmd, void __user *arg) +{ + struct rtentry rt; /* Use these to behave like 'other' stacks */ + struct sockaddr_ipx *sg, *st; + int rc = -EFAULT; + + if (copy_from_user(&rt, arg, sizeof(rt))) + goto out; + + sg = (struct sockaddr_ipx *)&rt.rt_gateway; + st = (struct sockaddr_ipx *)&rt.rt_dst; + + rc = -EINVAL; + if (!(rt.rt_flags & RTF_GATEWAY) || /* Direct routes are fixed */ + sg->sipx_family != AF_IPX || + st->sipx_family != AF_IPX) + goto out; + + switch (cmd) { + case SIOCDELRT: + rc = ipxrtr_delete(st->sipx_network); + break; + case SIOCADDRT: { + struct ipx_route_definition f; + f.ipx_network = st->sipx_network; + f.ipx_router_network = sg->sipx_network; + memcpy(f.ipx_router_node, sg->sipx_node, IPX_NODE_LEN); + rc = ipxrtr_create(&f); + break; + } + } + +out: + return rc; +} diff --git a/drivers/staging/ipx/pe2.c b/drivers/staging/ipx/pe2.c new file mode 100644 index 000000000000..ba7d4214bbff --- /dev/null +++ b/drivers/staging/ipx/pe2.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <linux/in.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/netdevice.h> +#include <linux/skbuff.h> +#include <linux/slab.h> + +#include <net/datalink.h> + +static int pEII_request(struct datalink_proto *dl, + struct sk_buff *skb, unsigned char *dest_node) +{ + struct net_device *dev = skb->dev; + + skb->protocol = htons(ETH_P_IPX); + dev_hard_header(skb, dev, ETH_P_IPX, dest_node, NULL, skb->len); + return dev_queue_xmit(skb); +} + +struct datalink_proto *make_EII_client(void) +{ + struct datalink_proto *proto = kmalloc(sizeof(*proto), GFP_ATOMIC); + + if (proto) { + proto->header_length = 0; + proto->request = pEII_request; + } + + return proto; +} + +void destroy_EII_client(struct datalink_proto *dl) +{ + kfree(dl); +} diff --git a/drivers/staging/ipx/sysctl_net_ipx.c b/drivers/staging/ipx/sysctl_net_ipx.c new file mode 100644 index 000000000000..c3eef457db88 --- /dev/null +++ b/drivers/staging/ipx/sysctl_net_ipx.c @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0 +/* -*- linux-c -*- + * sysctl_net_ipx.c: sysctl interface to net IPX subsystem. + * + * Begun April 1, 1996, Mike Shaver. + * Added /proc/sys/net/ipx directory entry (empty =) ). [MS] + * Added /proc/sys/net/ipx/ipx_pprop_broadcasting - acme March 4, 2001 + */ + +#include <linux/mm.h> +#include <linux/sysctl.h> +#include <net/net_namespace.h> +#include <net/ipx.h> + +#ifndef CONFIG_SYSCTL +#error This file should not be compiled without CONFIG_SYSCTL defined +#endif + +static struct ctl_table ipx_table[] = { + { + .procname = "ipx_pprop_broadcasting", + .data = &sysctl_ipx_pprop_broadcasting, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, + { }, +}; + +static struct ctl_table_header *ipx_table_header; + +void ipx_register_sysctl(void) +{ + ipx_table_header = register_net_sysctl(&init_net, "net/ipx", ipx_table); +} + +void ipx_unregister_sysctl(void) +{ + unregister_net_sysctl_table(ipx_table_header); +} diff --git a/drivers/staging/irda/drivers/pxaficp_ir.c b/drivers/staging/irda/drivers/pxaficp_ir.c index 1dba16bc7f8d..2ea00a6531f9 100644 --- a/drivers/staging/irda/drivers/pxaficp_ir.c +++ b/drivers/staging/irda/drivers/pxaficp_ir.c @@ -12,7 +12,6 @@ * Infra-red driver (SIR/FIR) for the PXA2xx embedded microprocessor * */ -#include <linux/dma-mapping.h> #include <linux/interrupt.h> #include <linux/module.h> #include <linux/netdevice.h> diff --git a/drivers/staging/irda/net/irlmp.c b/drivers/staging/irda/net/irlmp.c index 34355061ab0b..7af618fb66c0 100644 --- a/drivers/staging/irda/net/irlmp.c +++ b/drivers/staging/irda/net/irlmp.c @@ -1668,7 +1668,7 @@ static int irlmp_slsap_inuse(__u8 slsap_sel) IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, goto errlsap;); - if ((self->slsap_sel == slsap_sel)) { + if (self->slsap_sel == slsap_sel) { pr_debug("Source LSAP selector=%02x in use\n", self->slsap_sel); goto errlsap; @@ -1693,7 +1693,7 @@ static int irlmp_slsap_inuse(__u8 slsap_sel) self = (struct lsap_cb *) hashbin_get_first(irlmp->unconnected_lsaps); while (self != NULL) { IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, goto erruncon;); - if ((self->slsap_sel == slsap_sel)) { + if (self->slsap_sel == slsap_sel) { pr_debug("Source LSAP selector=%02x in use (unconnected)\n", self->slsap_sel); goto erruncon; diff --git a/drivers/staging/ks7010/ks_wlan_net.c b/drivers/staging/ks7010/ks_wlan_net.c index 880085e2f24a..e48c55769c94 100644 --- a/drivers/staging/ks7010/ks_wlan_net.c +++ b/drivers/staging/ks7010/ks_wlan_net.c @@ -2990,7 +2990,7 @@ int ks_wlan_net_stop(struct net_device *dev) /** * is_connect_status() - return true if status is 'connected' * @status: high bit is used as FORCE_DISCONNECT, low bits used for - * connect status. + * connect status. */ bool is_connect_status(u32 status) { @@ -3000,7 +3000,7 @@ bool is_connect_status(u32 status) /** * is_disconnect_status() - return true if status is 'disconnected' * @status: high bit is used as FORCE_DISCONNECT, low bits used for - * disconnect status. + * disconnect status. */ bool is_disconnect_status(u32 status) { diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs.h b/drivers/staging/lustre/include/linux/libcfs/libcfs.h index 6ad8867e5451..ca3472cc952f 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs.h @@ -45,7 +45,6 @@ #include <linux/libcfs/libcfs_prim.h> #include <linux/libcfs/libcfs_time.h> #include <linux/libcfs/libcfs_string.h> -#include <linux/libcfs/libcfs_workitem.h> #include <linux/libcfs/libcfs_hash.h> #include <linux/libcfs/libcfs_fail.h> #include <linux/libcfs/curproc.h> @@ -74,16 +73,6 @@ sigset_t cfs_block_sigsinv(unsigned long sigs); void cfs_restore_sigs(sigset_t sigset); void cfs_clear_sigpending(void); -/* - * Random number handling - */ - -/* returns a random 32-bit integer */ -unsigned int cfs_rand(void); -/* seed the generator */ -void cfs_srand(unsigned int seed1, unsigned int seed2); -void cfs_get_random_bytes(void *buf, int size); - struct libcfs_ioctl_handler { struct list_head item; int (*handle_ioctl)(unsigned int cmd, struct libcfs_ioctl_hdr *hdr); @@ -126,7 +115,7 @@ extern struct miscdevice libcfs_dev; */ extern char lnet_debug_log_upcall[1024]; -extern struct cfs_wi_sched *cfs_sched_rehash; +extern struct workqueue_struct *cfs_rehash_wq; struct lnet_debugfs_symlink_def { char *name; diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_cpu.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_cpu.h index 6d132f941281..61bce77fddd6 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_cpu.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_cpu.h @@ -79,7 +79,7 @@ /** * return cpumask of CPU partition \a cpt */ -cpumask_t *cfs_cpt_cpumask(struct cfs_cpt_table *cptab, int cpt); +cpumask_var_t *cfs_cpt_cpumask(struct cfs_cpt_table *cptab, int cpt); /** * print string information of cpt-table */ @@ -96,7 +96,7 @@ struct cfs_cpt_table { u64 ctb_version; }; -static inline cpumask_t * +static inline cpumask_var_t * cfs_cpt_cpumask(struct cfs_cpt_table *cptab, int cpt) { return NULL; diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h index 5a27220cc608..0506f1d45757 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_hash.h @@ -248,7 +248,7 @@ struct cfs_hash { /** # of iterators (caller of cfs_hash_for_each_*) */ u32 hs_iterators; /** rehash workitem */ - struct cfs_workitem hs_rehash_wi; + struct work_struct hs_rehash_work; /** refcount on this hash table */ atomic_t hs_refcount; /** rehash buckets-table */ @@ -265,7 +265,7 @@ struct cfs_hash { /** bits when we found the max depth */ unsigned int hs_dep_bits; /** workitem to output max depth */ - struct cfs_workitem hs_dep_wi; + struct work_struct hs_dep_work; #endif /** name of htable */ char hs_name[0]; @@ -738,7 +738,7 @@ u64 cfs_hash_size_get(struct cfs_hash *hs); */ void cfs_hash_rehash_cancel_locked(struct cfs_hash *hs); void cfs_hash_rehash_cancel(struct cfs_hash *hs); -int cfs_hash_rehash(struct cfs_hash *hs, int do_rehash); +void cfs_hash_rehash(struct cfs_hash *hs, int do_rehash); void cfs_hash_rehash_key(struct cfs_hash *hs, const void *old_key, void *new_key, struct hlist_node *hnode); diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h index 2f4ff595fac9..491d5971d199 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_private.h @@ -43,13 +43,6 @@ # define DEBUG_SUBSYSTEM S_UNDEFINED #endif -/* - * When this is on, LASSERT macro includes check for assignment used instead - * of equality check, but doesn't have unlikely(). Turn this on from time to - * time to make test-builds. This shouldn't be on for production release. - */ -#define LASSERT_CHECKED (0) - #define LASSERTF(cond, fmt, ...) \ do { \ if (unlikely(!(cond))) { \ @@ -74,8 +67,6 @@ do { \ # define LINVRNT(exp) ((void)sizeof !!(exp)) #endif -#define KLASSERT(e) LASSERT(e) - void __noreturn lbug_with_loc(struct libcfs_debug_msg_data *msg); #define LBUG() \ @@ -84,74 +75,24 @@ do { \ lbug_with_loc(&msgdata); \ } while (0) -#ifndef LIBCFS_VMALLOC_SIZE -#define LIBCFS_VMALLOC_SIZE (2 << PAGE_SHIFT) /* 2 pages */ -#endif - -#define LIBCFS_ALLOC_PRE(size, mask) \ - LASSERT(!in_interrupt() || ((size) <= LIBCFS_VMALLOC_SIZE && \ - !gfpflags_allow_blocking(mask))) - -#define LIBCFS_ALLOC_POST(ptr, size) \ -do { \ - if (unlikely(!(ptr))) { \ - CERROR("LNET: out of memory at %s:%d (tried to alloc '" \ - #ptr "' = %d)\n", __FILE__, __LINE__, (int)(size)); \ - } else { \ - memset((ptr), 0, (size)); \ - } \ -} while (0) - -/** - * allocate memory with GFP flags @mask - */ -#define LIBCFS_ALLOC_GFP(ptr, size, mask) \ -do { \ - LIBCFS_ALLOC_PRE((size), (mask)); \ - (ptr) = (size) <= LIBCFS_VMALLOC_SIZE ? \ - kmalloc((size), (mask)) : vmalloc(size); \ - LIBCFS_ALLOC_POST((ptr), (size)); \ -} while (0) - -/** - * default allocator - */ -#define LIBCFS_ALLOC(ptr, size) \ - LIBCFS_ALLOC_GFP(ptr, size, GFP_NOFS) - -/** - * non-sleeping allocator +/* + * Use #define rather than inline, as lnet_cpt_table() might + * not be defined yet */ -#define LIBCFS_ALLOC_ATOMIC(ptr, size) \ - LIBCFS_ALLOC_GFP(ptr, size, GFP_ATOMIC) +#define kmalloc_cpt(size, flags, cpt) \ + kmalloc_node(size, flags, cfs_cpt_spread_node(lnet_cpt_table(), cpt)) -/** - * allocate memory for specified CPU partition - * \a cptab != NULL, \a cpt is CPU partition id of \a cptab - * \a cptab == NULL, \a cpt is HW NUMA node id - */ -#define LIBCFS_CPT_ALLOC_GFP(ptr, cptab, cpt, size, mask) \ -do { \ - LIBCFS_ALLOC_PRE((size), (mask)); \ - (ptr) = (size) <= LIBCFS_VMALLOC_SIZE ? \ - kmalloc_node((size), (mask), cfs_cpt_spread_node(cptab, cpt)) :\ - vmalloc_node(size, cfs_cpt_spread_node(cptab, cpt)); \ - LIBCFS_ALLOC_POST((ptr), (size)); \ -} while (0) +#define kzalloc_cpt(size, flags, cpt) \ + kmalloc_node(size, flags | __GFP_ZERO, \ + cfs_cpt_spread_node(lnet_cpt_table(), cpt)) -/** default numa allocator */ -#define LIBCFS_CPT_ALLOC(ptr, cptab, cpt, size) \ - LIBCFS_CPT_ALLOC_GFP(ptr, cptab, cpt, size, GFP_NOFS) +#define kvmalloc_cpt(size, flags, cpt) \ + kvmalloc_node(size, flags, \ + cfs_cpt_spread_node(lnet_cpt_table(), cpt)) -#define LIBCFS_FREE(ptr, size) \ -do { \ - if (unlikely(!(ptr))) { \ - CERROR("LIBCFS: free NULL '" #ptr "' (%d bytes) at " \ - "%s:%d\n", (int)(size), __FILE__, __LINE__); \ - break; \ - } \ - kvfree(ptr); \ -} while (0) +#define kvzalloc_cpt(size, flags, cpt) \ + kvmalloc_node(size, flags | __GFP_ZERO, \ + cfs_cpt_spread_node(lnet_cpt_table(), cpt)) /******************************************************************************/ @@ -242,59 +183,18 @@ do { \ #define LASSERT_ATOMIC_ZERO(a) LASSERT_ATOMIC_EQ(a, 0) #define LASSERT_ATOMIC_POS(a) LASSERT_ATOMIC_GT(a, 0) -#define CFS_ALLOC_PTR(ptr) LIBCFS_ALLOC(ptr, sizeof(*(ptr))) -#define CFS_FREE_PTR(ptr) LIBCFS_FREE(ptr, sizeof(*(ptr))) - -/* max value for numeric network address */ -#define MAX_NUMERIC_VALUE 0xffffffff - /* implication */ #define ergo(a, b) (!(a) || (b)) /* logical equivalence */ #define equi(a, b) (!!(a) == !!(b)) -/* -------------------------------------------------------------------- - * Light-weight trace - * Support for temporary event tracing with minimal Heisenberg effect. - * -------------------------------------------------------------------- - */ - -#define MKSTR(ptr) ((ptr)) ? (ptr) : "" - -static inline size_t cfs_size_round4(int val) -{ - return (val + 3) & (~0x3); -} - #ifndef HAVE_CFS_SIZE_ROUND static inline size_t cfs_size_round(int val) { - return (val + 7) & (~0x7); + return round_up(val, 8); } #define HAVE_CFS_SIZE_ROUND #endif -static inline size_t cfs_size_round16(int val) -{ - return (val + 0xf) & (~0xf); -} - -static inline size_t cfs_size_round32(int val) -{ - return (val + 0x1f) & (~0x1f); -} - -static inline size_t cfs_size_round0(int val) -{ - if (!val) - return 0; - return (val + 1 + 7) & (~0x7); -} - -static inline size_t cfs_round_strlen(char *fset) -{ - return cfs_size_round((int)strlen(fset) + 1); -} - #endif diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_string.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_string.h index 1191764c431a..66463477074a 100644 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_string.h +++ b/drivers/staging/lustre/include/linux/libcfs/libcfs_string.h @@ -73,7 +73,6 @@ struct cfs_expr_list { struct list_head el_exprs; }; -char *cfs_trimwhite(char *str); int cfs_gettok(struct cfs_lstr *next, char delim, struct cfs_lstr *res); int cfs_str2num_check(char *str, int nob, unsigned int *num, unsigned int min, unsigned int max); @@ -86,11 +85,11 @@ static inline void cfs_expr_list_values_free(u32 *values, int num) { /* - * This array is allocated by LIBCFS_ALLOC(), so it shouldn't be freed + * This array is allocated by kvalloc(), so it shouldn't be freed * by OBD_FREE() if it's called by module other than libcfs & LNet, * otherwise we will see fake memory leak */ - LIBCFS_FREE(values, num * sizeof(values[0])); + kvfree(values); } void cfs_expr_list_free(struct cfs_expr_list *expr_list); diff --git a/drivers/staging/lustre/include/linux/libcfs/libcfs_workitem.h b/drivers/staging/lustre/include/linux/libcfs/libcfs_workitem.h deleted file mode 100644 index fc780f608e57..000000000000 --- a/drivers/staging/lustre/include/linux/libcfs/libcfs_workitem.h +++ /dev/null @@ -1,107 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.gnu.org/licenses/gpl-2.0.html - * - * GPL HEADER END - */ -/* - * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - * - * Copyright (c) 2012, Intel Corporation. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - * - * libcfs/include/libcfs/libcfs_workitem.h - * - * Author: Isaac Huang <he.h.huang@oracle.com> - * Liang Zhen <zhen.liang@sun.com> - * - * A workitems is deferred work with these semantics: - * - a workitem always runs in thread context. - * - a workitem can be concurrent with other workitems but is strictly - * serialized with respect to itself. - * - no CPU affinity, a workitem does not necessarily run on the same CPU - * that schedules it. However, this might change in the future. - * - if a workitem is scheduled again before it has a chance to run, it - * runs only once. - * - if a workitem is scheduled while it runs, it runs again after it - * completes; this ensures that events occurring while other events are - * being processed receive due attention. This behavior also allows a - * workitem to reschedule itself. - * - * Usage notes: - * - a workitem can sleep but it should be aware of how that sleep might - * affect others. - * - a workitem runs inside a kernel thread so there's no user space to access. - * - do not use a workitem if the scheduling latency can't be tolerated. - * - * When wi_action returns non-zero, it means the workitem has either been - * freed or reused and workitem scheduler won't touch it any more. - */ - -#ifndef __LIBCFS_WORKITEM_H__ -#define __LIBCFS_WORKITEM_H__ - -struct cfs_wi_sched; - -void cfs_wi_sched_destroy(struct cfs_wi_sched *sched); -int cfs_wi_sched_create(char *name, struct cfs_cpt_table *cptab, int cpt, - int nthrs, struct cfs_wi_sched **sched_pp); - -struct cfs_workitem; - -typedef int (*cfs_wi_action_t) (struct cfs_workitem *); -struct cfs_workitem { - /** chain on runq or rerunq */ - struct list_head wi_list; - /** working function */ - cfs_wi_action_t wi_action; - /** arg for working function */ - void *wi_data; - /** in running */ - unsigned short wi_running:1; - /** scheduled */ - unsigned short wi_scheduled:1; -}; - -static inline void -cfs_wi_init(struct cfs_workitem *wi, void *data, cfs_wi_action_t action) -{ - INIT_LIST_HEAD(&wi->wi_list); - - wi->wi_running = 0; - wi->wi_scheduled = 0; - wi->wi_data = data; - wi->wi_action = action; -} - -void cfs_wi_schedule(struct cfs_wi_sched *sched, struct cfs_workitem *wi); -int cfs_wi_deschedule(struct cfs_wi_sched *sched, struct cfs_workitem *wi); -void cfs_wi_exit(struct cfs_wi_sched *sched, struct cfs_workitem *wi); - -int cfs_wi_startup(void); -void cfs_wi_shutdown(void); - -/** # workitem scheduler loops before reschedule */ -#define CFS_WI_RESCHED 128 - -#endif /* __LIBCFS_WORKITEM_H__ */ diff --git a/drivers/staging/lustre/include/linux/libcfs/linux/linux-cpu.h b/drivers/staging/lustre/include/linux/libcfs/linux/linux-cpu.h index 854c84358ab4..6035376f2830 100644 --- a/drivers/staging/lustre/include/linux/libcfs/linux/linux-cpu.h +++ b/drivers/staging/lustre/include/linux/libcfs/linux/linux-cpu.h @@ -49,7 +49,7 @@ /** virtual processing unit */ struct cfs_cpu_partition { /* CPUs mask for this partition */ - cpumask_t *cpt_cpumask; + cpumask_var_t cpt_cpumask; /* nodes mask for this partition */ nodemask_t *cpt_nodemask; /* spread rotor for NUMA allocator */ @@ -69,7 +69,7 @@ struct cfs_cpt_table { /* shadow HW CPU to CPU partition ID */ int *ctb_cpu2cpt; /* all cpus in this partition table */ - cpumask_t *ctb_cpumask; + cpumask_var_t ctb_cpumask; /* all nodes in this partition table */ nodemask_t *ctb_nodemask; }; diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h index c1626726fa05..df4c72507a15 100644 --- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h +++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h @@ -181,21 +181,6 @@ lnet_net_lock_current(void) #define MAX_PORTALS 64 -static inline struct lnet_eq * -lnet_eq_alloc(void) -{ - struct lnet_eq *eq; - - LIBCFS_ALLOC(eq, sizeof(*eq)); - return eq; -} - -static inline void -lnet_eq_free(struct lnet_eq *eq) -{ - LIBCFS_FREE(eq, sizeof(*eq)); -} - static inline struct lnet_libmd * lnet_md_alloc(struct lnet_md *umd) { @@ -211,7 +196,7 @@ lnet_md_alloc(struct lnet_md *umd) size = offsetof(struct lnet_libmd, md_iov.iov[niov]); } - LIBCFS_ALLOC(md, size); + md = kzalloc(size, GFP_NOFS); if (md) { /* Set here in case of early free */ @@ -223,52 +208,6 @@ lnet_md_alloc(struct lnet_md *umd) return md; } -static inline void -lnet_md_free(struct lnet_libmd *md) -{ - unsigned int size; - - if (md->md_options & LNET_MD_KIOV) - size = offsetof(struct lnet_libmd, md_iov.kiov[md->md_niov]); - else - size = offsetof(struct lnet_libmd, md_iov.iov[md->md_niov]); - - LIBCFS_FREE(md, size); -} - -static inline struct lnet_me * -lnet_me_alloc(void) -{ - struct lnet_me *me; - - LIBCFS_ALLOC(me, sizeof(*me)); - return me; -} - -static inline void -lnet_me_free(struct lnet_me *me) -{ - LIBCFS_FREE(me, sizeof(*me)); -} - -static inline struct lnet_msg * -lnet_msg_alloc(void) -{ - struct lnet_msg *msg; - - LIBCFS_ALLOC(msg, sizeof(*msg)); - - /* no need to zero, LIBCFS_ALLOC does for us */ - return msg; -} - -static inline void -lnet_msg_free(struct lnet_msg *msg) -{ - LASSERT(!msg->msg_onactivelist); - LIBCFS_FREE(msg, sizeof(*msg)); -} - struct lnet_libhandle *lnet_res_lh_lookup(struct lnet_res_container *rec, __u64 cookie); void lnet_res_lh_initialize(struct lnet_res_container *rec, diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c index 8024843521ab..ec84edfda271 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.c @@ -325,7 +325,7 @@ int kiblnd_create_peer(struct lnet_ni *ni, struct kib_peer **peerp, LASSERT(net); LASSERT(nid != LNET_NID_ANY); - LIBCFS_CPT_ALLOC(peer, lnet_cpt_table(), cpt, sizeof(*peer)); + peer = kzalloc_cpt(sizeof(*peer), GFP_NOFS, cpt); if (!peer) { CERROR("Cannot allocate peer\n"); return -ENOMEM; @@ -367,7 +367,7 @@ void kiblnd_destroy_peer(struct kib_peer *peer) LASSERT(kiblnd_peer_idle(peer)); LASSERT(list_empty(&peer->ibp_tx_queue)); - LIBCFS_FREE(peer, sizeof(*peer)); + kfree(peer); /* * NB a peer's connections keep a reference on their peer until @@ -596,7 +596,7 @@ static void kiblnd_setup_mtu_locked(struct rdma_cm_id *cmid) static int kiblnd_get_completion_vector(struct kib_conn *conn, int cpt) { - cpumask_t *mask; + cpumask_var_t *mask; int vectors; int off; int i; @@ -611,8 +611,8 @@ static int kiblnd_get_completion_vector(struct kib_conn *conn, int cpt) return 0; /* hash NID to CPU id in this partition... */ - off = do_div(nid, cpumask_weight(mask)); - for_each_cpu(i, mask) { + off = do_div(nid, cpumask_weight(*mask)); + for_each_cpu(i, *mask) { if (!off--) return i % vectors; } @@ -656,15 +656,14 @@ struct kib_conn *kiblnd_create_conn(struct kib_peer *peer, struct rdma_cm_id *cm LASSERT(sched->ibs_nthreads > 0); - LIBCFS_CPT_ALLOC(init_qp_attr, lnet_cpt_table(), cpt, - sizeof(*init_qp_attr)); + init_qp_attr = kzalloc_cpt(sizeof(*init_qp_attr), GFP_NOFS, cpt); if (!init_qp_attr) { CERROR("Can't allocate qp_attr for %s\n", libcfs_nid2str(peer->ibp_nid)); goto failed_0; } - LIBCFS_CPT_ALLOC(conn, lnet_cpt_table(), cpt, sizeof(*conn)); + conn = kzalloc_cpt(sizeof(*conn), GFP_NOFS, cpt); if (!conn) { CERROR("Can't allocate connection for %s\n", libcfs_nid2str(peer->ibp_nid)); @@ -687,8 +686,7 @@ struct kib_conn *kiblnd_create_conn(struct kib_peer *peer, struct rdma_cm_id *cm INIT_LIST_HEAD(&conn->ibc_active_txs); spin_lock_init(&conn->ibc_lock); - LIBCFS_CPT_ALLOC(conn->ibc_connvars, lnet_cpt_table(), cpt, - sizeof(*conn->ibc_connvars)); + conn->ibc_connvars = kzalloc_cpt(sizeof(*conn->ibc_connvars), GFP_NOFS, cpt); if (!conn->ibc_connvars) { CERROR("Can't allocate in-progress connection state\n"); goto failed_2; @@ -722,8 +720,8 @@ struct kib_conn *kiblnd_create_conn(struct kib_peer *peer, struct rdma_cm_id *cm write_unlock_irqrestore(glock, flags); - LIBCFS_CPT_ALLOC(conn->ibc_rxs, lnet_cpt_table(), cpt, - IBLND_RX_MSGS(conn) * sizeof(struct kib_rx)); + conn->ibc_rxs = kzalloc_cpt(IBLND_RX_MSGS(conn) * sizeof(struct kib_rx), + GFP_NOFS, cpt); if (!conn->ibc_rxs) { CERROR("Cannot allocate RX buffers\n"); goto failed_2; @@ -776,7 +774,7 @@ struct kib_conn *kiblnd_create_conn(struct kib_peer *peer, struct rdma_cm_id *cm goto failed_2; } - LIBCFS_FREE(init_qp_attr, sizeof(*init_qp_attr)); + kfree(init_qp_attr); /* 1 ref for caller and each rxmsg */ atomic_set(&conn->ibc_refcount, 1 + IBLND_RX_MSGS(conn)); @@ -826,14 +824,15 @@ struct kib_conn *kiblnd_create_conn(struct kib_peer *peer, struct rdma_cm_id *cm return conn; failed_2: - kiblnd_destroy_conn(conn, true); + kiblnd_destroy_conn(conn); + kfree(conn); failed_1: - LIBCFS_FREE(init_qp_attr, sizeof(*init_qp_attr)); + kfree(init_qp_attr); failed_0: return NULL; } -void kiblnd_destroy_conn(struct kib_conn *conn, bool free_conn) +void kiblnd_destroy_conn(struct kib_conn *conn) { struct rdma_cm_id *cmid = conn->ibc_cmid; struct kib_peer *peer = conn->ibc_peer; @@ -877,13 +876,8 @@ void kiblnd_destroy_conn(struct kib_conn *conn, bool free_conn) if (conn->ibc_rx_pages) kiblnd_unmap_rx_descs(conn); - if (conn->ibc_rxs) { - LIBCFS_FREE(conn->ibc_rxs, - IBLND_RX_MSGS(conn) * sizeof(struct kib_rx)); - } - - if (conn->ibc_connvars) - LIBCFS_FREE(conn->ibc_connvars, sizeof(*conn->ibc_connvars)); + kfree(conn->ibc_rxs); + kfree(conn->ibc_connvars); if (conn->ibc_hdev) kiblnd_hdev_decref(conn->ibc_hdev); @@ -896,8 +890,6 @@ void kiblnd_destroy_conn(struct kib_conn *conn, bool free_conn) rdma_destroy_id(cmid); atomic_dec(&net->ibn_nconns); } - - LIBCFS_FREE(conn, sizeof(*conn)); } int kiblnd_close_peer_conns_locked(struct kib_peer *peer, int why) @@ -1089,7 +1081,7 @@ static void kiblnd_free_pages(struct kib_pages *p) __free_page(p->ibp_pages[i]); } - LIBCFS_FREE(p, offsetof(struct kib_pages, ibp_pages[npages])); + kfree(p); } int kiblnd_alloc_pages(struct kib_pages **pp, int cpt, int npages) @@ -1097,14 +1089,13 @@ int kiblnd_alloc_pages(struct kib_pages **pp, int cpt, int npages) struct kib_pages *p; int i; - LIBCFS_CPT_ALLOC(p, lnet_cpt_table(), cpt, - offsetof(struct kib_pages, ibp_pages[npages])); + p = kzalloc_cpt(offsetof(struct kib_pages, ibp_pages[npages]), + GFP_NOFS, cpt); if (!p) { CERROR("Can't allocate descriptor for %d pages\n", npages); return -ENOMEM; } - memset(p, 0, offsetof(struct kib_pages, ibp_pages[npages])); p->ibp_npages = npages; for (i = 0; i < npages; i++) { @@ -1299,7 +1290,7 @@ static void kiblnd_destroy_fmr_pool(struct kib_fmr_pool *fpo) frd_list) { list_del(&frd->frd_list); ib_dereg_mr(frd->frd_mr); - LIBCFS_FREE(frd, sizeof(*frd)); + kfree(frd); i++; } if (i < fpo->fast_reg.fpo_pool_size) @@ -1310,7 +1301,7 @@ static void kiblnd_destroy_fmr_pool(struct kib_fmr_pool *fpo) if (fpo->fpo_hdev) kiblnd_hdev_decref(fpo->fpo_hdev); - LIBCFS_FREE(fpo, sizeof(*fpo)); + kfree(fpo); } static void kiblnd_destroy_fmr_pool_list(struct list_head *head) @@ -1376,8 +1367,7 @@ static int kiblnd_alloc_freg_pool(struct kib_fmr_poolset *fps, struct kib_fmr_po INIT_LIST_HEAD(&fpo->fast_reg.fpo_pool_list); fpo->fast_reg.fpo_pool_size = 0; for (i = 0; i < fps->fps_pool_size; i++) { - LIBCFS_CPT_ALLOC(frd, lnet_cpt_table(), fps->fps_cpt, - sizeof(*frd)); + frd = kzalloc_cpt(sizeof(*frd), GFP_NOFS, fps->fps_cpt); if (!frd) { CERROR("Failed to allocate a new fast_reg descriptor\n"); rc = -ENOMEM; @@ -1405,14 +1395,14 @@ static int kiblnd_alloc_freg_pool(struct kib_fmr_poolset *fps, struct kib_fmr_po out_middle: if (frd->frd_mr) ib_dereg_mr(frd->frd_mr); - LIBCFS_FREE(frd, sizeof(*frd)); + kfree(frd); out: list_for_each_entry_safe(frd, tmp, &fpo->fast_reg.fpo_pool_list, frd_list) { list_del(&frd->frd_list); ib_dereg_mr(frd->frd_mr); - LIBCFS_FREE(frd, sizeof(*frd)); + kfree(frd); } return rc; @@ -1426,7 +1416,7 @@ static int kiblnd_create_fmr_pool(struct kib_fmr_poolset *fps, struct kib_fmr_pool *fpo; int rc; - LIBCFS_CPT_ALLOC(fpo, lnet_cpt_table(), fps->fps_cpt, sizeof(*fpo)); + fpo = kzalloc_cpt(sizeof(*fpo), GFP_NOFS, fps->fps_cpt); if (!fpo) return -ENOMEM; @@ -1464,7 +1454,7 @@ static int kiblnd_create_fmr_pool(struct kib_fmr_poolset *fps, out_fpo: kiblnd_hdev_decref(fpo->fpo_hdev); - LIBCFS_FREE(fpo, sizeof(*fpo)); + kfree(fpo); return rc; } @@ -1985,33 +1975,17 @@ static void kiblnd_destroy_tx_pool(struct kib_pool *pool) struct kib_tx *tx = &tpo->tpo_tx_descs[i]; list_del(&tx->tx_list); - if (tx->tx_pages) - LIBCFS_FREE(tx->tx_pages, - LNET_MAX_IOV * - sizeof(*tx->tx_pages)); - if (tx->tx_frags) - LIBCFS_FREE(tx->tx_frags, - (1 + IBLND_MAX_RDMA_FRAGS) * - sizeof(*tx->tx_frags)); - if (tx->tx_wrq) - LIBCFS_FREE(tx->tx_wrq, - (1 + IBLND_MAX_RDMA_FRAGS) * - sizeof(*tx->tx_wrq)); - if (tx->tx_sge) - LIBCFS_FREE(tx->tx_sge, - (1 + IBLND_MAX_RDMA_FRAGS) * - sizeof(*tx->tx_sge)); - if (tx->tx_rd) - LIBCFS_FREE(tx->tx_rd, - offsetof(struct kib_rdma_desc, - rd_frags[IBLND_MAX_RDMA_FRAGS])); - } - - LIBCFS_FREE(tpo->tpo_tx_descs, - pool->po_size * sizeof(struct kib_tx)); + kfree(tx->tx_pages); + kfree(tx->tx_frags); + kfree(tx->tx_wrq); + kfree(tx->tx_sge); + kfree(tx->tx_rd); + } + + kfree(tpo->tpo_tx_descs); out: kiblnd_fini_pool(pool); - LIBCFS_FREE(tpo, sizeof(*tpo)); + kfree(tpo); } static int kiblnd_tx_pool_size(int ncpts) @@ -2029,7 +2003,7 @@ static int kiblnd_create_tx_pool(struct kib_poolset *ps, int size, struct kib_pool *pool; struct kib_tx_pool *tpo; - LIBCFS_CPT_ALLOC(tpo, lnet_cpt_table(), ps->ps_cpt, sizeof(*tpo)); + tpo = kzalloc_cpt(sizeof(*tpo), GFP_NOFS, ps->ps_cpt); if (!tpo) { CERROR("Failed to allocate TX pool\n"); return -ENOMEM; @@ -2043,12 +2017,12 @@ static int kiblnd_create_tx_pool(struct kib_poolset *ps, int size, npg = DIV_ROUND_UP(size * IBLND_MSG_SIZE, PAGE_SIZE); if (kiblnd_alloc_pages(&tpo->tpo_tx_pages, ps->ps_cpt, npg)) { CERROR("Can't allocate tx pages: %d\n", npg); - LIBCFS_FREE(tpo, sizeof(*tpo)); + kfree(tpo); return -ENOMEM; } - LIBCFS_CPT_ALLOC(tpo->tpo_tx_descs, lnet_cpt_table(), ps->ps_cpt, - size * sizeof(struct kib_tx)); + tpo->tpo_tx_descs = kzalloc_cpt(size * sizeof(struct kib_tx), + GFP_NOFS, ps->ps_cpt); if (!tpo->tpo_tx_descs) { CERROR("Can't allocate %d tx descriptors\n", size); ps->ps_pool_destroy(pool); @@ -2062,36 +2036,35 @@ static int kiblnd_create_tx_pool(struct kib_poolset *ps, int size, tx->tx_pool = tpo; if (ps->ps_net->ibn_fmr_ps) { - LIBCFS_CPT_ALLOC(tx->tx_pages, - lnet_cpt_table(), ps->ps_cpt, - LNET_MAX_IOV * sizeof(*tx->tx_pages)); + tx->tx_pages = kzalloc_cpt(LNET_MAX_IOV * sizeof(*tx->tx_pages), + GFP_NOFS, ps->ps_cpt); if (!tx->tx_pages) break; } - LIBCFS_CPT_ALLOC(tx->tx_frags, lnet_cpt_table(), ps->ps_cpt, - (1 + IBLND_MAX_RDMA_FRAGS) * - sizeof(*tx->tx_frags)); + tx->tx_frags = kzalloc_cpt((1 + IBLND_MAX_RDMA_FRAGS) * + sizeof(*tx->tx_frags), + GFP_NOFS, ps->ps_cpt); if (!tx->tx_frags) break; sg_init_table(tx->tx_frags, IBLND_MAX_RDMA_FRAGS + 1); - LIBCFS_CPT_ALLOC(tx->tx_wrq, lnet_cpt_table(), ps->ps_cpt, - (1 + IBLND_MAX_RDMA_FRAGS) * - sizeof(*tx->tx_wrq)); + tx->tx_wrq = kzalloc_cpt((1 + IBLND_MAX_RDMA_FRAGS) * + sizeof(*tx->tx_wrq), + GFP_NOFS, ps->ps_cpt); if (!tx->tx_wrq) break; - LIBCFS_CPT_ALLOC(tx->tx_sge, lnet_cpt_table(), ps->ps_cpt, - (1 + IBLND_MAX_RDMA_FRAGS) * - sizeof(*tx->tx_sge)); + tx->tx_sge = kzalloc_cpt((1 + IBLND_MAX_RDMA_FRAGS) * + sizeof(*tx->tx_sge), + GFP_NOFS, ps->ps_cpt); if (!tx->tx_sge) break; - LIBCFS_CPT_ALLOC(tx->tx_rd, lnet_cpt_table(), ps->ps_cpt, - offsetof(struct kib_rdma_desc, - rd_frags[IBLND_MAX_RDMA_FRAGS])); + tx->tx_rd = kzalloc_cpt(offsetof(struct kib_rdma_desc, + rd_frags[IBLND_MAX_RDMA_FRAGS]), + GFP_NOFS, ps->ps_cpt); if (!tx->tx_rd) break; } @@ -2263,7 +2236,7 @@ void kiblnd_hdev_destroy(struct kib_hca_dev *hdev) if (hdev->ibh_cmid) rdma_destroy_id(hdev->ibh_cmid); - LIBCFS_FREE(hdev, sizeof(*hdev)); + kfree(hdev); } /* DUMMY */ @@ -2392,7 +2365,7 @@ int kiblnd_dev_failover(struct kib_dev *dev) goto out; } - LIBCFS_ALLOC(hdev, sizeof(*hdev)); + hdev = kzalloc(sizeof(*hdev), GFP_NOFS); if (!hdev) { CERROR("Failed to allocate kib_hca_dev\n"); rdma_destroy_id(cmid); @@ -2471,7 +2444,7 @@ void kiblnd_destroy_dev(struct kib_dev *dev) if (dev->ibd_hdev) kiblnd_hdev_decref(dev->ibd_hdev); - LIBCFS_FREE(dev, sizeof(*dev)); + kfree(dev); } static struct kib_dev *kiblnd_create_dev(char *ifname) @@ -2495,7 +2468,7 @@ static struct kib_dev *kiblnd_create_dev(char *ifname) return NULL; } - LIBCFS_ALLOC(dev, sizeof(*dev)); + dev = kzalloc(sizeof(*dev), GFP_NOFS); if (!dev) return NULL; @@ -2517,7 +2490,7 @@ static struct kib_dev *kiblnd_create_dev(char *ifname) rc = kiblnd_dev_failover(dev); if (rc) { CERROR("Can't initialize device: %d\n", rc); - LIBCFS_FREE(dev, sizeof(*dev)); + kfree(dev); return NULL; } @@ -2577,11 +2550,7 @@ static void kiblnd_base_shutdown(void) break; } - if (kiblnd_data.kib_peers) { - LIBCFS_FREE(kiblnd_data.kib_peers, - sizeof(struct list_head) * - kiblnd_data.kib_peer_hash_size); - } + kvfree(kiblnd_data.kib_peers); if (kiblnd_data.kib_scheds) cfs_percpt_free(kiblnd_data.kib_scheds); @@ -2648,7 +2617,7 @@ static void kiblnd_shutdown(struct lnet_ni *ni) net->ibn_init = IBLND_INIT_NOTHING; ni->ni_data = NULL; - LIBCFS_FREE(net, sizeof(*net)); + kfree(net); out: if (list_empty(&kiblnd_data.kib_devs)) @@ -2673,8 +2642,9 @@ static int kiblnd_base_startup(void) INIT_LIST_HEAD(&kiblnd_data.kib_failed_devs); kiblnd_data.kib_peer_hash_size = IBLND_PEER_HASH_SIZE; - LIBCFS_ALLOC(kiblnd_data.kib_peers, - sizeof(struct list_head) * kiblnd_data.kib_peer_hash_size); + kiblnd_data.kib_peers = kvmalloc_array(kiblnd_data.kib_peer_hash_size, + sizeof(struct list_head), + GFP_KERNEL); if (!kiblnd_data.kib_peers) goto failed; for (i = 0; i < kiblnd_data.kib_peer_hash_size; i++) @@ -2865,7 +2835,7 @@ static int kiblnd_startup(struct lnet_ni *ni) return rc; } - LIBCFS_ALLOC(net, sizeof(*net)); + net = kzalloc(sizeof(*net), GFP_NOFS); ni->ni_data = net; if (!net) goto net_failed; diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h index 171eced213f8..b18911d09e9a 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd.h @@ -1016,7 +1016,7 @@ int kiblnd_close_peer_conns_locked(struct kib_peer *peer, int why); struct kib_conn *kiblnd_create_conn(struct kib_peer *peer, struct rdma_cm_id *cmid, int state, int version); -void kiblnd_destroy_conn(struct kib_conn *conn, bool free_conn); +void kiblnd_destroy_conn(struct kib_conn *conn); void kiblnd_close_conn(struct kib_conn *conn, int error); void kiblnd_close_conn_locked(struct kib_conn *conn, int error); diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index 40e3af5d8b04..b3e7f28eb978 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -2124,7 +2124,7 @@ kiblnd_connreq_done(struct kib_conn *conn, int status) (conn->ibc_state == IBLND_CONN_PASSIVE_WAIT && peer->ibp_accepting > 0)); - LIBCFS_FREE(conn->ibc_connvars, sizeof(*conn->ibc_connvars)); + kfree(conn->ibc_connvars); conn->ibc_connvars = NULL; if (status) { @@ -3314,11 +3314,13 @@ kiblnd_connd(void *arg) spin_unlock_irqrestore(lock, flags); dropped_lock = 1; - kiblnd_destroy_conn(conn, !peer); + kiblnd_destroy_conn(conn); spin_lock_irqsave(lock, flags); - if (!peer) + if (!peer) { + kfree(conn); continue; + } conn->ibc_peer = peer; if (peer->ibp_reconnected < KIB_RECONN_HIGH_RACE) @@ -3363,7 +3365,7 @@ kiblnd_connd(void *arg) reconn += kiblnd_reconnect_peer(conn->ibc_peer); kiblnd_peer_decref(conn->ibc_peer); - LIBCFS_FREE(conn, sizeof(*conn)); + kfree(conn); spin_lock_irqsave(lock, flags); } diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c index a71b765215ad..b9235400bf1d 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_modparams.c @@ -181,8 +181,8 @@ int kiblnd_tunables_setup(struct lnet_ni *ni) * defaulted */ if (!ni->ni_lnd_tunables) { - LIBCFS_ALLOC(ni->ni_lnd_tunables, - sizeof(*ni->ni_lnd_tunables)); + ni->ni_lnd_tunables = kzalloc(sizeof(*ni->ni_lnd_tunables), + GFP_NOFS); if (!ni->ni_lnd_tunables) return -ENOMEM; diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c index 8267119ccc8e..ff292216290d 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd.c @@ -66,7 +66,7 @@ ksocknal_create_route(__u32 ipaddr, int port) { struct ksock_route *route; - LIBCFS_ALLOC(route, sizeof(*route)); + route = kzalloc(sizeof(*route), GFP_NOFS); if (!route) return NULL; @@ -93,7 +93,7 @@ ksocknal_destroy_route(struct ksock_route *route) if (route->ksnr_peer) ksocknal_peer_decref(route->ksnr_peer); - LIBCFS_FREE(route, sizeof(*route)); + kfree(route); } static int @@ -108,7 +108,7 @@ ksocknal_create_peer(struct ksock_peer **peerp, struct lnet_ni *ni, LASSERT(id.pid != LNET_PID_ANY); LASSERT(!in_interrupt()); - LIBCFS_CPT_ALLOC(peer, lnet_cpt_table(), cpt, sizeof(*peer)); + peer = kzalloc_cpt(sizeof(*peer), GFP_NOFS, cpt); if (!peer) return -ENOMEM; @@ -132,7 +132,7 @@ ksocknal_create_peer(struct ksock_peer **peerp, struct lnet_ni *ni, if (net->ksnn_shutdown) { spin_unlock_bh(&net->ksnn_lock); - LIBCFS_FREE(peer, sizeof(*peer)); + kfree(peer); CERROR("Can't create peer: network shutdown\n"); return -ESHUTDOWN; } @@ -160,7 +160,7 @@ ksocknal_destroy_peer(struct ksock_peer *peer) LASSERT(list_empty(&peer->ksnp_tx_queue)); LASSERT(list_empty(&peer->ksnp_zc_req_list)); - LIBCFS_FREE(peer, sizeof(*peer)); + kfree(peer); /* * NB a peer's connections and routes keep a reference on their peer @@ -985,7 +985,7 @@ ksocknal_accept(struct lnet_ni *ni, struct socket *sock) rc = lnet_sock_getaddr(sock, 1, &peer_ip, &peer_port); LASSERT(!rc); /* we succeeded before */ - LIBCFS_ALLOC(cr, sizeof(*cr)); + cr = kzalloc(sizeof(*cr), GFP_NOFS); if (!cr) { LCONSOLE_ERROR_MSG(0x12f, "Dropping connection request from %pI4h: memory exhausted\n", &peer_ip); @@ -1043,7 +1043,7 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_route *route, LASSERT(active == (type != SOCKLND_CONN_NONE)); - LIBCFS_ALLOC(conn, sizeof(*conn)); + conn = kzalloc(sizeof(*conn), GFP_NOFS); if (!conn) { rc = -ENOMEM; goto failed_0; @@ -1070,8 +1070,9 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_route *route, conn->ksnc_tx_carrier = NULL; atomic_set(&conn->ksnc_tx_nob, 0); - LIBCFS_ALLOC(hello, offsetof(struct ksock_hello_msg, - kshm_ips[LNET_MAX_INTERFACES])); + hello = kvzalloc(offsetof(struct ksock_hello_msg, + kshm_ips[LNET_MAX_INTERFACES]), + GFP_KERNEL); if (!hello) { rc = -ENOMEM; goto failed_1; @@ -1334,8 +1335,7 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_route *route, rc = ksocknal_send_hello(ni, conn, peerid.nid, hello); } - LIBCFS_FREE(hello, offsetof(struct ksock_hello_msg, - kshm_ips[LNET_MAX_INTERFACES])); + kvfree(hello); /* * setup the socket AFTER I've received hello (it disables @@ -1415,11 +1415,9 @@ ksocknal_create_conn(struct lnet_ni *ni, struct ksock_route *route, ksocknal_peer_decref(peer); failed_1: - if (hello) - LIBCFS_FREE(hello, offsetof(struct ksock_hello_msg, - kshm_ips[LNET_MAX_INTERFACES])); + kvfree(hello); - LIBCFS_FREE(conn, sizeof(*conn)); + kfree(conn); failed_0: sock_release(sock); @@ -1716,7 +1714,7 @@ ksocknal_destroy_conn(struct ksock_conn *conn) ksocknal_peer_decref(conn->ksnc_peer); - LIBCFS_FREE(conn, sizeof(*conn)); + kfree(conn); } int @@ -2259,19 +2257,12 @@ ksocknal_free_buffers(void) struct ksock_sched_info *info; int i; - cfs_percpt_for_each(info, i, ksocknal_data.ksnd_sched_info) { - if (info->ksi_scheds) { - LIBCFS_FREE(info->ksi_scheds, - info->ksi_nthreads_max * - sizeof(info->ksi_scheds[0])); - } - } + cfs_percpt_for_each(info, i, ksocknal_data.ksnd_sched_info) + kfree(info->ksi_scheds); cfs_percpt_free(ksocknal_data.ksnd_sched_info); } - LIBCFS_FREE(ksocknal_data.ksnd_peers, - sizeof(struct list_head) * - ksocknal_data.ksnd_peer_hash_size); + kvfree(ksocknal_data.ksnd_peers); spin_lock(&ksocknal_data.ksnd_tx_lock); @@ -2286,7 +2277,7 @@ ksocknal_free_buffers(void) list_for_each_entry_safe(tx, temp, &zlist, tx_list) { list_del(&tx->tx_list); - LIBCFS_FREE(tx, tx->tx_desc_size); + kfree(tx); } } else { spin_unlock(&ksocknal_data.ksnd_tx_lock); @@ -2401,9 +2392,9 @@ ksocknal_base_startup(void) memset(&ksocknal_data, 0, sizeof(ksocknal_data)); /* zero pointers */ ksocknal_data.ksnd_peer_hash_size = SOCKNAL_PEER_HASH_SIZE; - LIBCFS_ALLOC(ksocknal_data.ksnd_peers, - sizeof(struct list_head) * - ksocknal_data.ksnd_peer_hash_size); + ksocknal_data.ksnd_peers = kvmalloc_array(ksocknal_data.ksnd_peer_hash_size, + sizeof(struct list_head), + GFP_KERNEL); if (!ksocknal_data.ksnd_peers) return -ENOMEM; @@ -2456,8 +2447,8 @@ ksocknal_base_startup(void) info->ksi_nthreads_max = nthrs; info->ksi_cpt = i; - LIBCFS_CPT_ALLOC(info->ksi_scheds, lnet_cpt_table(), i, - info->ksi_nthreads_max * sizeof(*sched)); + info->ksi_scheds = kzalloc_cpt(info->ksi_nthreads_max * sizeof(*sched), + GFP_NOFS, i); if (!info->ksi_scheds) goto failed; @@ -2622,7 +2613,7 @@ ksocknal_shutdown(struct lnet_ni *ni) } list_del(&net->ksnn_list); - LIBCFS_FREE(net, sizeof(*net)); + kfree(net); ksocknal_data.ksnd_nnets--; if (!ksocknal_data.ksnd_nnets) @@ -2815,7 +2806,7 @@ ksocknal_startup(struct lnet_ni *ni) return rc; } - LIBCFS_ALLOC(net, sizeof(*net)); + net = kzalloc(sizeof(*net), GFP_NOFS); if (!net) goto fail_0; @@ -2877,7 +2868,7 @@ ksocknal_startup(struct lnet_ni *ni) return 0; fail_1: - LIBCFS_FREE(net, sizeof(*net)); + kfree(net); fail_0: if (!ksocknal_data.ksnd_nnets) ksocknal_base_shutdown(); diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c index 27c56d5ae4e5..11fd3a36424f 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_cb.c @@ -46,7 +46,7 @@ ksocknal_alloc_tx(int type, int size) } if (!tx) - LIBCFS_ALLOC(tx, size); + tx = kzalloc(size, GFP_NOFS); if (!tx) return NULL; @@ -102,7 +102,7 @@ ksocknal_free_tx(struct ksock_tx *tx) spin_unlock(&ksocknal_data.ksnd_tx_lock); } else { - LIBCFS_FREE(tx, tx->tx_desc_size); + kfree(tx); } } @@ -2117,7 +2117,7 @@ ksocknal_connd(void *arg) ksocknal_create_conn(cr->ksncr_ni, NULL, cr->ksncr_sock, SOCKLND_CONN_NONE); lnet_ni_decref(cr->ksncr_ni); - LIBCFS_FREE(cr, sizeof(*cr)); + kfree(cr); spin_lock_bh(connd_lock); } diff --git a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c index d827f770e831..05982dac781c 100644 --- a/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c +++ b/drivers/staging/lustre/lnet/klnds/socklnd/socklnd_proto.c @@ -467,7 +467,7 @@ ksocknal_send_hello_v1(struct ksock_conn *conn, struct ksock_hello_msg *hello) BUILD_BUG_ON(sizeof(struct lnet_magicversion) != offsetof(struct lnet_hdr, src_nid)); - LIBCFS_ALLOC(hdr, sizeof(*hdr)); + hdr = kzalloc(sizeof(*hdr), GFP_NOFS); if (!hdr) { CERROR("Can't allocate struct lnet_hdr\n"); return -ENOMEM; @@ -526,7 +526,7 @@ ksocknal_send_hello_v1(struct ksock_conn *conn, struct ksock_hello_msg *hello) &conn->ksnc_ipaddr, conn->ksnc_port); } out: - LIBCFS_FREE(hdr, sizeof(*hdr)); + kfree(hdr); return rc; } @@ -582,7 +582,7 @@ ksocknal_recv_hello_v1(struct ksock_conn *conn, struct ksock_hello_msg *hello, int rc; int i; - LIBCFS_ALLOC(hdr, sizeof(*hdr)); + hdr = kzalloc(sizeof(*hdr), GFP_NOFS); if (!hdr) { CERROR("Can't allocate struct lnet_hdr\n"); return -ENOMEM; @@ -644,7 +644,7 @@ ksocknal_recv_hello_v1(struct ksock_conn *conn, struct ksock_hello_msg *hello, } } out: - LIBCFS_FREE(hdr, sizeof(*hdr)); + kfree(hdr); return rc; } diff --git a/drivers/staging/lustre/lnet/libcfs/Makefile b/drivers/staging/lustre/lnet/libcfs/Makefile index 1607570ef8de..730f2c675047 100644 --- a/drivers/staging/lustre/lnet/libcfs/Makefile +++ b/drivers/staging/lustre/lnet/libcfs/Makefile @@ -15,7 +15,7 @@ libcfs-linux-objs += linux-mem.o libcfs-linux-objs := $(addprefix linux/,$(libcfs-linux-objs)) libcfs-all-objs := debug.o fail.o module.o tracefile.o \ - libcfs_string.o hash.o prng.o workitem.o \ + libcfs_string.o hash.o \ libcfs_cpu.o libcfs_mem.o libcfs_lock.o libcfs-objs := $(libcfs-linux-objs) $(libcfs-all-objs) diff --git a/drivers/staging/lustre/lnet/libcfs/fail.c b/drivers/staging/lustre/lnet/libcfs/fail.c index 5d501beeb622..39439b303d65 100644 --- a/drivers/staging/lustre/lnet/libcfs/fail.c +++ b/drivers/staging/lustre/lnet/libcfs/fail.c @@ -61,7 +61,7 @@ int __cfs_fail_check_set(u32 id, u32 value, int set) /* Fail 1/cfs_fail_val times */ if (cfs_fail_loc & CFS_FAIL_RAND) { - if (cfs_fail_val < 2 || cfs_rand() % cfs_fail_val > 0) + if (cfs_fail_val < 2 || prandom_u32_max(cfs_fail_val) > 0) return 0; } diff --git a/drivers/staging/lustre/lnet/libcfs/hash.c b/drivers/staging/lustre/lnet/libcfs/hash.c index f4f67d2b301e..f7b3c9306456 100644 --- a/drivers/staging/lustre/lnet/libcfs/hash.c +++ b/drivers/staging/lustre/lnet/libcfs/hash.c @@ -114,7 +114,7 @@ module_param(warn_on_depth, uint, 0644); MODULE_PARM_DESC(warn_on_depth, "warning when hash depth is high."); #endif -struct cfs_wi_sched *cfs_sched_rehash; +struct workqueue_struct *cfs_rehash_wq; static inline void cfs_hash_nl_lock(union cfs_hash_lock *lock, int exclusive) {} @@ -519,7 +519,7 @@ cfs_hash_bd_dep_record(struct cfs_hash *hs, struct cfs_hash_bd *bd, int dep_cur) hs->hs_dep_bits = hs->hs_cur_bits; spin_unlock(&hs->hs_dep_lock); - cfs_wi_schedule(cfs_sched_rehash, &hs->hs_dep_wi); + queue_work(cfs_rehash_wq, &hs->hs_dep_work); # endif } @@ -864,12 +864,10 @@ cfs_hash_buckets_free(struct cfs_hash_bucket **buckets, { int i; - for (i = prev_size; i < size; i++) { - if (buckets[i]) - LIBCFS_FREE(buckets[i], bkt_size); - } + for (i = prev_size; i < size; i++) + kfree(buckets[i]); - LIBCFS_FREE(buckets, sizeof(buckets[0]) * size); + kvfree(buckets); } /* @@ -889,7 +887,7 @@ cfs_hash_buckets_realloc(struct cfs_hash *hs, struct cfs_hash_bucket **old_bkts, if (old_bkts && old_size == new_size) return old_bkts; - LIBCFS_ALLOC(new_bkts, sizeof(new_bkts[0]) * new_size); + new_bkts = kvmalloc_array(new_size, sizeof(new_bkts[0]), GFP_KERNEL); if (!new_bkts) return NULL; @@ -902,7 +900,7 @@ cfs_hash_buckets_realloc(struct cfs_hash *hs, struct cfs_hash_bucket **old_bkts, struct hlist_head *hhead; struct cfs_hash_bd bd; - LIBCFS_ALLOC(new_bkts[i], cfs_hash_bkt_size(hs)); + new_bkts[i] = kzalloc(cfs_hash_bkt_size(hs), GFP_KERNEL); if (!new_bkts[i]) { cfs_hash_buckets_free(new_bkts, cfs_hash_bkt_size(hs), old_size, new_size); @@ -939,12 +937,12 @@ cfs_hash_buckets_realloc(struct cfs_hash *hs, struct cfs_hash_bucket **old_bkts, * @flags - CFS_HASH_REHASH enable synamic hash resizing * - CFS_HASH_SORT enable chained hash sort */ -static int cfs_hash_rehash_worker(struct cfs_workitem *wi); +static void cfs_hash_rehash_worker(struct work_struct *work); #if CFS_HASH_DEBUG_LEVEL >= CFS_HASH_DEBUG_1 -static int cfs_hash_dep_print(struct cfs_workitem *wi) +static void cfs_hash_dep_print(struct work_struct *work) { - struct cfs_hash *hs = container_of(wi, struct cfs_hash, hs_dep_wi); + struct cfs_hash *hs = container_of(work, struct cfs_hash, hs_dep_work); int dep; int bkt; int off; @@ -968,21 +966,12 @@ static int cfs_hash_dep_print(struct cfs_workitem *wi) static void cfs_hash_depth_wi_init(struct cfs_hash *hs) { spin_lock_init(&hs->hs_dep_lock); - cfs_wi_init(&hs->hs_dep_wi, hs, cfs_hash_dep_print); + INIT_WORK(&hs->hs_dep_work, cfs_hash_dep_print); } static void cfs_hash_depth_wi_cancel(struct cfs_hash *hs) { - if (cfs_wi_deschedule(cfs_sched_rehash, &hs->hs_dep_wi)) - return; - - spin_lock(&hs->hs_dep_lock); - while (hs->hs_dep_bits) { - spin_unlock(&hs->hs_dep_lock); - cond_resched(); - spin_lock(&hs->hs_dep_lock); - } - spin_unlock(&hs->hs_dep_lock); + cancel_work_sync(&hs->hs_dep_work); } #else /* CFS_HASH_DEBUG_LEVEL < CFS_HASH_DEBUG_1 */ @@ -1023,7 +1012,7 @@ cfs_hash_create(char *name, unsigned int cur_bits, unsigned int max_bits, len = !(flags & CFS_HASH_BIGNAME) ? CFS_HASH_NAME_LEN : CFS_HASH_BIGNAME_LEN; - LIBCFS_ALLOC(hs, offsetof(struct cfs_hash, hs_name[len])); + hs = kzalloc(offsetof(struct cfs_hash, hs_name[len]), GFP_KERNEL); if (!hs) return NULL; @@ -1044,7 +1033,7 @@ cfs_hash_create(char *name, unsigned int cur_bits, unsigned int max_bits, hs->hs_ops = ops; hs->hs_extra_bytes = extra_bytes; hs->hs_rehash_bits = 0; - cfs_wi_init(&hs->hs_rehash_wi, hs, cfs_hash_rehash_worker); + INIT_WORK(&hs->hs_rehash_work, cfs_hash_rehash_worker); cfs_hash_depth_wi_init(hs); if (cfs_hash_with_rehash(hs)) @@ -1055,7 +1044,7 @@ cfs_hash_create(char *name, unsigned int cur_bits, unsigned int max_bits, if (hs->hs_buckets) return hs; - LIBCFS_FREE(hs, offsetof(struct cfs_hash, hs_name[len])); + kfree(hs); return NULL; } EXPORT_SYMBOL(cfs_hash_create); @@ -1118,7 +1107,7 @@ cfs_hash_destroy(struct cfs_hash *hs) 0, CFS_HASH_NBKT(hs)); i = cfs_hash_with_bigname(hs) ? CFS_HASH_BIGNAME_LEN : CFS_HASH_NAME_LEN; - LIBCFS_FREE(hs, offsetof(struct cfs_hash, hs_name[i])); + kfree(hs); } struct cfs_hash *cfs_hash_getref(struct cfs_hash *hs) @@ -1364,6 +1353,7 @@ cfs_hash_for_each_enter(struct cfs_hash *hs) cfs_hash_lock(hs, 1); hs->hs_iterators++; + cfs_hash_unlock(hs, 1); /* NB: iteration is mostly called by service thread, * we tend to cancel pending rehash-request, instead of @@ -1371,8 +1361,7 @@ cfs_hash_for_each_enter(struct cfs_hash *hs) * after iteration */ if (cfs_hash_is_rehashing(hs)) - cfs_hash_rehash_cancel_locked(hs); - cfs_hash_unlock(hs, 1); + cfs_hash_rehash_cancel(hs); } static void @@ -1774,42 +1763,13 @@ EXPORT_SYMBOL(cfs_hash_for_each_key); * theta thresholds for @hs are tunable via cfs_hash_set_theta(). */ void -cfs_hash_rehash_cancel_locked(struct cfs_hash *hs) -{ - int i; - - /* need hold cfs_hash_lock(hs, 1) */ - LASSERT(cfs_hash_with_rehash(hs) && - !cfs_hash_with_no_lock(hs)); - - if (!cfs_hash_is_rehashing(hs)) - return; - - if (cfs_wi_deschedule(cfs_sched_rehash, &hs->hs_rehash_wi)) { - hs->hs_rehash_bits = 0; - return; - } - - for (i = 2; cfs_hash_is_rehashing(hs); i++) { - cfs_hash_unlock(hs, 1); - /* raise console warning while waiting too long */ - CDEBUG(is_power_of_2(i >> 3) ? D_WARNING : D_INFO, - "hash %s is still rehashing, rescheded %d\n", - hs->hs_name, i - 1); - cond_resched(); - cfs_hash_lock(hs, 1); - } -} - -void cfs_hash_rehash_cancel(struct cfs_hash *hs) { - cfs_hash_lock(hs, 1); - cfs_hash_rehash_cancel_locked(hs); - cfs_hash_unlock(hs, 1); + LASSERT(cfs_hash_with_rehash(hs)); + cancel_work_sync(&hs->hs_rehash_work); } -int +void cfs_hash_rehash(struct cfs_hash *hs, int do_rehash) { int rc; @@ -1821,21 +1781,21 @@ cfs_hash_rehash(struct cfs_hash *hs, int do_rehash) rc = cfs_hash_rehash_bits(hs); if (rc <= 0) { cfs_hash_unlock(hs, 1); - return rc; + return; } hs->hs_rehash_bits = rc; if (!do_rehash) { /* launch and return */ - cfs_wi_schedule(cfs_sched_rehash, &hs->hs_rehash_wi); + queue_work(cfs_rehash_wq, &hs->hs_rehash_work); cfs_hash_unlock(hs, 1); - return 0; + return; } /* rehash right now */ cfs_hash_unlock(hs, 1); - return cfs_hash_rehash_worker(&hs->hs_rehash_wi); + cfs_hash_rehash_worker(&hs->hs_rehash_work); } static int @@ -1869,10 +1829,10 @@ cfs_hash_rehash_bd(struct cfs_hash *hs, struct cfs_hash_bd *old) return c; } -static int -cfs_hash_rehash_worker(struct cfs_workitem *wi) +static void +cfs_hash_rehash_worker(struct work_struct *work) { - struct cfs_hash *hs = container_of(wi, struct cfs_hash, hs_rehash_wi); + struct cfs_hash *hs = container_of(work, struct cfs_hash, hs_rehash_work); struct cfs_hash_bucket **bkts; struct cfs_hash_bd bd; unsigned int old_size; @@ -1956,8 +1916,6 @@ cfs_hash_rehash_worker(struct cfs_workitem *wi) hs->hs_cur_bits = hs->hs_rehash_bits; out: hs->hs_rehash_bits = 0; - if (rc == -ESRCH) /* never be scheduled again */ - cfs_wi_exit(cfs_sched_rehash, wi); bsize = cfs_hash_bkt_size(hs); cfs_hash_unlock(hs, 1); /* can't refer to @hs anymore because it could be destroyed */ @@ -1965,8 +1923,6 @@ out: cfs_hash_buckets_free(bkts, bsize, new_size, old_size); if (rc) CDEBUG(D_INFO, "early quit of rehashing: %d\n", rc); - /* return 1 only if cfs_wi_exit is called */ - return rc == -ESRCH; } /** diff --git a/drivers/staging/lustre/lnet/libcfs/libcfs_cpu.c b/drivers/staging/lustre/lnet/libcfs/libcfs_cpu.c index e3a4c67a66b5..76291a350406 100644 --- a/drivers/staging/lustre/lnet/libcfs/libcfs_cpu.c +++ b/drivers/staging/lustre/lnet/libcfs/libcfs_cpu.c @@ -51,7 +51,7 @@ cfs_cpt_table_alloc(unsigned int ncpt) return NULL; } - LIBCFS_ALLOC(cptab, sizeof(*cptab)); + cptab = kzalloc(sizeof(*cptab), GFP_NOFS); if (cptab) { cptab->ctb_version = CFS_CPU_VERSION_MAGIC; node_set(0, cptab->ctb_nodemask); @@ -67,7 +67,7 @@ cfs_cpt_table_free(struct cfs_cpt_table *cptab) { LASSERT(cptab->ctb_version == CFS_CPU_VERSION_MAGIC); - LIBCFS_FREE(cptab, sizeof(*cptab)); + kfree(cptab); } EXPORT_SYMBOL(cfs_cpt_table_free); @@ -113,7 +113,7 @@ cfs_cpt_nodemask(struct cfs_cpt_table *cptab, int cpt) { return &cptab->ctb_nodemask; } -EXPORT_SYMBOL(cfs_cpt_cpumask); +EXPORT_SYMBOL(cfs_cpt_nodemask); int cfs_cpt_set_cpu(struct cfs_cpt_table *cptab, int cpt, int cpu) diff --git a/drivers/staging/lustre/lnet/libcfs/libcfs_lock.c b/drivers/staging/lustre/lnet/libcfs/libcfs_lock.c index f6a0040f4ab1..670ad5a34224 100644 --- a/drivers/staging/lustre/lnet/libcfs/libcfs_lock.c +++ b/drivers/staging/lustre/lnet/libcfs/libcfs_lock.c @@ -38,7 +38,7 @@ cfs_percpt_lock_free(struct cfs_percpt_lock *pcl) LASSERT(!pcl->pcl_locked); cfs_percpt_free(pcl->pcl_locks); - LIBCFS_FREE(pcl, sizeof(*pcl)); + kfree(pcl); } EXPORT_SYMBOL(cfs_percpt_lock_free); @@ -58,14 +58,14 @@ cfs_percpt_lock_create(struct cfs_cpt_table *cptab, int i; /* NB: cptab can be NULL, pcl will be for HW CPUs on that case */ - LIBCFS_ALLOC(pcl, sizeof(*pcl)); + pcl = kzalloc(sizeof(*pcl), GFP_NOFS); if (!pcl) return NULL; pcl->pcl_cptab = cptab; pcl->pcl_locks = cfs_percpt_alloc(cptab, sizeof(*lock)); if (!pcl->pcl_locks) { - LIBCFS_FREE(pcl, sizeof(*pcl)); + kfree(pcl); return NULL; } diff --git a/drivers/staging/lustre/lnet/libcfs/libcfs_mem.c b/drivers/staging/lustre/lnet/libcfs/libcfs_mem.c index df93d8f77ea2..7faed94994ea 100644 --- a/drivers/staging/lustre/lnet/libcfs/libcfs_mem.c +++ b/drivers/staging/lustre/lnet/libcfs/libcfs_mem.c @@ -49,13 +49,10 @@ cfs_percpt_free(void *vars) arr = container_of(vars, struct cfs_var_array, va_ptrs[0]); - for (i = 0; i < arr->va_count; i++) { - if (arr->va_ptrs[i]) - LIBCFS_FREE(arr->va_ptrs[i], arr->va_size); - } + for (i = 0; i < arr->va_count; i++) + kfree(arr->va_ptrs[i]); - LIBCFS_FREE(arr, offsetof(struct cfs_var_array, - va_ptrs[arr->va_count])); + kvfree(arr); } EXPORT_SYMBOL(cfs_percpt_free); @@ -79,7 +76,8 @@ cfs_percpt_alloc(struct cfs_cpt_table *cptab, unsigned int size) count = cfs_cpt_number(cptab); - LIBCFS_ALLOC(arr, offsetof(struct cfs_var_array, va_ptrs[count])); + arr = kvzalloc(offsetof(struct cfs_var_array, va_ptrs[count]), + GFP_KERNEL); if (!arr) return NULL; @@ -89,7 +87,8 @@ cfs_percpt_alloc(struct cfs_cpt_table *cptab, unsigned int size) arr->va_cptab = cptab; for (i = 0; i < count; i++) { - LIBCFS_CPT_ALLOC(arr->va_ptrs[i], cptab, i, size); + arr->va_ptrs[i] = kzalloc_node(size, GFP_KERNEL, + cfs_cpt_spread_node(cptab, i)); if (!arr->va_ptrs[i]) { cfs_percpt_free((void *)&arr->va_ptrs[0]); return NULL; @@ -130,10 +129,9 @@ cfs_array_free(void *vars) if (!arr->va_ptrs[i]) continue; - LIBCFS_FREE(arr->va_ptrs[i], arr->va_size); + kvfree(arr->va_ptrs[i]); } - LIBCFS_FREE(arr, offsetof(struct cfs_var_array, - va_ptrs[arr->va_count])); + kvfree(arr); } EXPORT_SYMBOL(cfs_array_free); @@ -148,7 +146,7 @@ cfs_array_alloc(int count, unsigned int size) struct cfs_var_array *arr; int i; - LIBCFS_ALLOC(arr, offsetof(struct cfs_var_array, va_ptrs[count])); + arr = kvmalloc(offsetof(struct cfs_var_array, va_ptrs[count]), GFP_KERNEL); if (!arr) return NULL; @@ -156,7 +154,7 @@ cfs_array_alloc(int count, unsigned int size) arr->va_size = size; for (i = 0; i < count; i++) { - LIBCFS_ALLOC(arr->va_ptrs[i], size); + arr->va_ptrs[i] = kvzalloc(size, GFP_KERNEL); if (!arr->va_ptrs[i]) { cfs_array_free((void *)&arr->va_ptrs[0]); diff --git a/drivers/staging/lustre/lnet/libcfs/libcfs_string.c b/drivers/staging/lustre/lnet/libcfs/libcfs_string.c index bcac5074bf80..442889a3d729 100644 --- a/drivers/staging/lustre/lnet/libcfs/libcfs_string.c +++ b/drivers/staging/lustre/lnet/libcfs/libcfs_string.c @@ -137,26 +137,6 @@ out: } EXPORT_SYMBOL(cfs_firststr); -char * -cfs_trimwhite(char *str) -{ - char *end; - - while (isspace(*str)) - str++; - - end = str + strlen(str); - while (end > str) { - if (!isspace(end[-1])) - break; - end--; - } - - *end = 0; - return str; -} -EXPORT_SYMBOL(cfs_trimwhite); - /** * Extracts tokens from strings. * @@ -280,7 +260,7 @@ cfs_range_expr_parse(struct cfs_lstr *src, unsigned int min, unsigned int max, struct cfs_range_expr *re; struct cfs_lstr tok; - LIBCFS_ALLOC(re, sizeof(*re)); + re = kzalloc(sizeof(*re), GFP_NOFS); if (!re) return -ENOMEM; @@ -333,7 +313,7 @@ cfs_range_expr_parse(struct cfs_lstr *src, unsigned int min, unsigned int max, return 0; failed: - LIBCFS_FREE(re, sizeof(*re)); + kfree(re); return -EINVAL; } @@ -457,7 +437,7 @@ cfs_expr_list_values(struct cfs_expr_list *expr_list, int max, u32 **valpp) return -EINVAL; } - LIBCFS_ALLOC(val, sizeof(val[0]) * count); + val = kvmalloc_array(count, sizeof(val[0]), GFP_KERNEL | __GFP_ZERO); if (!val) return -ENOMEM; @@ -488,10 +468,10 @@ cfs_expr_list_free(struct cfs_expr_list *expr_list) expr = list_entry(expr_list->el_exprs.next, struct cfs_range_expr, re_link); list_del(&expr->re_link); - LIBCFS_FREE(expr, sizeof(*expr)); + kfree(expr); } - LIBCFS_FREE(expr_list, sizeof(*expr_list)); + kfree(expr_list); } EXPORT_SYMBOL(cfs_expr_list_free); @@ -510,7 +490,7 @@ cfs_expr_list_parse(char *str, int len, unsigned int min, unsigned int max, struct cfs_lstr src; int rc; - LIBCFS_ALLOC(expr_list, sizeof(*expr_list)); + expr_list = kzalloc(sizeof(*expr_list), GFP_NOFS); if (!expr_list) return -ENOMEM; diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-cpu.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-cpu.c index 51823ce71773..c07165e0ad95 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-cpu.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-cpu.c @@ -72,7 +72,7 @@ struct cfs_cpt_data { /* mutex to protect cpt_cpumask */ struct mutex cpt_mutex; /* scratch buffer for set/unset_node */ - cpumask_t *cpt_cpumask; + cpumask_var_t cpt_cpumask; }; static struct cfs_cpt_data cpt_data; @@ -93,35 +93,21 @@ cfs_cpt_table_free(struct cfs_cpt_table *cptab) { int i; - if (cptab->ctb_cpu2cpt) { - LIBCFS_FREE(cptab->ctb_cpu2cpt, - num_possible_cpus() * - sizeof(cptab->ctb_cpu2cpt[0])); - } + kvfree(cptab->ctb_cpu2cpt); for (i = 0; cptab->ctb_parts && i < cptab->ctb_nparts; i++) { struct cfs_cpu_partition *part = &cptab->ctb_parts[i]; - if (part->cpt_nodemask) { - LIBCFS_FREE(part->cpt_nodemask, - sizeof(*part->cpt_nodemask)); - } - - if (part->cpt_cpumask) - LIBCFS_FREE(part->cpt_cpumask, cpumask_size()); + kfree(part->cpt_nodemask); + free_cpumask_var(part->cpt_cpumask); } - if (cptab->ctb_parts) { - LIBCFS_FREE(cptab->ctb_parts, - cptab->ctb_nparts * sizeof(cptab->ctb_parts[0])); - } + kvfree(cptab->ctb_parts); - if (cptab->ctb_nodemask) - LIBCFS_FREE(cptab->ctb_nodemask, sizeof(*cptab->ctb_nodemask)); - if (cptab->ctb_cpumask) - LIBCFS_FREE(cptab->ctb_cpumask, cpumask_size()); + kfree(cptab->ctb_nodemask); + free_cpumask_var(cptab->ctb_cpumask); - LIBCFS_FREE(cptab, sizeof(*cptab)); + kfree(cptab); } EXPORT_SYMBOL(cfs_cpt_table_free); @@ -131,36 +117,39 @@ cfs_cpt_table_alloc(unsigned int ncpt) struct cfs_cpt_table *cptab; int i; - LIBCFS_ALLOC(cptab, sizeof(*cptab)); + cptab = kzalloc(sizeof(*cptab), GFP_NOFS); if (!cptab) return NULL; cptab->ctb_nparts = ncpt; - LIBCFS_ALLOC(cptab->ctb_cpumask, cpumask_size()); - LIBCFS_ALLOC(cptab->ctb_nodemask, sizeof(*cptab->ctb_nodemask)); - - if (!cptab->ctb_cpumask || !cptab->ctb_nodemask) + cptab->ctb_nodemask = kzalloc(sizeof(*cptab->ctb_nodemask), + GFP_NOFS); + if (!zalloc_cpumask_var(&cptab->ctb_cpumask, GFP_NOFS) || + !cptab->ctb_nodemask) goto failed; - LIBCFS_ALLOC(cptab->ctb_cpu2cpt, - num_possible_cpus() * sizeof(cptab->ctb_cpu2cpt[0])); + cptab->ctb_cpu2cpt = kvmalloc_array(num_possible_cpus(), + sizeof(cptab->ctb_cpu2cpt[0]), + GFP_KERNEL); if (!cptab->ctb_cpu2cpt) goto failed; memset(cptab->ctb_cpu2cpt, -1, num_possible_cpus() * sizeof(cptab->ctb_cpu2cpt[0])); - LIBCFS_ALLOC(cptab->ctb_parts, ncpt * sizeof(cptab->ctb_parts[0])); + cptab->ctb_parts = kvmalloc_array(ncpt, sizeof(cptab->ctb_parts[0]), + GFP_KERNEL); if (!cptab->ctb_parts) goto failed; for (i = 0; i < ncpt; i++) { struct cfs_cpu_partition *part = &cptab->ctb_parts[i]; - LIBCFS_ALLOC(part->cpt_cpumask, cpumask_size()); - LIBCFS_ALLOC(part->cpt_nodemask, sizeof(*part->cpt_nodemask)); - if (!part->cpt_cpumask || !part->cpt_nodemask) + part->cpt_nodemask = kzalloc(sizeof(*part->cpt_nodemask), + GFP_NOFS); + if (!zalloc_cpumask_var(&part->cpt_cpumask, GFP_NOFS) || + !part->cpt_nodemask) goto failed; } @@ -251,13 +240,13 @@ cfs_cpt_online(struct cfs_cpt_table *cptab, int cpt) } EXPORT_SYMBOL(cfs_cpt_online); -cpumask_t * +cpumask_var_t * cfs_cpt_cpumask(struct cfs_cpt_table *cptab, int cpt) { LASSERT(cpt == CFS_CPT_ANY || (cpt >= 0 && cpt < cptab->ctb_nparts)); return cpt == CFS_CPT_ANY ? - cptab->ctb_cpumask : cptab->ctb_parts[cpt].cpt_cpumask; + &cptab->ctb_cpumask : &cptab->ctb_parts[cpt].cpt_cpumask; } EXPORT_SYMBOL(cfs_cpt_cpumask); @@ -405,7 +394,6 @@ EXPORT_SYMBOL(cfs_cpt_unset_cpumask); int cfs_cpt_set_node(struct cfs_cpt_table *cptab, int cpt, int node) { - cpumask_t *mask; int rc; if (node < 0 || node >= MAX_NUMNODES) { @@ -416,10 +404,9 @@ cfs_cpt_set_node(struct cfs_cpt_table *cptab, int cpt, int node) mutex_lock(&cpt_data.cpt_mutex); - mask = cpt_data.cpt_cpumask; - cfs_node_to_cpumask(node, mask); + cfs_node_to_cpumask(node, cpt_data.cpt_cpumask); - rc = cfs_cpt_set_cpumask(cptab, cpt, mask); + rc = cfs_cpt_set_cpumask(cptab, cpt, cpt_data.cpt_cpumask); mutex_unlock(&cpt_data.cpt_mutex); @@ -430,8 +417,6 @@ EXPORT_SYMBOL(cfs_cpt_set_node); void cfs_cpt_unset_node(struct cfs_cpt_table *cptab, int cpt, int node) { - cpumask_t *mask; - if (node < 0 || node >= MAX_NUMNODES) { CDEBUG(D_INFO, "Invalid NUMA id %d for CPU partition %d\n", node, cpt); @@ -440,10 +425,9 @@ cfs_cpt_unset_node(struct cfs_cpt_table *cptab, int cpt, int node) mutex_lock(&cpt_data.cpt_mutex); - mask = cpt_data.cpt_cpumask; - cfs_node_to_cpumask(node, mask); + cfs_node_to_cpumask(node, cpt_data.cpt_cpumask); - cfs_cpt_unset_cpumask(cptab, cpt, mask); + cfs_cpt_unset_cpumask(cptab, cpt, cpt_data.cpt_cpumask); mutex_unlock(&cpt_data.cpt_mutex); } @@ -529,19 +513,20 @@ EXPORT_SYMBOL(cfs_cpt_spread_node); int cfs_cpt_current(struct cfs_cpt_table *cptab, int remap) { - int cpu = smp_processor_id(); - int cpt = cptab->ctb_cpu2cpt[cpu]; + int cpu; + int cpt; - if (cpt < 0) { - if (!remap) - return cpt; + preempt_disable(); + cpu = smp_processor_id(); + cpt = cptab->ctb_cpu2cpt[cpu]; + if (cpt < 0 && remap) { /* don't return negative value for safety of upper layer, * instead we shadow the unknown cpu to a valid partition ID */ cpt = cpu % cptab->ctb_nparts; } - + preempt_enable(); return cpt; } EXPORT_SYMBOL(cfs_cpt_current); @@ -558,7 +543,7 @@ EXPORT_SYMBOL(cfs_cpt_of_cpu); int cfs_cpt_bind(struct cfs_cpt_table *cptab, int cpt) { - cpumask_t *cpumask; + cpumask_var_t *cpumask; nodemask_t *nodemask; int rc; int i; @@ -566,24 +551,24 @@ cfs_cpt_bind(struct cfs_cpt_table *cptab, int cpt) LASSERT(cpt == CFS_CPT_ANY || (cpt >= 0 && cpt < cptab->ctb_nparts)); if (cpt == CFS_CPT_ANY) { - cpumask = cptab->ctb_cpumask; + cpumask = &cptab->ctb_cpumask; nodemask = cptab->ctb_nodemask; } else { - cpumask = cptab->ctb_parts[cpt].cpt_cpumask; + cpumask = &cptab->ctb_parts[cpt].cpt_cpumask; nodemask = cptab->ctb_parts[cpt].cpt_nodemask; } - if (cpumask_any_and(cpumask, cpu_online_mask) >= nr_cpu_ids) { + if (cpumask_any_and(*cpumask, cpu_online_mask) >= nr_cpu_ids) { CERROR("No online CPU found in CPU partition %d, did someone do CPU hotplug on system? You might need to reload Lustre modules to keep system working well.\n", cpt); return -EINVAL; } for_each_online_cpu(i) { - if (cpumask_test_cpu(i, cpumask)) + if (cpumask_test_cpu(i, *cpumask)) continue; - rc = set_cpus_allowed_ptr(current, cpumask); + rc = set_cpus_allowed_ptr(current, *cpumask); set_mems_allowed(*nodemask); if (!rc) schedule(); /* switch to allowed CPU */ @@ -604,8 +589,8 @@ static int cfs_cpt_choose_ncpus(struct cfs_cpt_table *cptab, int cpt, cpumask_t *node, int number) { - cpumask_t *socket = NULL; - cpumask_t *core = NULL; + cpumask_var_t socket; + cpumask_var_t core; int rc = 0; int cpu; @@ -623,13 +608,17 @@ cfs_cpt_choose_ncpus(struct cfs_cpt_table *cptab, int cpt, return 0; } - /* allocate scratch buffer */ - LIBCFS_ALLOC(socket, cpumask_size()); - LIBCFS_ALLOC(core, cpumask_size()); - if (!socket || !core) { + /* + * Allocate scratch buffers + * As we cannot initialize a cpumask_var_t, we need + * to alloc both before we can risk trying to free either + */ + if (!zalloc_cpumask_var(&socket, GFP_NOFS)) rc = -ENOMEM; + if (!zalloc_cpumask_var(&core, GFP_NOFS)) + rc = -ENOMEM; + if (rc) goto out; - } while (!cpumask_empty(node)) { cpu = cpumask_first(node); @@ -667,10 +656,8 @@ cfs_cpt_choose_ncpus(struct cfs_cpt_table *cptab, int cpt, } out: - if (socket) - LIBCFS_FREE(socket, cpumask_size()); - if (core) - LIBCFS_FREE(core, cpumask_size()); + free_cpumask_var(socket); + free_cpumask_var(core); return rc; } @@ -723,7 +710,7 @@ static struct cfs_cpt_table * cfs_cpt_table_create(int ncpt) { struct cfs_cpt_table *cptab = NULL; - cpumask_t *mask = NULL; + cpumask_var_t mask; int cpt = 0; int num; int rc; @@ -756,8 +743,7 @@ cfs_cpt_table_create(int ncpt) goto failed; } - LIBCFS_ALLOC(mask, cpumask_size()); - if (!mask) { + if (!zalloc_cpumask_var(&mask, GFP_NOFS)){ CERROR("Failed to allocate scratch cpumask\n"); goto failed; } @@ -784,7 +770,7 @@ cfs_cpt_table_create(int ncpt) rc = cfs_cpt_choose_ncpus(cptab, cpt, mask, n); if (rc < 0) - goto failed; + goto failed_mask; LASSERT(num >= cpumask_weight(part->cpt_cpumask)); if (num == cpumask_weight(part->cpt_cpumask)) @@ -797,20 +783,19 @@ cfs_cpt_table_create(int ncpt) CERROR("Expect %d(%d) CPU partitions but got %d(%d), CPU hotplug/unplug while setting?\n", cptab->ctb_nparts, num, cpt, cpumask_weight(cptab->ctb_parts[ncpt - 1].cpt_cpumask)); - goto failed; + goto failed_mask; } - LIBCFS_FREE(mask, cpumask_size()); + free_cpumask_var(mask); return cptab; + failed_mask: + free_cpumask_var(mask); failed: CERROR("Failed to setup CPU-partition-table with %d CPU-partitions, online HW nodes: %d, HW cpus: %d.\n", ncpt, num_online_nodes(), num_online_cpus()); - if (mask) - LIBCFS_FREE(mask, cpumask_size()); - if (cptab) cfs_cpt_table_free(cptab); @@ -830,7 +815,7 @@ cfs_cpt_table_create_pattern(char *pattern) int c; int i; - str = cfs_trimwhite(pattern); + str = strim(pattern); if (*str == 'n' || *str == 'N') { pattern = str + 1; if (*pattern != '\0') { @@ -882,7 +867,7 @@ cfs_cpt_table_create_pattern(char *pattern) high = node ? MAX_NUMNODES - 1 : nr_cpu_ids - 1; - for (str = cfs_trimwhite(pattern), c = 0;; c++) { + for (str = strim(pattern), c = 0;; c++) { struct cfs_range_expr *range; struct cfs_expr_list *el; char *bracket = strchr(str, '['); @@ -917,7 +902,7 @@ cfs_cpt_table_create_pattern(char *pattern) goto failed; } - str = cfs_trimwhite(str + n); + str = strim(str + n); if (str != bracket) { CERROR("Invalid pattern %s\n", str); goto failed; @@ -957,7 +942,7 @@ cfs_cpt_table_create_pattern(char *pattern) goto failed; } - str = cfs_trimwhite(bracket + 1); + str = strim(bracket + 1); } return cptab; @@ -1013,8 +998,7 @@ cfs_cpu_fini(void) cpuhp_remove_state_nocalls(lustre_cpu_online); cpuhp_remove_state_nocalls(CPUHP_LUSTRE_CFS_DEAD); #endif - if (cpt_data.cpt_cpumask) - LIBCFS_FREE(cpt_data.cpt_cpumask, cpumask_size()); + free_cpumask_var(cpt_data.cpt_cpumask); } int @@ -1026,8 +1010,7 @@ cfs_cpu_init(void) memset(&cpt_data, 0, sizeof(cpt_data)); - LIBCFS_ALLOC(cpt_data.cpt_cpumask, cpumask_size()); - if (!cpt_data.cpt_cpumask) { + if (!zalloc_cpumask_var(&cpt_data.cpt_cpumask, GFP_NOFS)) { CERROR("Failed to allocate scratch buffer\n"); return -1; } diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c index b5746230ab31..ddf625669bff 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c @@ -146,7 +146,7 @@ int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp, return -EINVAL; } - LIBCFS_ALLOC(*hdr_pp, hdr.ioc_len); + *hdr_pp = kvmalloc(hdr.ioc_len, GFP_KERNEL); if (!*hdr_pp) return -ENOMEM; @@ -164,7 +164,7 @@ int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp, return 0; free: - LIBCFS_FREE(*hdr_pp, hdr.ioc_len); + kvfree(*hdr_pp); return err; } diff --git a/drivers/staging/lustre/lnet/libcfs/module.c b/drivers/staging/lustre/lnet/libcfs/module.c index 4ead55920e79..a03f924f1d7c 100644 --- a/drivers/staging/lustre/lnet/libcfs/module.c +++ b/drivers/staging/lustre/lnet/libcfs/module.c @@ -156,7 +156,7 @@ int libcfs_ioctl(unsigned long cmd, void __user *uparam) break; } } out: - LIBCFS_FREE(hdr, hdr->ioc_len); + kvfree(hdr); return err; } @@ -302,7 +302,7 @@ static int __proc_cpt_table(void *data, int write, LASSERT(cfs_cpt_table); while (1) { - LIBCFS_ALLOC(buf, len); + buf = kzalloc(len, GFP_KERNEL); if (!buf) return -ENOMEM; @@ -311,7 +311,7 @@ static int __proc_cpt_table(void *data, int write, break; if (rc == -EFBIG) { - LIBCFS_FREE(buf, len); + kfree(buf); len <<= 1; continue; } @@ -325,8 +325,7 @@ static int __proc_cpt_table(void *data, int write, rc = cfs_trace_copyout_string(buffer, nob, buf + pos, NULL); out: - if (buf) - LIBCFS_FREE(buf, len); + kfree(buf); return rc; } @@ -548,33 +547,23 @@ static int libcfs_init(void) goto cleanup_cpu; } - rc = cfs_wi_startup(); - if (rc) { - CERROR("initialize workitem: error %d\n", rc); - goto cleanup_deregister; - } - - /* max to 4 threads, should be enough for rehash */ - rc = min(cfs_cpt_weight(cfs_cpt_table, CFS_CPT_ANY), 4); - rc = cfs_wi_sched_create("cfs_rh", cfs_cpt_table, CFS_CPT_ANY, - rc, &cfs_sched_rehash); - if (rc) { - CERROR("Startup workitem scheduler: error: %d\n", rc); + cfs_rehash_wq = alloc_workqueue("cfs_rh", WQ_SYSFS, 4); + if (!cfs_rehash_wq) { + CERROR("Failed to start rehash workqueue.\n"); + rc = -ENOMEM; goto cleanup_deregister; } rc = cfs_crypto_register(); if (rc) { CERROR("cfs_crypto_register: error %d\n", rc); - goto cleanup_wi; + goto cleanup_deregister; } lustre_insert_debugfs(lnet_table, lnet_debugfs_symlinks); CDEBUG(D_OTHER, "portals setup OK\n"); return 0; - cleanup_wi: - cfs_wi_shutdown(); cleanup_deregister: misc_deregister(&libcfs_dev); cleanup_cpu: @@ -590,13 +579,12 @@ static void libcfs_exit(void) lustre_remove_debugfs(); - if (cfs_sched_rehash) { - cfs_wi_sched_destroy(cfs_sched_rehash); - cfs_sched_rehash = NULL; + if (cfs_rehash_wq) { + destroy_workqueue(cfs_rehash_wq); + cfs_rehash_wq = NULL; } cfs_crypto_unregister(); - cfs_wi_shutdown(); misc_deregister(&libcfs_dev); diff --git a/drivers/staging/lustre/lnet/libcfs/prng.c b/drivers/staging/lustre/lnet/libcfs/prng.c deleted file mode 100644 index f47cf67a92e3..000000000000 --- a/drivers/staging/lustre/lnet/libcfs/prng.c +++ /dev/null @@ -1,137 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.gnu.org/licenses/gpl-2.0.html - * - * GPL HEADER END - */ -/* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - * - * libcfs/libcfs/prng.c - * - * concatenation of following two 16-bit multiply with carry generators - * x(n)=a*x(n-1)+carry mod 2^16 and y(n)=b*y(n-1)+carry mod 2^16, - * number and carry packed within the same 32 bit integer. - * algorithm recommended by Marsaglia - */ - -#include <linux/libcfs/libcfs.h> - -/* - * From: George Marsaglia <geo@stat.fsu.edu> - * Newsgroups: sci.math - * Subject: Re: A RANDOM NUMBER GENERATOR FOR C - * Date: Tue, 30 Sep 1997 05:29:35 -0700 - * - * You may replace the two constants 36969 and 18000 by any - * pair of distinct constants from this list: - * 18000 18030 18273 18513 18879 19074 19098 19164 19215 19584 - * 19599 19950 20088 20508 20544 20664 20814 20970 21153 21243 - * 21423 21723 21954 22125 22188 22293 22860 22938 22965 22974 - * 23109 23124 23163 23208 23508 23520 23553 23658 23865 24114 - * 24219 24660 24699 24864 24948 25023 25308 25443 26004 26088 - * 26154 26550 26679 26838 27183 27258 27753 27795 27810 27834 - * 27960 28320 28380 28689 28710 28794 28854 28959 28980 29013 - * 29379 29889 30135 30345 30459 30714 30903 30963 31059 31083 - * (or any other 16-bit constants k for which both k*2^16-1 - * and k*2^15-1 are prime) - */ - -#define RANDOM_CONST_A 18030 -#define RANDOM_CONST_B 29013 - -static unsigned int seed_x = 521288629; -static unsigned int seed_y = 362436069; - -/** - * cfs_rand - creates new seeds - * - * First it creates new seeds from the previous seeds. Then it generates a - * new pseudo random number for use. - * - * Returns a pseudo-random 32-bit integer - */ -unsigned int cfs_rand(void) -{ - seed_x = RANDOM_CONST_A * (seed_x & 65535) + (seed_x >> 16); - seed_y = RANDOM_CONST_B * (seed_y & 65535) + (seed_y >> 16); - - return ((seed_x << 16) + (seed_y & 65535)); -} -EXPORT_SYMBOL(cfs_rand); - -/** - * cfs_srand - sets the initial seed - * @seed1 : (seed_x) should have the most entropy in the low bits of the word - * @seed2 : (seed_y) should have the most entropy in the high bits of the word - * - * Replaces the original seeds with new values. Used to generate a new pseudo - * random numbers. - */ -void cfs_srand(unsigned int seed1, unsigned int seed2) -{ - if (seed1) - seed_x = seed1; /* use default seeds if parameter is 0 */ - if (seed2) - seed_y = seed2; -} -EXPORT_SYMBOL(cfs_srand); - -/** - * cfs_get_random_bytes - generate a bunch of random numbers - * @buf : buffer to fill with random numbers - * @size: size of passed in buffer - * - * Fills a buffer with random bytes - */ -void cfs_get_random_bytes(void *buf, int size) -{ - int *p = buf; - int rem, tmp; - - LASSERT(size >= 0); - - rem = min((int)((unsigned long)buf & (sizeof(int) - 1)), size); - if (rem) { - get_random_bytes(&tmp, sizeof(tmp)); - tmp ^= cfs_rand(); - memcpy(buf, &tmp, rem); - p = buf + rem; - size -= rem; - } - - while (size >= sizeof(int)) { - get_random_bytes(&tmp, sizeof(tmp)); - *p = cfs_rand() ^ tmp; - size -= sizeof(int); - p++; - } - buf = p; - if (size) { - get_random_bytes(&tmp, sizeof(tmp)); - tmp ^= cfs_rand(); - memcpy(buf, &tmp, size); - } -} -EXPORT_SYMBOL(cfs_get_random_bytes); diff --git a/drivers/staging/lustre/lnet/libcfs/tracefile.c b/drivers/staging/lustre/lnet/libcfs/tracefile.c index da2844f37edf..57913aae1d88 100644 --- a/drivers/staging/lustre/lnet/libcfs/tracefile.c +++ b/drivers/staging/lustre/lnet/libcfs/tracefile.c @@ -785,7 +785,7 @@ int cfs_trace_copyin_string(char *knl_buffer, int knl_buffer_nob, return -EFAULT; nob = strnlen(knl_buffer, usr_buffer_nob); - while (nob-- >= 0) /* strip trailing whitespace */ + while (--nob >= 0) /* strip trailing whitespace */ if (!isspace(knl_buffer[nob])) break; diff --git a/drivers/staging/lustre/lnet/libcfs/workitem.c b/drivers/staging/lustre/lnet/libcfs/workitem.c deleted file mode 100644 index 6a05d9bab8dc..000000000000 --- a/drivers/staging/lustre/lnet/libcfs/workitem.c +++ /dev/null @@ -1,466 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.gnu.org/licenses/gpl-2.0.html - * - * GPL HEADER END - */ -/* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - * - * Copyright (c) 2011, 2012, Intel Corporation. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - * - * libcfs/libcfs/workitem.c - * - * Author: Isaac Huang <isaac@clusterfs.com> - * Liang Zhen <zhen.liang@sun.com> - */ - -#define DEBUG_SUBSYSTEM S_LNET - -#include <linux/libcfs/libcfs.h> - -#define CFS_WS_NAME_LEN 16 - -struct cfs_wi_sched { - /* chain on global list */ - struct list_head ws_list; - /** serialised workitems */ - spinlock_t ws_lock; - /** where schedulers sleep */ - wait_queue_head_t ws_waitq; - /** concurrent workitems */ - struct list_head ws_runq; - /** - * rescheduled running-workitems, a workitem can be rescheduled - * while running in wi_action(), but we don't to execute it again - * unless it returns from wi_action(), so we put it on ws_rerunq - * while rescheduling, and move it to runq after it returns - * from wi_action() - */ - struct list_head ws_rerunq; - /** CPT-table for this scheduler */ - struct cfs_cpt_table *ws_cptab; - /** CPT id for affinity */ - int ws_cpt; - /** number of scheduled workitems */ - int ws_nscheduled; - /** started scheduler thread, protected by cfs_wi_data::wi_glock */ - unsigned int ws_nthreads:30; - /** shutting down, protected by cfs_wi_data::wi_glock */ - unsigned int ws_stopping:1; - /** serialize starting thread, protected by cfs_wi_data::wi_glock */ - unsigned int ws_starting:1; - /** scheduler name */ - char ws_name[CFS_WS_NAME_LEN]; -}; - -static struct cfs_workitem_data { - /** serialize */ - spinlock_t wi_glock; - /** list of all schedulers */ - struct list_head wi_scheds; - /** WI module is initialized */ - int wi_init; - /** shutting down the whole WI module */ - int wi_stopping; -} cfs_wi_data; - -static inline int -cfs_wi_sched_cansleep(struct cfs_wi_sched *sched) -{ - spin_lock(&sched->ws_lock); - if (sched->ws_stopping) { - spin_unlock(&sched->ws_lock); - return 0; - } - - if (!list_empty(&sched->ws_runq)) { - spin_unlock(&sched->ws_lock); - return 0; - } - spin_unlock(&sched->ws_lock); - return 1; -} - -/* XXX: - * 0. it only works when called from wi->wi_action. - * 1. when it returns no one shall try to schedule the workitem. - */ -void -cfs_wi_exit(struct cfs_wi_sched *sched, struct cfs_workitem *wi) -{ - LASSERT(!in_interrupt()); /* because we use plain spinlock */ - LASSERT(!sched->ws_stopping); - - spin_lock(&sched->ws_lock); - - LASSERT(wi->wi_running); - if (wi->wi_scheduled) { /* cancel pending schedules */ - LASSERT(!list_empty(&wi->wi_list)); - list_del_init(&wi->wi_list); - - LASSERT(sched->ws_nscheduled > 0); - sched->ws_nscheduled--; - } - - LASSERT(list_empty(&wi->wi_list)); - - wi->wi_scheduled = 1; /* LBUG future schedule attempts */ - spin_unlock(&sched->ws_lock); -} -EXPORT_SYMBOL(cfs_wi_exit); - -/** - * cancel schedule request of workitem \a wi - */ -int -cfs_wi_deschedule(struct cfs_wi_sched *sched, struct cfs_workitem *wi) -{ - int rc; - - LASSERT(!in_interrupt()); /* because we use plain spinlock */ - LASSERT(!sched->ws_stopping); - - /* - * return 0 if it's running already, otherwise return 1, which - * means the workitem will not be scheduled and will not have - * any race with wi_action. - */ - spin_lock(&sched->ws_lock); - - rc = !(wi->wi_running); - - if (wi->wi_scheduled) { /* cancel pending schedules */ - LASSERT(!list_empty(&wi->wi_list)); - list_del_init(&wi->wi_list); - - LASSERT(sched->ws_nscheduled > 0); - sched->ws_nscheduled--; - - wi->wi_scheduled = 0; - } - - LASSERT(list_empty(&wi->wi_list)); - - spin_unlock(&sched->ws_lock); - return rc; -} -EXPORT_SYMBOL(cfs_wi_deschedule); - -/* - * Workitem scheduled with (serial == 1) is strictly serialised not only with - * itself, but also with others scheduled this way. - * - * Now there's only one static serialised queue, but in the future more might - * be added, and even dynamic creation of serialised queues might be supported. - */ -void -cfs_wi_schedule(struct cfs_wi_sched *sched, struct cfs_workitem *wi) -{ - LASSERT(!in_interrupt()); /* because we use plain spinlock */ - LASSERT(!sched->ws_stopping); - - spin_lock(&sched->ws_lock); - - if (!wi->wi_scheduled) { - LASSERT(list_empty(&wi->wi_list)); - - wi->wi_scheduled = 1; - sched->ws_nscheduled++; - if (!wi->wi_running) { - list_add_tail(&wi->wi_list, &sched->ws_runq); - wake_up(&sched->ws_waitq); - } else { - list_add(&wi->wi_list, &sched->ws_rerunq); - } - } - - LASSERT(!list_empty(&wi->wi_list)); - spin_unlock(&sched->ws_lock); -} -EXPORT_SYMBOL(cfs_wi_schedule); - -static int cfs_wi_scheduler(void *arg) -{ - struct cfs_wi_sched *sched = (struct cfs_wi_sched *)arg; - - cfs_block_allsigs(); - - /* CPT affinity scheduler? */ - if (sched->ws_cptab) - if (cfs_cpt_bind(sched->ws_cptab, sched->ws_cpt)) - CWARN("Unable to bind %s on CPU partition %d\n", - sched->ws_name, sched->ws_cpt); - - spin_lock(&cfs_wi_data.wi_glock); - - LASSERT(sched->ws_starting == 1); - sched->ws_starting--; - sched->ws_nthreads++; - - spin_unlock(&cfs_wi_data.wi_glock); - - spin_lock(&sched->ws_lock); - - while (!sched->ws_stopping) { - int nloops = 0; - int rc; - struct cfs_workitem *wi; - - while (!list_empty(&sched->ws_runq) && - nloops < CFS_WI_RESCHED) { - wi = list_entry(sched->ws_runq.next, - struct cfs_workitem, wi_list); - LASSERT(wi->wi_scheduled && !wi->wi_running); - - list_del_init(&wi->wi_list); - - LASSERT(sched->ws_nscheduled > 0); - sched->ws_nscheduled--; - - wi->wi_running = 1; - wi->wi_scheduled = 0; - - spin_unlock(&sched->ws_lock); - nloops++; - - rc = (*wi->wi_action)(wi); - - spin_lock(&sched->ws_lock); - if (rc) /* WI should be dead, even be freed! */ - continue; - - wi->wi_running = 0; - if (list_empty(&wi->wi_list)) - continue; - - LASSERT(wi->wi_scheduled); - /* wi is rescheduled, should be on rerunq now, we - * move it to runq so it can run action now - */ - list_move_tail(&wi->wi_list, &sched->ws_runq); - } - - if (!list_empty(&sched->ws_runq)) { - spin_unlock(&sched->ws_lock); - /* don't sleep because some workitems still - * expect me to come back soon - */ - cond_resched(); - spin_lock(&sched->ws_lock); - continue; - } - - spin_unlock(&sched->ws_lock); - rc = wait_event_interruptible_exclusive(sched->ws_waitq, - !cfs_wi_sched_cansleep(sched)); - spin_lock(&sched->ws_lock); - } - - spin_unlock(&sched->ws_lock); - - spin_lock(&cfs_wi_data.wi_glock); - sched->ws_nthreads--; - spin_unlock(&cfs_wi_data.wi_glock); - - return 0; -} - -void -cfs_wi_sched_destroy(struct cfs_wi_sched *sched) -{ - int i; - - LASSERT(cfs_wi_data.wi_init); - LASSERT(!cfs_wi_data.wi_stopping); - - spin_lock(&cfs_wi_data.wi_glock); - if (sched->ws_stopping) { - CDEBUG(D_INFO, "%s is in progress of stopping\n", - sched->ws_name); - spin_unlock(&cfs_wi_data.wi_glock); - return; - } - - LASSERT(!list_empty(&sched->ws_list)); - sched->ws_stopping = 1; - - spin_unlock(&cfs_wi_data.wi_glock); - - i = 2; - wake_up_all(&sched->ws_waitq); - - spin_lock(&cfs_wi_data.wi_glock); - while (sched->ws_nthreads > 0) { - CDEBUG(is_power_of_2(++i) ? D_WARNING : D_NET, - "waiting for %d threads of WI sched[%s] to terminate\n", - sched->ws_nthreads, sched->ws_name); - - spin_unlock(&cfs_wi_data.wi_glock); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(cfs_time_seconds(1) / 20); - spin_lock(&cfs_wi_data.wi_glock); - } - - list_del(&sched->ws_list); - - spin_unlock(&cfs_wi_data.wi_glock); - LASSERT(!sched->ws_nscheduled); - - LIBCFS_FREE(sched, sizeof(*sched)); -} -EXPORT_SYMBOL(cfs_wi_sched_destroy); - -int -cfs_wi_sched_create(char *name, struct cfs_cpt_table *cptab, - int cpt, int nthrs, struct cfs_wi_sched **sched_pp) -{ - struct cfs_wi_sched *sched; - int rc; - - LASSERT(cfs_wi_data.wi_init); - LASSERT(!cfs_wi_data.wi_stopping); - LASSERT(!cptab || cpt == CFS_CPT_ANY || - (cpt >= 0 && cpt < cfs_cpt_number(cptab))); - - LIBCFS_ALLOC(sched, sizeof(*sched)); - if (!sched) - return -ENOMEM; - - if (strlen(name) > sizeof(sched->ws_name) - 1) { - LIBCFS_FREE(sched, sizeof(*sched)); - return -E2BIG; - } - strncpy(sched->ws_name, name, sizeof(sched->ws_name)); - - sched->ws_cptab = cptab; - sched->ws_cpt = cpt; - - spin_lock_init(&sched->ws_lock); - init_waitqueue_head(&sched->ws_waitq); - INIT_LIST_HEAD(&sched->ws_runq); - INIT_LIST_HEAD(&sched->ws_rerunq); - INIT_LIST_HEAD(&sched->ws_list); - - rc = 0; - while (nthrs > 0) { - char name[16]; - struct task_struct *task; - - spin_lock(&cfs_wi_data.wi_glock); - while (sched->ws_starting > 0) { - spin_unlock(&cfs_wi_data.wi_glock); - schedule(); - spin_lock(&cfs_wi_data.wi_glock); - } - - sched->ws_starting++; - spin_unlock(&cfs_wi_data.wi_glock); - - if (sched->ws_cptab && sched->ws_cpt >= 0) { - snprintf(name, sizeof(name), "%s_%02d_%02u", - sched->ws_name, sched->ws_cpt, - sched->ws_nthreads); - } else { - snprintf(name, sizeof(name), "%s_%02u", - sched->ws_name, sched->ws_nthreads); - } - - task = kthread_run(cfs_wi_scheduler, sched, "%s", name); - if (!IS_ERR(task)) { - nthrs--; - continue; - } - rc = PTR_ERR(task); - - CERROR("Failed to create thread for WI scheduler %s: %d\n", - name, rc); - - spin_lock(&cfs_wi_data.wi_glock); - - /* make up for cfs_wi_sched_destroy */ - list_add(&sched->ws_list, &cfs_wi_data.wi_scheds); - sched->ws_starting--; - - spin_unlock(&cfs_wi_data.wi_glock); - - cfs_wi_sched_destroy(sched); - return rc; - } - spin_lock(&cfs_wi_data.wi_glock); - list_add(&sched->ws_list, &cfs_wi_data.wi_scheds); - spin_unlock(&cfs_wi_data.wi_glock); - - *sched_pp = sched; - return 0; -} -EXPORT_SYMBOL(cfs_wi_sched_create); - -int -cfs_wi_startup(void) -{ - memset(&cfs_wi_data, 0, sizeof(cfs_wi_data)); - - spin_lock_init(&cfs_wi_data.wi_glock); - INIT_LIST_HEAD(&cfs_wi_data.wi_scheds); - cfs_wi_data.wi_init = 1; - - return 0; -} - -void -cfs_wi_shutdown(void) -{ - struct cfs_wi_sched *sched; - struct cfs_wi_sched *temp; - - spin_lock(&cfs_wi_data.wi_glock); - cfs_wi_data.wi_stopping = 1; - spin_unlock(&cfs_wi_data.wi_glock); - - /* nobody should contend on this list */ - list_for_each_entry(sched, &cfs_wi_data.wi_scheds, ws_list) { - sched->ws_stopping = 1; - wake_up_all(&sched->ws_waitq); - } - - list_for_each_entry(sched, &cfs_wi_data.wi_scheds, ws_list) { - spin_lock(&cfs_wi_data.wi_glock); - - while (sched->ws_nthreads) { - spin_unlock(&cfs_wi_data.wi_glock); - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(cfs_time_seconds(1) / 20); - spin_lock(&cfs_wi_data.wi_glock); - } - spin_unlock(&cfs_wi_data.wi_glock); - } - list_for_each_entry_safe(sched, temp, &cfs_wi_data.wi_scheds, ws_list) { - list_del(&sched->ws_list); - LIBCFS_FREE(sched, sizeof(*sched)); - } - - cfs_wi_data.wi_stopping = 0; - cfs_wi_data.wi_init = 0; -} diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c index 7caff290c146..2c7abad57104 100644 --- a/drivers/staging/lustre/lnet/lnet/api-ni.c +++ b/drivers/staging/lustre/lnet/lnet/api-ni.c @@ -108,7 +108,8 @@ lnet_create_remote_nets_table(void) LASSERT(!the_lnet.ln_remote_nets_hash); LASSERT(the_lnet.ln_remote_nets_hbits > 0); - LIBCFS_ALLOC(hash, LNET_REMOTE_NETS_HASH_SIZE * sizeof(*hash)); + hash = kvmalloc_array(LNET_REMOTE_NETS_HASH_SIZE, sizeof(*hash), + GFP_KERNEL); if (!hash) { CERROR("Failed to create remote nets hash table\n"); return -ENOMEM; @@ -131,9 +132,7 @@ lnet_destroy_remote_nets_table(void) for (i = 0; i < LNET_REMOTE_NETS_HASH_SIZE; i++) LASSERT(list_empty(&the_lnet.ln_remote_nets_hash[i])); - LIBCFS_FREE(the_lnet.ln_remote_nets_hash, - LNET_REMOTE_NETS_HASH_SIZE * - sizeof(the_lnet.ln_remote_nets_hash[0])); + kvfree(the_lnet.ln_remote_nets_hash); the_lnet.ln_remote_nets_hash = NULL; } @@ -384,10 +383,10 @@ lnet_res_container_cleanup(struct lnet_res_container *rec) list_del_init(e); if (rec->rec_type == LNET_COOKIE_TYPE_EQ) { - lnet_eq_free(list_entry(e, struct lnet_eq, eq_list)); + kfree(list_entry(e, struct lnet_eq, eq_list)); } else if (rec->rec_type == LNET_COOKIE_TYPE_MD) { - lnet_md_free(list_entry(e, struct lnet_libmd, md_list)); + kfree(list_entry(e, struct lnet_libmd, md_list)); } else { /* NB: Active MEs should be attached on portals */ LBUG(); @@ -405,11 +404,8 @@ lnet_res_container_cleanup(struct lnet_res_container *rec) count, lnet_res_type2str(rec->rec_type)); } - if (rec->rec_lh_hash) { - LIBCFS_FREE(rec->rec_lh_hash, - LNET_LH_HASH_SIZE * sizeof(rec->rec_lh_hash[0])); - rec->rec_lh_hash = NULL; - } + kfree(rec->rec_lh_hash); + rec->rec_lh_hash = NULL; rec->rec_type = 0; /* mark it as finalized */ } @@ -427,8 +423,8 @@ lnet_res_container_setup(struct lnet_res_container *rec, int cpt, int type) rec->rec_lh_cookie = (cpt << LNET_COOKIE_TYPE_BITS) | type; /* Arbitrary choice of hash table size */ - LIBCFS_CPT_ALLOC(rec->rec_lh_hash, lnet_cpt_table(), cpt, - LNET_LH_HASH_SIZE * sizeof(rec->rec_lh_hash[0])); + rec->rec_lh_hash = kvmalloc_cpt(LNET_LH_HASH_SIZE * sizeof(rec->rec_lh_hash[0]), + GFP_KERNEL, cpt); if (!rec->rec_lh_hash) { rc = -ENOMEM; goto out; @@ -831,7 +827,7 @@ lnet_ping_info_create(int num_ni) unsigned int infosz; infosz = offsetof(struct lnet_ping_info, pi_ni[num_ni]); - LIBCFS_ALLOC(ping_info, infosz); + ping_info = kvzalloc(infosz, GFP_KERNEL); if (!ping_info) { CERROR("Can't allocate ping info[%d]\n", num_ni); return NULL; @@ -864,9 +860,7 @@ lnet_get_ni_count(void) static inline void lnet_ping_info_free(struct lnet_ping_info *pinfo) { - LIBCFS_FREE(pinfo, - offsetof(struct lnet_ping_info, - pi_ni[pinfo->pi_nnis])); + kvfree(pinfo); } static void @@ -1280,8 +1274,8 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf) lnd_tunables = (struct lnet_ioctl_config_lnd_tunables *)conf->cfg_bulk; if (lnd_tunables) { - LIBCFS_ALLOC(ni->ni_lnd_tunables, - sizeof(*ni->ni_lnd_tunables)); + ni->ni_lnd_tunables = kzalloc(sizeof(*ni->ni_lnd_tunables), + GFP_NOFS); if (!ni->ni_lnd_tunables) { mutex_unlock(&the_lnet.ln_lnd_mutex); rc = -ENOMEM; @@ -2160,7 +2154,7 @@ static int lnet_ping(struct lnet_process_id id, int timeout_ms, if (id.pid == LNET_PID_ANY) id.pid = LNET_PID_LUSTRE; - LIBCFS_ALLOC(info, infosz); + info = kzalloc(infosz, GFP_KERNEL); if (!info) return -ENOMEM; @@ -2310,6 +2304,6 @@ static int lnet_ping(struct lnet_process_id id, int timeout_ms, LASSERT(!rc2); out_0: - LIBCFS_FREE(info, infosz); + kfree(info); return rc; } diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index 0cf0f4f99435..0aea268a4f1c 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -106,19 +106,16 @@ lnet_ni_free(struct lnet_ni *ni) if (ni->ni_cpts) cfs_expr_list_values_free(ni->ni_cpts, ni->ni_ncpts); - if (ni->ni_lnd_tunables) - LIBCFS_FREE(ni->ni_lnd_tunables, sizeof(*ni->ni_lnd_tunables)); + kfree(ni->ni_lnd_tunables); - for (i = 0; i < LNET_MAX_INTERFACES && ni->ni_interfaces[i]; i++) { - LIBCFS_FREE(ni->ni_interfaces[i], - strlen(ni->ni_interfaces[i]) + 1); - } + for (i = 0; i < LNET_MAX_INTERFACES && ni->ni_interfaces[i]; i++) + kfree(ni->ni_interfaces[i]); /* release reference to net namespace */ if (ni->ni_net_ns) put_net(ni->ni_net_ns); - LIBCFS_FREE(ni, sizeof(*ni)); + kfree(ni); } struct lnet_ni * @@ -135,7 +132,7 @@ lnet_ni_alloc(__u32 net, struct cfs_expr_list *el, struct list_head *nilist) return NULL; } - LIBCFS_ALLOC(ni, sizeof(*ni)); + ni = kzalloc(sizeof(*ni), GFP_NOFS); if (!ni) { CERROR("Out of memory creating network %s\n", libcfs_net2str(net)); @@ -170,7 +167,7 @@ lnet_ni_alloc(__u32 net, struct cfs_expr_list *el, struct list_head *nilist) LASSERT(rc <= LNET_CPT_NUMBER); if (rc == LNET_CPT_NUMBER) { - LIBCFS_FREE(ni->ni_cpts, rc * sizeof(ni->ni_cpts[0])); + cfs_expr_list_values_free(ni->ni_cpts, LNET_CPT_NUMBER); ni->ni_cpts = NULL; } @@ -198,7 +195,6 @@ int lnet_parse_networks(struct list_head *nilist, char *networks) { struct cfs_expr_list *el = NULL; - int tokensize; char *tokens; char *str; char *tmp; @@ -219,15 +215,12 @@ lnet_parse_networks(struct list_head *nilist, char *networks) return -EINVAL; } - tokensize = strlen(networks) + 1; - - LIBCFS_ALLOC(tokens, tokensize); + tokens = kstrdup(networks, GFP_KERNEL); if (!tokens) { CERROR("Can't allocate net tokens\n"); return -ENOMEM; } - memcpy(tokens, networks, tokensize); tmp = tokens; str = tokens; @@ -275,7 +268,7 @@ lnet_parse_networks(struct list_head *nilist, char *networks) if (comma) *comma++ = 0; - net = libcfs_str2net(cfs_trimwhite(str)); + net = libcfs_str2net(strim(str)); if (net == LNET_NIDNET(LNET_NID_ANY)) { LCONSOLE_ERROR_MSG(0x113, @@ -298,7 +291,7 @@ lnet_parse_networks(struct list_head *nilist, char *networks) } *bracket = 0; - net = libcfs_str2net(cfs_trimwhite(str)); + net = libcfs_str2net(strim(str)); if (net == LNET_NIDNET(LNET_NID_ANY)) { tmp = str; goto failed_syntax; @@ -328,7 +321,7 @@ lnet_parse_networks(struct list_head *nilist, char *networks) if (comma) *comma++ = 0; - iface = cfs_trimwhite(iface); + iface = strim(iface); if (!*iface) { tmp = iface; goto failed_syntax; @@ -349,14 +342,11 @@ lnet_parse_networks(struct list_head *nilist, char *networks) * The newly allocated ni_interfaces[] can be * freed when freeing the NI */ - LIBCFS_ALLOC(ni->ni_interfaces[niface], - strlen(iface) + 1); + ni->ni_interfaces[niface] = kstrdup(iface, GFP_KERNEL); if (!ni->ni_interfaces[niface]) { CERROR("Can't allocate net interface name\n"); goto failed; } - strncpy(ni->ni_interfaces[niface], iface, - strlen(iface)); niface++; iface = comma; } while (iface); @@ -365,7 +355,7 @@ lnet_parse_networks(struct list_head *nilist, char *networks) comma = strchr(bracket + 1, ','); if (comma) { *comma = 0; - str = cfs_trimwhite(str); + str = strim(str); if (*str) { tmp = str; goto failed_syntax; @@ -374,7 +364,7 @@ lnet_parse_networks(struct list_head *nilist, char *networks) continue; } - str = cfs_trimwhite(str); + str = strim(str); if (*str) { tmp = str; goto failed_syntax; @@ -384,7 +374,7 @@ lnet_parse_networks(struct list_head *nilist, char *networks) list_for_each(temp_node, nilist) nnets++; - LIBCFS_FREE(tokens, tokensize); + kfree(tokens); return nnets; failed_syntax: @@ -400,7 +390,7 @@ lnet_parse_networks(struct list_head *nilist, char *networks) if (el) cfs_expr_list_free(el); - LIBCFS_FREE(tokens, tokensize); + kfree(tokens); return -EINVAL; } @@ -424,7 +414,7 @@ lnet_new_text_buf(int str_len) return NULL; } - LIBCFS_ALLOC(ltb, nob); + ltb = kzalloc(nob, GFP_KERNEL); if (!ltb) return NULL; @@ -438,7 +428,7 @@ static void lnet_free_text_buf(struct lnet_text_buf *ltb) { lnet_tbnob -= ltb->ltb_size; - LIBCFS_FREE(ltb, ltb->ltb_size); + kfree(ltb); } static void @@ -1156,7 +1146,7 @@ lnet_ipaddr_enumerate(__u32 **ipaddrsp) if (nif <= 0) return nif; - LIBCFS_ALLOC(ipaddrs, nif * sizeof(*ipaddrs)); + ipaddrs = kcalloc(nif, sizeof(*ipaddrs), GFP_KERNEL); if (!ipaddrs) { CERROR("Can't allocate ipaddrs[%d]\n", nif); lnet_ipif_free_enumeration(ifnames, nif); @@ -1189,7 +1179,8 @@ lnet_ipaddr_enumerate(__u32 **ipaddrsp) *ipaddrsp = ipaddrs; } else { if (nip > 0) { - LIBCFS_ALLOC(ipaddrs2, nip * sizeof(*ipaddrs2)); + ipaddrs2 = kcalloc(nip, sizeof(*ipaddrs2), + GFP_KERNEL); if (!ipaddrs2) { CERROR("Can't allocate ipaddrs[%d]\n", nip); nip = -ENOMEM; @@ -1200,7 +1191,7 @@ lnet_ipaddr_enumerate(__u32 **ipaddrsp) rc = nip; } } - LIBCFS_FREE(ipaddrs, nip * sizeof(*ipaddrs)); + kfree(ipaddrs); } return nip; } @@ -1226,7 +1217,7 @@ lnet_parse_ip2nets(char **networksp, char *ip2nets) } rc = lnet_match_networks(networksp, ip2nets, ipaddrs, nip); - LIBCFS_FREE(ipaddrs, nip * sizeof(*ipaddrs)); + kfree(ipaddrs); if (rc < 0) { LCONSOLE_ERROR_MSG(0x119, "Error %d parsing ip2nets\n", rc); diff --git a/drivers/staging/lustre/lnet/lnet/lib-eq.c b/drivers/staging/lustre/lnet/lnet/lib-eq.c index daf744277003..a173b69e2f92 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-eq.c +++ b/drivers/staging/lustre/lnet/lnet/lib-eq.c @@ -90,12 +90,13 @@ LNetEQAlloc(unsigned int count, lnet_eq_handler_t callback, if (!count && callback == LNET_EQ_HANDLER_NONE) return -EINVAL; - eq = lnet_eq_alloc(); + eq = kzalloc(sizeof(*eq), GFP_NOFS); if (!eq) return -ENOMEM; if (count) { - LIBCFS_ALLOC(eq->eq_events, count * sizeof(struct lnet_event)); + eq->eq_events = kvmalloc_array(count, sizeof(struct lnet_event), + GFP_KERNEL | __GFP_ZERO); if (!eq->eq_events) goto failed; /* @@ -132,13 +133,12 @@ LNetEQAlloc(unsigned int count, lnet_eq_handler_t callback, return 0; failed: - if (eq->eq_events) - LIBCFS_FREE(eq->eq_events, count * sizeof(struct lnet_event)); + kvfree(eq->eq_events); if (eq->eq_refs) cfs_percpt_free(eq->eq_refs); - lnet_eq_free(eq); + kfree(eq); return -ENOMEM; } EXPORT_SYMBOL(LNetEQAlloc); @@ -197,13 +197,12 @@ LNetEQFree(struct lnet_handle_eq eqh) lnet_res_lh_invalidate(&eq->eq_lh); list_del(&eq->eq_list); - lnet_eq_free(eq); + kfree(eq); out: lnet_eq_wait_unlock(); lnet_res_unlock(LNET_LOCK_EX); - if (events) - LIBCFS_FREE(events, size * sizeof(struct lnet_event)); + kvfree(events); if (refs) cfs_percpt_free(refs); diff --git a/drivers/staging/lustre/lnet/lnet/lib-md.c b/drivers/staging/lustre/lnet/lnet/lib-md.c index ac5b9593d597..8a22514aaf71 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-md.c +++ b/drivers/staging/lustre/lnet/lnet/lib-md.c @@ -81,7 +81,7 @@ lnet_md_unlink(struct lnet_libmd *md) LASSERT(!list_empty(&md->md_list)); list_del_init(&md->md_list); - lnet_md_free(md); + kfree(md); } static int @@ -173,7 +173,7 @@ lnet_md_link(struct lnet_libmd *md, struct lnet_handle_eq eq_handle, int cpt) /* * NB we are passed an allocated, but inactive md. * if we return success, caller may lnet_md_unlink() it. - * otherwise caller may only lnet_md_free() it. + * otherwise caller may only kfree() it. */ /* * This implementation doesn't know how to create START events or @@ -329,7 +329,7 @@ LNetMDAttach(struct lnet_handle_me meh, struct lnet_md umd, out_unlock: lnet_res_unlock(cpt); out_free: - lnet_md_free(md); + kfree(md); return rc; } EXPORT_SYMBOL(LNetMDAttach); @@ -390,7 +390,7 @@ LNetMDBind(struct lnet_md umd, enum lnet_unlink unlink, out_unlock: lnet_res_unlock(cpt); out_free: - lnet_md_free(md); + kfree(md); return rc; } diff --git a/drivers/staging/lustre/lnet/lnet/lib-me.c b/drivers/staging/lustre/lnet/lnet/lib-me.c index dd5d3cf6d3e2..672e37bdd045 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-me.c +++ b/drivers/staging/lustre/lnet/lnet/lib-me.c @@ -90,7 +90,7 @@ LNetMEAttach(unsigned int portal, if (!mtable) /* can't match portal type */ return -EPERM; - me = lnet_me_alloc(); + me = kzalloc(sizeof(*me), GFP_NOFS); if (!me) return -ENOMEM; @@ -157,7 +157,7 @@ LNetMEInsert(struct lnet_handle_me current_meh, if (pos == LNET_INS_LOCAL) return -EPERM; - new_me = lnet_me_alloc(); + new_me = kzalloc(sizeof(*new_me), GFP_NOFS); if (!new_me) return -ENOMEM; @@ -167,7 +167,7 @@ LNetMEInsert(struct lnet_handle_me current_meh, current_me = lnet_handle2me(¤t_meh); if (!current_me) { - lnet_me_free(new_me); + kfree(new_me); lnet_res_unlock(cpt); return -ENOENT; @@ -178,7 +178,7 @@ LNetMEInsert(struct lnet_handle_me current_meh, ptl = the_lnet.ln_portals[current_me->me_portal]; if (lnet_ptl_is_unique(ptl)) { /* nosense to insertion on unique portal */ - lnet_me_free(new_me); + kfree(new_me); lnet_res_unlock(cpt); return -EPERM; } @@ -270,5 +270,5 @@ lnet_me_unlink(struct lnet_me *me) } lnet_res_lh_invalidate(&me->me_lh); - lnet_me_free(me); + kfree(me); } diff --git a/drivers/staging/lustre/lnet/lnet/lib-move.c b/drivers/staging/lustre/lnet/lnet/lib-move.c index 68d16ffec980..c673037dbce4 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-move.c +++ b/drivers/staging/lustre/lnet/lnet/lib-move.c @@ -57,7 +57,7 @@ lnet_fail_nid(lnet_nid_t nid, unsigned int threshold) /* NB: use lnet_net_lock(0) to serialize operations on test peers */ if (threshold) { /* Adding a new entry */ - LIBCFS_ALLOC(tp, sizeof(*tp)); + tp = kzalloc(sizeof(*tp), GFP_NOFS); if (!tp) return -ENOMEM; @@ -90,7 +90,7 @@ lnet_fail_nid(lnet_nid_t nid, unsigned int threshold) list_for_each_entry_safe(tp, temp, &cull, tp_list) { list_del(&tp->tp_list); - LIBCFS_FREE(tp, sizeof(*tp)); + kfree(tp); } return 0; } @@ -149,7 +149,7 @@ fail_peer(lnet_nid_t nid, int outgoing) list_for_each_entry_safe(tp, temp, &cull, tp_list) { list_del(&tp->tp_list); - LIBCFS_FREE(tp, sizeof(*tp)); + kfree(tp); } return fail; @@ -1769,7 +1769,7 @@ lnet_parse(struct lnet_ni *ni, struct lnet_hdr *hdr, lnet_nid_t from_nid, goto drop; } - msg = lnet_msg_alloc(); + msg = kzalloc(sizeof(*msg), GFP_NOFS); if (!msg) { CERROR("%s, src %s: Dropping %s (out of memory)\n", libcfs_nid2str(from_nid), libcfs_nid2str(src_nid), @@ -1777,7 +1777,7 @@ lnet_parse(struct lnet_ni *ni, struct lnet_hdr *hdr, lnet_nid_t from_nid, goto drop; } - /* msg zeroed in lnet_msg_alloc; + /* msg zeroed by kzalloc() * i.e. flags all clear, pointers NULL etc */ msg->msg_type = type; @@ -1812,7 +1812,7 @@ lnet_parse(struct lnet_ni *ni, struct lnet_hdr *hdr, lnet_nid_t from_nid, CERROR("%s, src %s: Dropping %s (error %d looking up sender)\n", libcfs_nid2str(from_nid), libcfs_nid2str(src_nid), lnet_msgtyp2str(type), rc); - lnet_msg_free(msg); + kfree(msg); if (rc == -ESHUTDOWN) /* We are shutting down. Don't do anything more */ return 0; @@ -2010,7 +2010,7 @@ LNetPut(lnet_nid_t self, struct lnet_handle_md mdh, enum lnet_ack_req ack, return -EIO; } - msg = lnet_msg_alloc(); + msg = kzalloc(sizeof(*msg), GFP_NOFS); if (!msg) { CERROR("Dropping PUT to %s: ENOMEM on struct lnet_msg\n", libcfs_id2str(target)); @@ -2031,7 +2031,7 @@ LNetPut(lnet_nid_t self, struct lnet_handle_md mdh, enum lnet_ack_req ack, md->md_me->me_portal); lnet_res_unlock(cpt); - lnet_msg_free(msg); + kfree(msg); return -ENOENT; } @@ -2086,7 +2086,7 @@ lnet_create_reply_msg(struct lnet_ni *ni, struct lnet_msg *getmsg) * CAVEAT EMPTOR: 'getmsg' is the original GET, which is freed when * lnet_finalize() is called on it, so the LND must call this first */ - struct lnet_msg *msg = lnet_msg_alloc(); + struct lnet_msg *msg = kzalloc(sizeof(*msg), GFP_NOFS); struct lnet_libmd *getmd = getmsg->msg_md; struct lnet_process_id peer_id = getmsg->msg_target; int cpt; @@ -2146,8 +2146,7 @@ lnet_create_reply_msg(struct lnet_ni *ni, struct lnet_msg *getmsg) the_lnet.ln_counters[cpt]->drop_length += getmd->md_length; lnet_net_unlock(cpt); - if (msg) - lnet_msg_free(msg); + kfree(msg); return NULL; } @@ -2215,7 +2214,7 @@ LNetGet(lnet_nid_t self, struct lnet_handle_md mdh, return -EIO; } - msg = lnet_msg_alloc(); + msg = kzalloc(sizeof(*msg), GFP_NOFS); if (!msg) { CERROR("Dropping GET to %s: ENOMEM on struct lnet_msg\n", libcfs_id2str(target)); @@ -2236,7 +2235,7 @@ LNetGet(lnet_nid_t self, struct lnet_handle_md mdh, lnet_res_unlock(cpt); - lnet_msg_free(msg); + kfree(msg); return -ENOENT; } diff --git a/drivers/staging/lustre/lnet/lnet/lib-msg.c b/drivers/staging/lustre/lnet/lnet/lib-msg.c index c72ef05b2420..0091273c04b9 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-msg.c +++ b/drivers/staging/lustre/lnet/lnet/lib-msg.c @@ -433,7 +433,7 @@ lnet_complete_msg_locked(struct lnet_msg *msg, int cpt) } lnet_msg_decommit(msg, cpt, status); - lnet_msg_free(msg); + kfree(msg); return 0; } @@ -466,7 +466,7 @@ lnet_finalize(struct lnet_ni *ni, struct lnet_msg *msg, int status) if (!msg->msg_tx_committed && !msg->msg_rx_committed) { /* not committed to network yet */ LASSERT(!msg->msg_onactivelist); - lnet_msg_free(msg); + kfree(msg); return; } @@ -546,19 +546,15 @@ lnet_msg_container_cleanup(struct lnet_msg_container *container) LASSERT(msg->msg_onactivelist); msg->msg_onactivelist = 0; list_del(&msg->msg_activelist); - lnet_msg_free(msg); + kfree(msg); count++; } if (count > 0) CERROR("%d active msg on exit\n", count); - if (container->msc_finalizers) { - LIBCFS_FREE(container->msc_finalizers, - container->msc_nfinalizers * - sizeof(*container->msc_finalizers)); - container->msc_finalizers = NULL; - } + kvfree(container->msc_finalizers); + container->msc_finalizers = NULL; container->msc_init = 0; } @@ -573,9 +569,9 @@ lnet_msg_container_setup(struct lnet_msg_container *container, int cpt) /* number of CPUs */ container->msc_nfinalizers = cfs_cpt_weight(lnet_cpt_table(), cpt); - LIBCFS_CPT_ALLOC(container->msc_finalizers, lnet_cpt_table(), cpt, - container->msc_nfinalizers * - sizeof(*container->msc_finalizers)); + container->msc_finalizers = kvzalloc_cpt(container->msc_nfinalizers * + sizeof(*container->msc_finalizers), + GFP_KERNEL, cpt); if (!container->msc_finalizers) { CERROR("Failed to allocate message finalizers\n"); diff --git a/drivers/staging/lustre/lnet/lnet/lib-ptl.c b/drivers/staging/lustre/lnet/lnet/lib-ptl.c index 8ae93bf6fd1b..471f2f6c86f4 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-ptl.c +++ b/drivers/staging/lustre/lnet/lnet/lib-ptl.c @@ -771,11 +771,11 @@ lnet_ptl_cleanup(struct lnet_portal *ptl) struct lnet_me, me_list); CERROR("Active ME %p on exit\n", me); list_del(&me->me_list); - lnet_me_free(me); + kfree(me); } } /* the extra entry is for MEs with ignore bits */ - LIBCFS_FREE(mhash, sizeof(*mhash) * (LNET_MT_HASH_SIZE + 1)); + kvfree(mhash); } cfs_percpt_free(ptl->ptl_mtables); @@ -803,8 +803,8 @@ lnet_ptl_setup(struct lnet_portal *ptl, int index) spin_lock_init(&ptl->ptl_lock); cfs_percpt_for_each(mtable, i, ptl->ptl_mtables) { /* the extra entry is for MEs with ignore bits */ - LIBCFS_CPT_ALLOC(mhash, lnet_cpt_table(), i, - sizeof(*mhash) * (LNET_MT_HASH_SIZE + 1)); + mhash = kvzalloc_cpt(sizeof(*mhash) * (LNET_MT_HASH_SIZE + 1), + GFP_KERNEL, i); if (!mhash) { CERROR("Failed to create match hash for portal %d\n", index); diff --git a/drivers/staging/lustre/lnet/lnet/lib-socket.c b/drivers/staging/lustre/lnet/lnet/lib-socket.c index ed46aaca0ba3..ce93806eefca 100644 --- a/drivers/staging/lustre/lnet/lnet/lib-socket.c +++ b/drivers/staging/lustre/lnet/lnet/lib-socket.c @@ -170,7 +170,7 @@ lnet_ipif_enumerate(char ***namesp) nalloc); } - LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr)); + ifr = kzalloc(nalloc * sizeof(*ifr), GFP_KERNEL); if (!ifr) { CERROR("ENOMEM enumerating up to %d interfaces\n", nalloc); @@ -195,14 +195,14 @@ lnet_ipif_enumerate(char ***namesp) if (nfound < nalloc || toobig) break; - LIBCFS_FREE(ifr, nalloc * sizeof(*ifr)); + kfree(ifr); nalloc *= 2; } if (!nfound) goto out1; - LIBCFS_ALLOC(names, nfound * sizeof(*names)); + names = kzalloc(nfound * sizeof(*names), GFP_KERNEL); if (!names) { rc = -ENOMEM; goto out1; @@ -218,7 +218,7 @@ lnet_ipif_enumerate(char ***namesp) goto out2; } - LIBCFS_ALLOC(names[i], IFNAMSIZ); + names[i] = kmalloc(IFNAMSIZ, GFP_KERNEL); if (!names[i]) { rc = -ENOMEM; goto out2; @@ -235,7 +235,7 @@ out2: if (rc < 0) lnet_ipif_free_enumeration(names, nfound); out1: - LIBCFS_FREE(ifr, nalloc * sizeof(*ifr)); + kfree(ifr); out0: return rc; } @@ -249,9 +249,9 @@ lnet_ipif_free_enumeration(char **names, int n) LASSERT(n > 0); for (i = 0; i < n && names[i]; i++) - LIBCFS_FREE(names[i], IFNAMSIZ); + kfree(names[i]); - LIBCFS_FREE(names, n * sizeof(*names)); + kfree(names); } EXPORT_SYMBOL(lnet_ipif_free_enumeration); diff --git a/drivers/staging/lustre/lnet/lnet/net_fault.c b/drivers/staging/lustre/lnet/lnet/net_fault.c index 5a5d1811ffbe..e3468cef273b 100644 --- a/drivers/staging/lustre/lnet/lnet/net_fault.c +++ b/drivers/staging/lustre/lnet/lnet/net_fault.c @@ -161,7 +161,7 @@ lnet_drop_rule_add(struct lnet_fault_attr *attr) if (lnet_fault_attr_validate(attr)) return -EINVAL; - CFS_ALLOC_PTR(rule); + rule = kzalloc(sizeof(*rule), GFP_NOFS); if (!rule) return -ENOMEM; @@ -170,10 +170,10 @@ lnet_drop_rule_add(struct lnet_fault_attr *attr) rule->dr_attr = *attr; if (attr->u.drop.da_interval) { rule->dr_time_base = cfs_time_shift(attr->u.drop.da_interval); - rule->dr_drop_time = cfs_time_shift(cfs_rand() % - attr->u.drop.da_interval); + rule->dr_drop_time = cfs_time_shift( + prandom_u32_max(attr->u.drop.da_interval)); } else { - rule->dr_drop_at = cfs_rand() % attr->u.drop.da_rate; + rule->dr_drop_at = prandom_u32_max(attr->u.drop.da_rate); } lnet_net_lock(LNET_LOCK_EX); @@ -223,7 +223,7 @@ lnet_drop_rule_del(lnet_nid_t src, lnet_nid_t dst) rule->dr_attr.u.drop.da_interval); list_del(&rule->dr_link); - CFS_FREE_PTR(rule); + kfree(rule); n++; } @@ -277,10 +277,10 @@ lnet_drop_rule_reset(void) memset(&rule->dr_stat, 0, sizeof(rule->dr_stat)); if (attr->u.drop.da_rate) { - rule->dr_drop_at = cfs_rand() % attr->u.drop.da_rate; + rule->dr_drop_at = prandom_u32_max(attr->u.drop.da_rate); } else { - rule->dr_drop_time = cfs_time_shift(cfs_rand() % - attr->u.drop.da_interval); + rule->dr_drop_time = cfs_time_shift( + prandom_u32_max(attr->u.drop.da_interval)); rule->dr_time_base = cfs_time_shift(attr->u.drop.da_interval); } spin_unlock(&rule->dr_lock); @@ -315,8 +315,8 @@ drop_rule_match(struct lnet_drop_rule *rule, lnet_nid_t src, rule->dr_time_base = now; rule->dr_drop_time = rule->dr_time_base + - cfs_time_seconds(cfs_rand() % - attr->u.drop.da_interval); + cfs_time_seconds( + prandom_u32_max(attr->u.drop.da_interval)); rule->dr_time_base += cfs_time_seconds(attr->u.drop.da_interval); CDEBUG(D_NET, "Drop Rule %s->%s: next drop : %lu\n", @@ -330,7 +330,7 @@ drop_rule_match(struct lnet_drop_rule *rule, lnet_nid_t src, if (!do_div(rule->dr_stat.fs_count, attr->u.drop.da_rate)) { rule->dr_drop_at = rule->dr_stat.fs_count + - cfs_rand() % attr->u.drop.da_rate; + prandom_u32_max(attr->u.drop.da_rate); CDEBUG(D_NET, "Drop Rule %s->%s: next drop: %lu\n", libcfs_nid2str(attr->fa_src), libcfs_nid2str(attr->fa_dst), rule->dr_drop_at); @@ -452,7 +452,7 @@ delay_rule_decref(struct lnet_delay_rule *rule) LASSERT(list_empty(&rule->dl_msg_list)); LASSERT(list_empty(&rule->dl_link)); - CFS_FREE_PTR(rule); + kfree(rule); } } @@ -483,8 +483,9 @@ delay_rule_match(struct lnet_delay_rule *rule, lnet_nid_t src, rule->dl_time_base = now; rule->dl_delay_time = rule->dl_time_base + - cfs_time_seconds(cfs_rand() % - attr->u.delay.la_interval); + cfs_time_seconds( + prandom_u32_max( + attr->u.delay.la_interval)); rule->dl_time_base += cfs_time_seconds(attr->u.delay.la_interval); CDEBUG(D_NET, "Delay Rule %s->%s: next delay : %lu\n", @@ -498,7 +499,7 @@ delay_rule_match(struct lnet_delay_rule *rule, lnet_nid_t src, /* generate the next random rate sequence */ if (!do_div(rule->dl_stat.fs_count, attr->u.delay.la_rate)) { rule->dl_delay_at = rule->dl_stat.fs_count + - cfs_rand() % attr->u.delay.la_rate; + prandom_u32_max(attr->u.delay.la_rate); CDEBUG(D_NET, "Delay Rule %s->%s: next delay: %lu\n", libcfs_nid2str(attr->fa_src), libcfs_nid2str(attr->fa_dst), rule->dl_delay_at); @@ -738,7 +739,7 @@ lnet_delay_rule_add(struct lnet_fault_attr *attr) if (lnet_fault_attr_validate(attr)) return -EINVAL; - CFS_ALLOC_PTR(rule); + rule = kzalloc(sizeof(*rule), GFP_NOFS); if (!rule) return -ENOMEM; @@ -771,10 +772,10 @@ lnet_delay_rule_add(struct lnet_fault_attr *attr) rule->dl_attr = *attr; if (attr->u.delay.la_interval) { rule->dl_time_base = cfs_time_shift(attr->u.delay.la_interval); - rule->dl_delay_time = cfs_time_shift(cfs_rand() % - attr->u.delay.la_interval); + rule->dl_delay_time = cfs_time_shift( + prandom_u32_max(attr->u.delay.la_interval)); } else { - rule->dl_delay_at = cfs_rand() % attr->u.delay.la_rate; + rule->dl_delay_at = prandom_u32_max(attr->u.delay.la_rate); } rule->dl_msg_send = -1; @@ -792,7 +793,7 @@ lnet_delay_rule_add(struct lnet_fault_attr *attr) return 0; failed: mutex_unlock(&delay_dd.dd_mutex); - CFS_FREE_PTR(rule); + kfree(rule); return rc; } @@ -920,10 +921,11 @@ lnet_delay_rule_reset(void) memset(&rule->dl_stat, 0, sizeof(rule->dl_stat)); if (attr->u.delay.la_rate) { - rule->dl_delay_at = cfs_rand() % attr->u.delay.la_rate; + rule->dl_delay_at = prandom_u32_max(attr->u.delay.la_rate); } else { - rule->dl_delay_time = cfs_time_shift(cfs_rand() % - attr->u.delay.la_interval); + rule->dl_delay_time = + cfs_time_shift(prandom_u32_max( + attr->u.delay.la_interval)); rule->dl_time_base = cfs_time_shift(attr->u.delay.la_interval); } spin_unlock(&rule->dl_lock); diff --git a/drivers/staging/lustre/lnet/lnet/nidstrings.c b/drivers/staging/lustre/lnet/lnet/nidstrings.c index 05b120c2d45a..3aba1421c741 100644 --- a/drivers/staging/lustre/lnet/lnet/nidstrings.c +++ b/drivers/staging/lustre/lnet/lnet/nidstrings.c @@ -166,7 +166,7 @@ parse_addrange(const struct cfs_lstr *src, struct nidrange *nidrange) return 0; } - LIBCFS_ALLOC(addrrange, sizeof(struct addrrange)); + addrrange = kzalloc(sizeof(struct addrrange), GFP_NOFS); if (!addrrange) return -ENOMEM; list_add_tail(&addrrange->ar_link, &nidrange->nr_addrranges); @@ -225,7 +225,7 @@ add_nidrange(const struct cfs_lstr *src, return nr; } - LIBCFS_ALLOC(nr, sizeof(struct nidrange)); + nr = kzalloc(sizeof(struct nidrange), GFP_NOFS); if (!nr) return NULL; list_add_tail(&nr->nr_link, nidlist); @@ -286,7 +286,7 @@ free_addrranges(struct list_head *list) cfs_expr_list_free_list(&ar->ar_numaddr_ranges); list_del(&ar->ar_link); - LIBCFS_FREE(ar, sizeof(struct addrrange)); + kfree(ar); } } @@ -308,7 +308,7 @@ cfs_free_nidlist(struct list_head *list) nr = list_entry(pos, struct nidrange, nr_link); free_addrranges(&nr->nr_addrranges); list_del(pos); - LIBCFS_FREE(nr, sizeof(struct nidrange)); + kfree(nr); } } EXPORT_SYMBOL(cfs_free_nidlist); diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c index 5e94ad349454..3e157c10fec4 100644 --- a/drivers/staging/lustre/lnet/lnet/peer.c +++ b/drivers/staging/lustre/lnet/lnet/peer.c @@ -56,8 +56,8 @@ lnet_peer_tables_create(void) cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) { INIT_LIST_HEAD(&ptable->pt_deathrow); - LIBCFS_CPT_ALLOC(hash, lnet_cpt_table(), i, - LNET_PEER_HASH_SIZE * sizeof(*hash)); + hash = kvmalloc_cpt(LNET_PEER_HASH_SIZE * sizeof(*hash), + GFP_KERNEL, i); if (!hash) { CERROR("Failed to create peer hash table\n"); lnet_peer_tables_destroy(); @@ -94,7 +94,7 @@ lnet_peer_tables_destroy(void) for (j = 0; j < LNET_PEER_HASH_SIZE; j++) LASSERT(list_empty(&hash[j])); - LIBCFS_FREE(hash, LNET_PEER_HASH_SIZE * sizeof(*hash)); + kvfree(hash); } cfs_percpt_free(the_lnet.ln_peer_tables); @@ -212,7 +212,7 @@ lnet_peer_tables_cleanup(struct lnet_ni *ni) list_for_each_entry_safe(lp, temp, &deathrow, lp_hashlist) { list_del(&lp->lp_hashlist); - LIBCFS_FREE(lp, sizeof(*lp)); + kfree(lp); } } @@ -297,7 +297,7 @@ lnet_nid2peer_locked(struct lnet_peer **lpp, lnet_nid_t nid, int cpt) if (lp) memset(lp, 0, sizeof(*lp)); else - LIBCFS_CPT_ALLOC(lp, lnet_cpt_table(), cpt2, sizeof(*lp)); + lp = kzalloc_cpt(sizeof(*lp), GFP_NOFS, cpt2); if (!lp) { rc = -ENOMEM; diff --git a/drivers/staging/lustre/lnet/lnet/router.c b/drivers/staging/lustre/lnet/lnet/router.c index 88283ca3f860..6504761ca598 100644 --- a/drivers/staging/lustre/lnet/lnet/router.c +++ b/drivers/staging/lustre/lnet/lnet/router.c @@ -238,28 +238,25 @@ lnet_find_net_locked(__u32 net) static void lnet_shuffle_seed(void) { static int seeded; - __u32 lnd_type, seed[2]; - struct timespec64 ts; struct lnet_ni *ni; if (seeded) return; - cfs_get_random_bytes(seed, sizeof(seed)); - /* * Nodes with small feet have little entropy * the NID for this node gives the most entropy in the low bits */ list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) { - lnd_type = LNET_NETTYP(LNET_NIDNET(ni->ni_nid)); + __u32 lnd_type, seed; - if (lnd_type != LOLND) - seed[0] ^= (LNET_NIDADDR(ni->ni_nid) | lnd_type); + lnd_type = LNET_NETTYP(LNET_NIDNET(ni->ni_nid)); + if (lnd_type != LOLND) { + seed = (LNET_NIDADDR(ni->ni_nid) | lnd_type); + add_device_randomness(&seed, sizeof(seed)); + } } - ktime_get_ts64(&ts); - cfs_srand(ts.tv_sec ^ seed[0], ts.tv_nsec ^ seed[1]); seeded = 1; } @@ -277,8 +274,8 @@ lnet_add_route_to_rnet(struct lnet_remotenet *rnet, struct lnet_route *route) len++; } - /* len+1 positions to add a new entry, also prevents division by 0 */ - offset = cfs_rand() % (len + 1); + /* len+1 positions to add a new entry */ + offset = prandom_u32_max(len + 1); list_for_each(e, &rnet->lrn_routes) { if (!offset) break; @@ -318,15 +315,13 @@ lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway, return -EEXIST; /* Assume net, route, all new */ - LIBCFS_ALLOC(route, sizeof(*route)); - LIBCFS_ALLOC(rnet, sizeof(*rnet)); + route = kzalloc(sizeof(*route), GFP_NOFS); + rnet = kzalloc(sizeof(*rnet), GFP_NOFS); if (!route || !rnet) { CERROR("Out of memory creating route %s %d %s\n", libcfs_net2str(net), hops, libcfs_nid2str(gateway)); - if (route) - LIBCFS_FREE(route, sizeof(*route)); - if (rnet) - LIBCFS_FREE(rnet, sizeof(*rnet)); + kfree(route); + kfree(rnet); return -ENOMEM; } @@ -342,8 +337,8 @@ lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway, if (rc) { lnet_net_unlock(LNET_LOCK_EX); - LIBCFS_FREE(route, sizeof(*route)); - LIBCFS_FREE(rnet, sizeof(*rnet)); + kfree(route); + kfree(rnet); if (rc == -EHOSTUNREACH) /* gateway is not on a local net */ return rc; /* ignore the route entry */ @@ -398,11 +393,11 @@ lnet_add_route(__u32 net, __u32 hops, lnet_nid_t gateway, if (!add_route) { rc = -EEXIST; - LIBCFS_FREE(route, sizeof(*route)); + kfree(route); } if (rnet != rnet2) - LIBCFS_FREE(rnet, sizeof(*rnet)); + kfree(rnet); /* indicate to startup the router checker if configured */ wake_up(&the_lnet.ln_rc_waitq); @@ -520,10 +515,8 @@ lnet_del_route(__u32 net, lnet_nid_t gw_nid) lnet_net_unlock(LNET_LOCK_EX); - LIBCFS_FREE(route, sizeof(*route)); - - if (rnet) - LIBCFS_FREE(rnet, sizeof(*rnet)); + kfree(route); + kfree(rnet); rc = 0; lnet_net_lock(LNET_LOCK_EX); @@ -891,10 +884,9 @@ lnet_destroy_rc_data(struct lnet_rc_data *rcd) lnet_net_unlock(cpt); } - if (rcd->rcd_pinginfo) - LIBCFS_FREE(rcd->rcd_pinginfo, LNET_PINGINFO_SIZE); + kfree(rcd->rcd_pinginfo); - LIBCFS_FREE(rcd, sizeof(*rcd)); + kfree(rcd); } static struct lnet_rc_data * @@ -908,14 +900,14 @@ lnet_create_rc_data_locked(struct lnet_peer *gateway) lnet_net_unlock(gateway->lp_cpt); - LIBCFS_ALLOC(rcd, sizeof(*rcd)); + rcd = kzalloc(sizeof(*rcd), GFP_NOFS); if (!rcd) goto out; LNetInvalidateMDHandle(&rcd->rcd_mdh); INIT_LIST_HEAD(&rcd->rcd_list); - LIBCFS_ALLOC(pi, LNET_PINGINFO_SIZE); + pi = kzalloc(LNET_PINGINFO_SIZE, GFP_NOFS); if (!pi) goto out; @@ -1304,12 +1296,10 @@ rescan: void lnet_destroy_rtrbuf(struct lnet_rtrbuf *rb, int npages) { - int sz = offsetof(struct lnet_rtrbuf, rb_kiov[npages]); - while (--npages >= 0) __free_page(rb->rb_kiov[npages].bv_page); - LIBCFS_FREE(rb, sz); + kfree(rb); } static struct lnet_rtrbuf * @@ -1321,7 +1311,7 @@ lnet_new_rtrbuf(struct lnet_rtrbufpool *rbp, int cpt) struct lnet_rtrbuf *rb; int i; - LIBCFS_CPT_ALLOC(rb, lnet_cpt_table(), cpt, sz); + rb = kzalloc_cpt(sz, GFP_NOFS, cpt); if (!rb) return NULL; @@ -1335,7 +1325,7 @@ lnet_new_rtrbuf(struct lnet_rtrbufpool *rbp, int cpt) while (--i >= 0) __free_page(rb->rb_kiov[i].bv_page); - LIBCFS_FREE(rb, sz); + kfree(rb); return NULL; } diff --git a/drivers/staging/lustre/lnet/lnet/router_proc.c b/drivers/staging/lustre/lnet/lnet/router_proc.c index d32d653edcb0..1a71ffebc889 100644 --- a/drivers/staging/lustre/lnet/lnet/router_proc.c +++ b/drivers/staging/lustre/lnet/lnet/router_proc.c @@ -91,13 +91,13 @@ static int __proc_lnet_stats(void *data, int write, /* read */ - LIBCFS_ALLOC(ctrs, sizeof(*ctrs)); + ctrs = kzalloc(sizeof(*ctrs), GFP_NOFS); if (!ctrs) return -ENOMEM; - LIBCFS_ALLOC(tmpstr, tmpsiz); + tmpstr = kmalloc(tmpsiz, GFP_KERNEL); if (!tmpstr) { - LIBCFS_FREE(ctrs, sizeof(*ctrs)); + kfree(ctrs); return -ENOMEM; } @@ -118,8 +118,8 @@ static int __proc_lnet_stats(void *data, int write, rc = cfs_trace_copyout_string(buffer, nob, tmpstr + pos, "\n"); - LIBCFS_FREE(tmpstr, tmpsiz); - LIBCFS_FREE(ctrs, sizeof(*ctrs)); + kfree(tmpstr); + kfree(ctrs); return rc; } @@ -151,7 +151,7 @@ static int proc_lnet_routes(struct ctl_table *table, int write, if (!*lenp) return 0; - LIBCFS_ALLOC(tmpstr, tmpsiz); + tmpstr = kmalloc(tmpsiz, GFP_KERNEL); if (!tmpstr) return -ENOMEM; @@ -183,7 +183,7 @@ static int proc_lnet_routes(struct ctl_table *table, int write, if (ver != LNET_PROC_VERSION(the_lnet.ln_remote_nets_version)) { lnet_net_unlock(0); - LIBCFS_FREE(tmpstr, tmpsiz); + kfree(tmpstr); return -ESTALE; } @@ -248,7 +248,7 @@ static int proc_lnet_routes(struct ctl_table *table, int write, } } - LIBCFS_FREE(tmpstr, tmpsiz); + kfree(tmpstr); if (!rc) *lenp = len; @@ -275,7 +275,7 @@ static int proc_lnet_routers(struct ctl_table *table, int write, if (!*lenp) return 0; - LIBCFS_ALLOC(tmpstr, tmpsiz); + tmpstr = kmalloc(tmpsiz, GFP_KERNEL); if (!tmpstr) return -ENOMEM; @@ -303,7 +303,7 @@ static int proc_lnet_routers(struct ctl_table *table, int write, if (ver != LNET_PROC_VERSION(the_lnet.ln_routers_version)) { lnet_net_unlock(0); - LIBCFS_FREE(tmpstr, tmpsiz); + kfree(tmpstr); return -ESTALE; } @@ -385,7 +385,7 @@ static int proc_lnet_routers(struct ctl_table *table, int write, } } - LIBCFS_FREE(tmpstr, tmpsiz); + kfree(tmpstr); if (!rc) *lenp = len; @@ -418,7 +418,7 @@ static int proc_lnet_peers(struct ctl_table *table, int write, return 0; } - LIBCFS_ALLOC(tmpstr, tmpsiz); + tmpstr = kmalloc(tmpsiz, GFP_KERNEL); if (!tmpstr) return -ENOMEM; @@ -448,7 +448,7 @@ static int proc_lnet_peers(struct ctl_table *table, int write, if (ver != LNET_PROC_VERSION(ptable->pt_version)) { lnet_net_unlock(cpt); - LIBCFS_FREE(tmpstr, tmpsiz); + kfree(tmpstr); return -ESTALE; } @@ -556,7 +556,7 @@ static int proc_lnet_peers(struct ctl_table *table, int write, *ppos = LNET_PROC_POS_MAKE(cpt, ver, hash, hoff); } - LIBCFS_FREE(tmpstr, tmpsiz); + kfree(tmpstr); if (!rc) *lenp = len; @@ -579,7 +579,7 @@ static int __proc_lnet_buffers(void *data, int write, /* (4 %d) * 4 * LNET_CPT_NUMBER */ tmpsiz = 64 * (LNET_NRBPOOLS + 1) * LNET_CPT_NUMBER; - LIBCFS_ALLOC(tmpstr, tmpsiz); + tmpstr = kvmalloc(tmpsiz, GFP_KERNEL); if (!tmpstr) return -ENOMEM; @@ -618,7 +618,7 @@ static int __proc_lnet_buffers(void *data, int write, rc = cfs_trace_copyout_string(buffer, nob, tmpstr + pos, NULL); - LIBCFS_FREE(tmpstr, tmpsiz); + kvfree(tmpstr); return rc; } @@ -643,7 +643,7 @@ static int proc_lnet_nis(struct ctl_table *table, int write, if (!*lenp) return 0; - LIBCFS_ALLOC(tmpstr, tmpsiz); + tmpstr = kvmalloc(tmpsiz, GFP_KERNEL); if (!tmpstr) return -ENOMEM; @@ -744,7 +744,7 @@ static int proc_lnet_nis(struct ctl_table *table, int write, *ppos += 1; } - LIBCFS_FREE(tmpstr, tmpsiz); + kvfree(tmpstr); if (!rc) *lenp = len; @@ -795,7 +795,7 @@ static int __proc_lnet_portal_rotor(void *data, int write, int rc; int i; - LIBCFS_ALLOC(buf, buf_len); + buf = kmalloc(buf_len, GFP_KERNEL); if (!buf) return -ENOMEM; @@ -829,7 +829,7 @@ static int __proc_lnet_portal_rotor(void *data, int write, if (rc < 0) goto out; - tmp = cfs_trimwhite(buf); + tmp = strim(buf); rc = -EINVAL; lnet_res_lock(0); @@ -843,7 +843,7 @@ static int __proc_lnet_portal_rotor(void *data, int write, } lnet_res_unlock(0); out: - LIBCFS_FREE(buf, buf_len); + kfree(buf); return rc; } diff --git a/drivers/staging/lustre/lnet/selftest/conctl.c b/drivers/staging/lustre/lnet/selftest/conctl.c index 082c0afacf23..34ba440b3c02 100644 --- a/drivers/staging/lustre/lnet/selftest/conctl.c +++ b/drivers/staging/lustre/lnet/selftest/conctl.c @@ -45,7 +45,7 @@ static int lst_session_new_ioctl(struct lstio_session_new_args *args) { - char *name; + char name[LST_NAME_SIZE + 1]; int rc; if (!args->lstio_ses_idp || /* address for output sid */ @@ -55,13 +55,8 @@ lst_session_new_ioctl(struct lstio_session_new_args *args) args->lstio_ses_nmlen > LST_NAME_SIZE) return -EINVAL; - LIBCFS_ALLOC(name, args->lstio_ses_nmlen + 1); - if (!name) - return -ENOMEM; - if (copy_from_user(name, args->lstio_ses_namep, args->lstio_ses_nmlen)) { - LIBCFS_FREE(name, args->lstio_ses_nmlen + 1); return -EFAULT; } @@ -74,7 +69,6 @@ lst_session_new_ioctl(struct lstio_session_new_args *args) args->lstio_ses_force, args->lstio_ses_idp); - LIBCFS_FREE(name, args->lstio_ses_nmlen + 1); return rc; } @@ -112,7 +106,7 @@ lst_session_info_ioctl(struct lstio_session_info_args *args) static int lst_debug_ioctl(struct lstio_debug_args *args) { - char *name = NULL; + char name[LST_NAME_SIZE + 1]; int client = 1; int rc; @@ -128,16 +122,10 @@ lst_debug_ioctl(struct lstio_debug_args *args) return -EINVAL; if (args->lstio_dbg_namep) { - LIBCFS_ALLOC(name, args->lstio_dbg_nmlen + 1); - if (!name) - return -ENOMEM; if (copy_from_user(name, args->lstio_dbg_namep, - args->lstio_dbg_nmlen)) { - LIBCFS_FREE(name, args->lstio_dbg_nmlen + 1); - + args->lstio_dbg_nmlen)) return -EFAULT; - } name[args->lstio_dbg_nmlen] = 0; } @@ -154,7 +142,7 @@ lst_debug_ioctl(struct lstio_debug_args *args) client = 0; /* fall through */ case LST_OPC_BATCHCLI: - if (!name) + if (!args->lstio_dbg_namep) goto out; rc = lstcon_batch_debug(args->lstio_dbg_timeout, @@ -162,7 +150,7 @@ lst_debug_ioctl(struct lstio_debug_args *args) break; case LST_OPC_GROUP: - if (!name) + if (!args->lstio_dbg_namep) goto out; rc = lstcon_group_debug(args->lstio_dbg_timeout, @@ -185,16 +173,13 @@ lst_debug_ioctl(struct lstio_debug_args *args) } out: - if (name) - LIBCFS_FREE(name, args->lstio_dbg_nmlen + 1); - return rc; } static int lst_group_add_ioctl(struct lstio_group_add_args *args) { - char *name; + char name[LST_NAME_SIZE + 1]; int rc; if (args->lstio_grp_key != console_session.ses_key) @@ -205,22 +190,14 @@ lst_group_add_ioctl(struct lstio_group_add_args *args) args->lstio_grp_nmlen > LST_NAME_SIZE) return -EINVAL; - LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1); - if (!name) - return -ENOMEM; - if (copy_from_user(name, args->lstio_grp_namep, - args->lstio_grp_nmlen)) { - LIBCFS_FREE(name, args->lstio_grp_nmlen); + args->lstio_grp_nmlen)) return -EFAULT; - } name[args->lstio_grp_nmlen] = 0; rc = lstcon_group_add(name); - LIBCFS_FREE(name, args->lstio_grp_nmlen + 1); - return rc; } @@ -228,7 +205,7 @@ static int lst_group_del_ioctl(struct lstio_group_del_args *args) { int rc; - char *name; + char name[LST_NAME_SIZE + 1]; if (args->lstio_grp_key != console_session.ses_key) return -EACCES; @@ -238,22 +215,14 @@ lst_group_del_ioctl(struct lstio_group_del_args *args) args->lstio_grp_nmlen > LST_NAME_SIZE) return -EINVAL; - LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1); - if (!name) - return -ENOMEM; - if (copy_from_user(name, args->lstio_grp_namep, - args->lstio_grp_nmlen)) { - LIBCFS_FREE(name, args->lstio_grp_nmlen + 1); + args->lstio_grp_nmlen)) return -EFAULT; - } name[args->lstio_grp_nmlen] = 0; rc = lstcon_group_del(name); - LIBCFS_FREE(name, args->lstio_grp_nmlen + 1); - return rc; } @@ -261,7 +230,7 @@ static int lst_group_update_ioctl(struct lstio_group_update_args *args) { int rc; - char *name; + char name[LST_NAME_SIZE + 1]; if (args->lstio_grp_key != console_session.ses_key) return -EACCES; @@ -272,15 +241,9 @@ lst_group_update_ioctl(struct lstio_group_update_args *args) args->lstio_grp_nmlen > LST_NAME_SIZE) return -EINVAL; - LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1); - if (!name) - return -ENOMEM; - if (copy_from_user(name, args->lstio_grp_namep, - args->lstio_grp_nmlen)) { - LIBCFS_FREE(name, args->lstio_grp_nmlen + 1); + args->lstio_grp_nmlen)) return -EFAULT; - } name[args->lstio_grp_nmlen] = 0; @@ -309,8 +272,6 @@ lst_group_update_ioctl(struct lstio_group_update_args *args) break; } - LIBCFS_FREE(name, args->lstio_grp_nmlen + 1); - return rc; } @@ -319,7 +280,7 @@ lst_nodes_add_ioctl(struct lstio_group_nodes_args *args) { unsigned int feats; int rc; - char *name; + char name[LST_NAME_SIZE + 1]; if (args->lstio_grp_key != console_session.ses_key) return -EACCES; @@ -333,16 +294,9 @@ lst_nodes_add_ioctl(struct lstio_group_nodes_args *args) args->lstio_grp_nmlen > LST_NAME_SIZE) return -EINVAL; - LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1); - if (!name) - return -ENOMEM; - if (copy_from_user(name, args->lstio_grp_namep, - args->lstio_grp_nmlen)) { - LIBCFS_FREE(name, args->lstio_grp_nmlen + 1); - + args->lstio_grp_nmlen)) return -EFAULT; - } name[args->lstio_grp_nmlen] = 0; @@ -350,7 +304,6 @@ lst_nodes_add_ioctl(struct lstio_group_nodes_args *args) args->lstio_grp_idsp, &feats, args->lstio_grp_resultp); - LIBCFS_FREE(name, args->lstio_grp_nmlen + 1); if (!rc && copy_to_user(args->lstio_grp_featp, &feats, sizeof(feats))) { return -EINVAL; @@ -379,7 +332,7 @@ lst_group_list_ioctl(struct lstio_group_list_args *args) static int lst_group_info_ioctl(struct lstio_group_info_args *args) { - char *name; + char name[LST_NAME_SIZE + 1]; int ndent; int index; int rc; @@ -411,23 +364,15 @@ lst_group_info_ioctl(struct lstio_group_info_args *args) return -EINVAL; } - LIBCFS_ALLOC(name, args->lstio_grp_nmlen + 1); - if (!name) - return -ENOMEM; - if (copy_from_user(name, args->lstio_grp_namep, - args->lstio_grp_nmlen)) { - LIBCFS_FREE(name, args->lstio_grp_nmlen + 1); + args->lstio_grp_nmlen)) return -EFAULT; - } name[args->lstio_grp_nmlen] = 0; rc = lstcon_group_info(name, args->lstio_grp_entp, &index, &ndent, args->lstio_grp_dentsp); - LIBCFS_FREE(name, args->lstio_grp_nmlen + 1); - if (rc) return rc; @@ -443,7 +388,7 @@ static int lst_batch_add_ioctl(struct lstio_batch_add_args *args) { int rc; - char *name; + char name[LST_NAME_SIZE + 1]; if (args->lstio_bat_key != console_session.ses_key) return -EACCES; @@ -453,22 +398,14 @@ lst_batch_add_ioctl(struct lstio_batch_add_args *args) args->lstio_bat_nmlen > LST_NAME_SIZE) return -EINVAL; - LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1); - if (!name) - return -ENOMEM; - if (copy_from_user(name, args->lstio_bat_namep, - args->lstio_bat_nmlen)) { - LIBCFS_FREE(name, args->lstio_bat_nmlen + 1); + args->lstio_bat_nmlen)) return -EFAULT; - } name[args->lstio_bat_nmlen] = 0; rc = lstcon_batch_add(name); - LIBCFS_FREE(name, args->lstio_bat_nmlen + 1); - return rc; } @@ -476,7 +413,7 @@ static int lst_batch_run_ioctl(struct lstio_batch_run_args *args) { int rc; - char *name; + char name[LST_NAME_SIZE + 1]; if (args->lstio_bat_key != console_session.ses_key) return -EACCES; @@ -486,23 +423,15 @@ lst_batch_run_ioctl(struct lstio_batch_run_args *args) args->lstio_bat_nmlen > LST_NAME_SIZE) return -EINVAL; - LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1); - if (!name) - return -ENOMEM; - if (copy_from_user(name, args->lstio_bat_namep, - args->lstio_bat_nmlen)) { - LIBCFS_FREE(name, args->lstio_bat_nmlen + 1); + args->lstio_bat_nmlen)) return -EFAULT; - } name[args->lstio_bat_nmlen] = 0; rc = lstcon_batch_run(name, args->lstio_bat_timeout, args->lstio_bat_resultp); - LIBCFS_FREE(name, args->lstio_bat_nmlen + 1); - return rc; } @@ -510,7 +439,7 @@ static int lst_batch_stop_ioctl(struct lstio_batch_stop_args *args) { int rc; - char *name; + char name[LST_NAME_SIZE + 1]; if (args->lstio_bat_key != console_session.ses_key) return -EACCES; @@ -521,30 +450,22 @@ lst_batch_stop_ioctl(struct lstio_batch_stop_args *args) args->lstio_bat_nmlen > LST_NAME_SIZE) return -EINVAL; - LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1); - if (!name) - return -ENOMEM; - if (copy_from_user(name, args->lstio_bat_namep, - args->lstio_bat_nmlen)) { - LIBCFS_FREE(name, args->lstio_bat_nmlen + 1); + args->lstio_bat_nmlen)) return -EFAULT; - } name[args->lstio_bat_nmlen] = 0; rc = lstcon_batch_stop(name, args->lstio_bat_force, args->lstio_bat_resultp); - LIBCFS_FREE(name, args->lstio_bat_nmlen + 1); - return rc; } static int lst_batch_query_ioctl(struct lstio_batch_query_args *args) { - char *name; + char name[LST_NAME_SIZE + 1]; int rc; if (args->lstio_bat_key != console_session.ses_key) @@ -559,15 +480,9 @@ lst_batch_query_ioctl(struct lstio_batch_query_args *args) if (args->lstio_bat_testidx < 0) return -EINVAL; - LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1); - if (!name) - return -ENOMEM; - if (copy_from_user(name, args->lstio_bat_namep, - args->lstio_bat_nmlen)) { - LIBCFS_FREE(name, args->lstio_bat_nmlen + 1); + args->lstio_bat_nmlen)) return -EFAULT; - } name[args->lstio_bat_nmlen] = 0; @@ -577,8 +492,6 @@ lst_batch_query_ioctl(struct lstio_batch_query_args *args) args->lstio_bat_timeout, args->lstio_bat_resultp); - LIBCFS_FREE(name, args->lstio_bat_nmlen + 1); - return rc; } @@ -602,7 +515,7 @@ lst_batch_list_ioctl(struct lstio_batch_list_args *args) static int lst_batch_info_ioctl(struct lstio_batch_info_args *args) { - char *name; + char name[LST_NAME_SIZE + 1]; int rc; int index; int ndent; @@ -634,15 +547,9 @@ lst_batch_info_ioctl(struct lstio_batch_info_args *args) return -EINVAL; } - LIBCFS_ALLOC(name, args->lstio_bat_nmlen + 1); - if (!name) - return -ENOMEM; - if (copy_from_user(name, args->lstio_bat_namep, - args->lstio_bat_nmlen)) { - LIBCFS_FREE(name, args->lstio_bat_nmlen + 1); + args->lstio_bat_nmlen)) return -EFAULT; - } name[args->lstio_bat_nmlen] = 0; @@ -650,8 +557,6 @@ lst_batch_info_ioctl(struct lstio_batch_info_args *args) args->lstio_bat_server, args->lstio_bat_testidx, &index, &ndent, args->lstio_bat_dentsp); - LIBCFS_FREE(name, args->lstio_bat_nmlen + 1); - if (rc) return rc; @@ -667,7 +572,7 @@ static int lst_stat_query_ioctl(struct lstio_stat_args *args) { int rc; - char *name = NULL; + char name[LST_NAME_SIZE + 1]; /* TODO: not finished */ if (args->lstio_sta_key != console_session.ses_key) @@ -689,10 +594,6 @@ lst_stat_query_ioctl(struct lstio_stat_args *args) args->lstio_sta_nmlen > LST_NAME_SIZE) return -EINVAL; - LIBCFS_ALLOC(name, args->lstio_sta_nmlen + 1); - if (!name) - return -ENOMEM; - rc = copy_from_user(name, args->lstio_sta_namep, args->lstio_sta_nmlen); if (!rc) @@ -704,16 +605,14 @@ lst_stat_query_ioctl(struct lstio_stat_args *args) rc = -EINVAL; } - if (name) - LIBCFS_FREE(name, args->lstio_sta_nmlen + 1); return rc; } static int lst_test_add_ioctl(struct lstio_test_args *args) { - char *batch_name; - char *src_name = NULL; - char *dst_name = NULL; + char batch_name[LST_NAME_SIZE + 1]; + char src_name[LST_NAME_SIZE + 1]; + char dst_name[LST_NAME_SIZE + 1]; void *param = NULL; int ret = 0; int rc = -ENOMEM; @@ -748,20 +647,8 @@ static int lst_test_add_ioctl(struct lstio_test_args *args) if (!args->lstio_tes_param && args->lstio_tes_param_len) return -EINVAL; - LIBCFS_ALLOC(batch_name, args->lstio_tes_bat_nmlen + 1); - if (!batch_name) - return rc; - - LIBCFS_ALLOC(src_name, args->lstio_tes_sgrp_nmlen + 1); - if (!src_name) - goto out; - - LIBCFS_ALLOC(dst_name, args->lstio_tes_dgrp_nmlen + 1); - if (!dst_name) - goto out; - if (args->lstio_tes_param) { - LIBCFS_ALLOC(param, args->lstio_tes_param_len); + param = kmalloc(args->lstio_tes_param_len, GFP_KERNEL); if (!param) goto out; if (copy_from_user(param, args->lstio_tes_param, @@ -791,17 +678,7 @@ static int lst_test_add_ioctl(struct lstio_test_args *args) rc = (copy_to_user(args->lstio_tes_retp, &ret, sizeof(ret))) ? -EFAULT : 0; out: - if (batch_name) - LIBCFS_FREE(batch_name, args->lstio_tes_bat_nmlen + 1); - - if (src_name) - LIBCFS_FREE(src_name, args->lstio_tes_sgrp_nmlen + 1); - - if (dst_name) - LIBCFS_FREE(dst_name, args->lstio_tes_dgrp_nmlen + 1); - - if (param) - LIBCFS_FREE(param, args->lstio_tes_param_len); + kfree(param); return rc; } @@ -824,13 +701,13 @@ lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_hdr *hdr) if (data->ioc_plen1 > PAGE_SIZE) return -EINVAL; - LIBCFS_ALLOC(buf, data->ioc_plen1); + buf = kmalloc(data->ioc_plen1, GFP_KERNEL); if (!buf) return -ENOMEM; /* copy in parameter */ if (copy_from_user(buf, data->ioc_pbuf1, data->ioc_plen1)) { - LIBCFS_FREE(buf, data->ioc_plen1); + kfree(buf); return -EFAULT; } @@ -920,7 +797,7 @@ lstcon_ioctl_entry(unsigned int cmd, struct libcfs_ioctl_hdr *hdr) out: mutex_unlock(&console_session.ses_mutex); - LIBCFS_FREE(buf, data->ioc_plen1); + kfree(buf); return rc; } diff --git a/drivers/staging/lustre/lnet/selftest/conrpc.c b/drivers/staging/lustre/lnet/selftest/conrpc.c index 6a0f770e0e24..7aa515c34594 100644 --- a/drivers/staging/lustre/lnet/selftest/conrpc.c +++ b/drivers/staging/lustre/lnet/selftest/conrpc.c @@ -129,7 +129,7 @@ lstcon_rpc_prep(struct lstcon_node *nd, int service, unsigned int feats, spin_unlock(&console_session.ses_rpc_lock); if (!crpc) { - LIBCFS_ALLOC(crpc, sizeof(*crpc)); + crpc = kzalloc(sizeof(*crpc), GFP_NOFS); if (!crpc) return -ENOMEM; } @@ -140,7 +140,7 @@ lstcon_rpc_prep(struct lstcon_node *nd, int service, unsigned int feats, return 0; } - LIBCFS_FREE(crpc, sizeof(*crpc)); + kfree(crpc); return rc; } @@ -250,7 +250,7 @@ lstcon_rpc_trans_prep(struct list_head *translist, int transop, } /* create a trans group */ - LIBCFS_ALLOC(trans, sizeof(*trans)); + trans = kzalloc(sizeof(*trans), GFP_NOFS); if (!trans) return -ENOMEM; @@ -585,7 +585,7 @@ lstcon_rpc_trans_destroy(struct lstcon_rpc_trans *trans) CDEBUG(D_NET, "Transaction %s destroyed with %d pending RPCs\n", lstcon_rpc_trans_name(trans->tas_opc), count); - LIBCFS_FREE(trans, sizeof(*trans)); + kfree(trans); } int @@ -1369,7 +1369,7 @@ lstcon_rpc_cleanup_wait(void) list_for_each_entry_safe(crpc, temp, &zlist, crp_link) { list_del(&crpc->crp_link); - LIBCFS_FREE(crpc, sizeof(struct lstcon_rpc)); + kfree(crpc); } } diff --git a/drivers/staging/lustre/lnet/selftest/console.c b/drivers/staging/lustre/lnet/selftest/console.c index a2662638d599..1acd5cb324b1 100644 --- a/drivers/staging/lustre/lnet/selftest/console.c +++ b/drivers/staging/lustre/lnet/selftest/console.c @@ -88,7 +88,7 @@ lstcon_node_find(struct lnet_process_id id, struct lstcon_node **ndpp, if (!create) return -ENOENT; - LIBCFS_ALLOC(*ndpp, sizeof(**ndpp) + sizeof(*ndl)); + *ndpp = kzalloc(sizeof(**ndpp) + sizeof(*ndl), GFP_KERNEL); if (!*ndpp) return -ENOMEM; @@ -133,7 +133,7 @@ lstcon_node_put(struct lstcon_node *nd) list_del(&ndl->ndl_link); list_del(&ndl->ndl_hlink); - LIBCFS_FREE(nd, sizeof(*nd) + sizeof(*ndl)); + kfree(nd); } static int @@ -166,7 +166,7 @@ lstcon_ndlink_find(struct list_head *hash, struct lnet_process_id id, if (rc) return rc; - LIBCFS_ALLOC(ndl, sizeof(struct lstcon_ndlink)); + ndl = kzalloc(sizeof(struct lstcon_ndlink), GFP_NOFS); if (!ndl) { lstcon_node_put(nd); return -ENOMEM; @@ -190,7 +190,7 @@ lstcon_ndlink_release(struct lstcon_ndlink *ndl) list_del(&ndl->ndl_hlink); /* delete from hash */ lstcon_node_put(ndl->ndl_node); - LIBCFS_FREE(ndl, sizeof(*ndl)); + kfree(ndl); } static int @@ -199,16 +199,16 @@ lstcon_group_alloc(char *name, struct lstcon_group **grpp) struct lstcon_group *grp; int i; - LIBCFS_ALLOC(grp, offsetof(struct lstcon_group, - grp_ndl_hash[LST_NODE_HASHSIZE])); + grp = kmalloc(offsetof(struct lstcon_group, + grp_ndl_hash[LST_NODE_HASHSIZE]), + GFP_KERNEL); if (!grp) return -ENOMEM; grp->grp_ref = 1; if (name) { if (strlen(name) > sizeof(grp->grp_name) - 1) { - LIBCFS_FREE(grp, offsetof(struct lstcon_group, - grp_ndl_hash[LST_NODE_HASHSIZE])); + kfree(grp); return -E2BIG; } strncpy(grp->grp_name, name, sizeof(grp->grp_name)); @@ -263,8 +263,7 @@ lstcon_group_decref(struct lstcon_group *grp) for (i = 0; i < LST_NODE_HASHSIZE; i++) LASSERT(list_empty(&grp->grp_ndl_hash[i])); - LIBCFS_FREE(grp, offsetof(struct lstcon_group, - grp_ndl_hash[LST_NODE_HASHSIZE])); + kfree(grp); } static int @@ -807,7 +806,7 @@ lstcon_group_info(char *name, struct lstcon_ndlist_ent __user *gents_p, } /* non-verbose query */ - LIBCFS_ALLOC(gentp, sizeof(struct lstcon_ndlist_ent)); + gentp = kzalloc(sizeof(struct lstcon_ndlist_ent), GFP_NOFS); if (!gentp) { CERROR("Can't allocate ndlist_ent\n"); lstcon_group_decref(grp); @@ -821,7 +820,7 @@ lstcon_group_info(char *name, struct lstcon_ndlist_ent __user *gents_p, rc = copy_to_user(gents_p, gentp, sizeof(struct lstcon_ndlist_ent)) ? -EFAULT : 0; - LIBCFS_FREE(gentp, sizeof(struct lstcon_ndlist_ent)); + kfree(gentp); lstcon_group_decref(grp); @@ -856,35 +855,35 @@ lstcon_batch_add(char *name) return rc; } - LIBCFS_ALLOC(bat, sizeof(struct lstcon_batch)); + bat = kzalloc(sizeof(struct lstcon_batch), GFP_NOFS); if (!bat) { CERROR("Can't allocate descriptor for batch %s\n", name); return -ENOMEM; } - LIBCFS_ALLOC(bat->bat_cli_hash, - sizeof(struct list_head) * LST_NODE_HASHSIZE); + bat->bat_cli_hash = kmalloc(sizeof(struct list_head) * LST_NODE_HASHSIZE, + GFP_KERNEL); if (!bat->bat_cli_hash) { CERROR("Can't allocate hash for batch %s\n", name); - LIBCFS_FREE(bat, sizeof(struct lstcon_batch)); + kfree(bat); return -ENOMEM; } - LIBCFS_ALLOC(bat->bat_srv_hash, - sizeof(struct list_head) * LST_NODE_HASHSIZE); + bat->bat_srv_hash = kmalloc(sizeof(struct list_head) * LST_NODE_HASHSIZE, + GFP_KERNEL); if (!bat->bat_srv_hash) { CERROR("Can't allocate hash for batch %s\n", name); - LIBCFS_FREE(bat->bat_cli_hash, LST_NODE_HASHSIZE); - LIBCFS_FREE(bat, sizeof(struct lstcon_batch)); + kfree(bat->bat_cli_hash); + kfree(bat); return -ENOMEM; } if (strlen(name) > sizeof(bat->bat_name) - 1) { - LIBCFS_FREE(bat->bat_srv_hash, LST_NODE_HASHSIZE); - LIBCFS_FREE(bat->bat_cli_hash, LST_NODE_HASHSIZE); - LIBCFS_FREE(bat, sizeof(struct lstcon_batch)); + kfree(bat->bat_srv_hash); + kfree(bat->bat_cli_hash); + kfree(bat); return -E2BIG; } strncpy(bat->bat_name, name, sizeof(bat->bat_name)); @@ -971,7 +970,7 @@ lstcon_batch_info(char *name, struct lstcon_test_batch_ent __user *ent_up, } /* non-verbose query */ - LIBCFS_ALLOC(entp, sizeof(struct lstcon_test_batch_ent)); + entp = kzalloc(sizeof(struct lstcon_test_batch_ent), GFP_NOFS); if (!entp) return -ENOMEM; @@ -993,7 +992,7 @@ lstcon_batch_info(char *name, struct lstcon_test_batch_ent __user *ent_up, rc = copy_to_user(ent_up, entp, sizeof(struct lstcon_test_batch_ent)) ? -EFAULT : 0; - LIBCFS_FREE(entp, sizeof(struct lstcon_test_batch_ent)); + kfree(entp); return rc; } @@ -1107,8 +1106,7 @@ lstcon_batch_destroy(struct lstcon_batch *bat) lstcon_group_decref(test->tes_src_grp); lstcon_group_decref(test->tes_dst_grp); - LIBCFS_FREE(test, offsetof(struct lstcon_test, - tes_param[test->tes_paramlen])); + kfree(test); } LASSERT(list_empty(&bat->bat_trans_list)); @@ -1134,11 +1132,9 @@ lstcon_batch_destroy(struct lstcon_batch *bat) LASSERT(list_empty(&bat->bat_srv_hash[i])); } - LIBCFS_FREE(bat->bat_cli_hash, - sizeof(struct list_head) * LST_NODE_HASHSIZE); - LIBCFS_FREE(bat->bat_srv_hash, - sizeof(struct list_head) * LST_NODE_HASHSIZE); - LIBCFS_FREE(bat, sizeof(struct lstcon_batch)); + kfree(bat->bat_cli_hash); + kfree(bat->bat_srv_hash); + kfree(bat); } static int @@ -1311,7 +1307,8 @@ lstcon_test_add(char *batch_name, int type, int loop, if (dst_grp->grp_userland) *retp = 1; - LIBCFS_ALLOC(test, offsetof(struct lstcon_test, tes_param[paramlen])); + test = kzalloc(offsetof(struct lstcon_test, tes_param[paramlen]), + GFP_KERNEL); if (!test) { CERROR("Can't allocate test descriptor\n"); rc = -ENOMEM; @@ -1357,8 +1354,7 @@ lstcon_test_add(char *batch_name, int type, int loop, /* hold groups so nobody can change them */ return rc; out: - if (test) - LIBCFS_FREE(test, offsetof(struct lstcon_test, tes_param[paramlen])); + kfree(test); if (dst_grp) lstcon_group_decref(dst_grp); @@ -1790,7 +1786,7 @@ lstcon_session_info(struct lst_sid __user *sid_up, int __user *key_up, if (console_session.ses_state != LST_SESSION_ACTIVE) return -ESRCH; - LIBCFS_ALLOC(entp, sizeof(*entp)); + entp = kzalloc(sizeof(*entp), GFP_NOFS); if (!entp) return -ENOMEM; @@ -1807,7 +1803,7 @@ lstcon_session_info(struct lst_sid __user *sid_up, int __user *key_up, copy_to_user(name_up, console_session.ses_name, len)) rc = -EFAULT; - LIBCFS_FREE(entp, sizeof(*entp)); + kfree(entp); return rc; } @@ -2027,8 +2023,8 @@ lstcon_console_init(void) INIT_LIST_HEAD(&console_session.ses_bat_list); INIT_LIST_HEAD(&console_session.ses_trans_list); - LIBCFS_ALLOC(console_session.ses_ndl_hash, - sizeof(struct list_head) * LST_GLOBAL_HASHSIZE); + console_session.ses_ndl_hash = + kmalloc(sizeof(struct list_head) * LST_GLOBAL_HASHSIZE, GFP_KERNEL); if (!console_session.ses_ndl_hash) return -ENOMEM; @@ -2041,8 +2037,7 @@ lstcon_console_init(void) rc = srpc_add_service(&lstcon_acceptor_service); LASSERT(rc != -EBUSY); if (rc) { - LIBCFS_FREE(console_session.ses_ndl_hash, - sizeof(struct list_head) * LST_GLOBAL_HASHSIZE); + kfree(console_session.ses_ndl_hash); return rc; } @@ -2064,8 +2059,7 @@ out: srpc_shutdown_service(&lstcon_acceptor_service); srpc_remove_service(&lstcon_acceptor_service); - LIBCFS_FREE(console_session.ses_ndl_hash, - sizeof(struct list_head) * LST_GLOBAL_HASHSIZE); + kfree(console_session.ses_ndl_hash); srpc_wait_service_shutdown(&lstcon_acceptor_service); @@ -2099,8 +2093,7 @@ lstcon_console_fini(void) for (i = 0; i < LST_NODE_HASHSIZE; i++) LASSERT(list_empty(&console_session.ses_ndl_hash[i])); - LIBCFS_FREE(console_session.ses_ndl_hash, - sizeof(struct list_head) * LST_GLOBAL_HASHSIZE); + kfree(console_session.ses_ndl_hash); srpc_wait_service_shutdown(&lstcon_acceptor_service); diff --git a/drivers/staging/lustre/lnet/selftest/framework.c b/drivers/staging/lustre/lnet/selftest/framework.c index fe889607ff3f..c7697f66f663 100644 --- a/drivers/staging/lustre/lnet/selftest/framework.c +++ b/drivers/staging/lustre/lnet/selftest/framework.c @@ -143,7 +143,7 @@ sfw_register_test(struct srpc_service *service, return -EEXIST; } - LIBCFS_ALLOC(tsc, sizeof(struct sfw_test_case)); + tsc = kzalloc(sizeof(struct sfw_test_case), GFP_NOFS); if (!tsc) return -ENOMEM; @@ -344,7 +344,7 @@ sfw_bid2batch(struct lst_bid bid) if (bat) return bat; - LIBCFS_ALLOC(bat, sizeof(struct sfw_batch)); + bat = kzalloc(sizeof(struct sfw_batch), GFP_NOFS); if (!bat) return NULL; @@ -447,7 +447,7 @@ sfw_make_session(struct srpc_mksn_reqst *request, struct srpc_mksn_reply *reply) } /* brand new or create by force */ - LIBCFS_ALLOC(sn, sizeof(struct sfw_session)); + sn = kzalloc(sizeof(struct sfw_session), GFP_NOFS); if (!sn) { CERROR("dropping RPC mksn under memory pressure\n"); return -ENOMEM; @@ -632,19 +632,19 @@ sfw_destroy_test_instance(struct sfw_test_instance *tsi) tsu = list_entry(tsi->tsi_units.next, struct sfw_test_unit, tsu_list); list_del(&tsu->tsu_list); - LIBCFS_FREE(tsu, sizeof(*tsu)); + kfree(tsu); } while (!list_empty(&tsi->tsi_free_rpcs)) { rpc = list_entry(tsi->tsi_free_rpcs.next, struct srpc_client_rpc, crpc_list); list_del(&rpc->crpc_list); - LIBCFS_FREE(rpc, srpc_client_rpc_size(rpc)); + kfree(rpc); } clean: sfw_unload_test(tsi); - LIBCFS_FREE(tsi, sizeof(*tsi)); + kfree(tsi); } static void @@ -662,7 +662,7 @@ sfw_destroy_batch(struct sfw_batch *tsb) sfw_destroy_test_instance(tsi); } - LIBCFS_FREE(tsb, sizeof(struct sfw_batch)); + kfree(tsb); } void @@ -680,7 +680,7 @@ sfw_destroy_session(struct sfw_session *sn) sfw_destroy_batch(batch); } - LIBCFS_FREE(sn, sizeof(*sn)); + kfree(sn); atomic_dec(&sfw_data.fw_nzombies); } @@ -740,7 +740,7 @@ sfw_add_test_instance(struct sfw_batch *tsb, struct srpc_server_rpc *rpc) int i; int rc; - LIBCFS_ALLOC(tsi, sizeof(*tsi)); + tsi = kzalloc(sizeof(*tsi), GFP_NOFS); if (!tsi) { CERROR("Can't allocate test instance for batch: %llu\n", tsb->bat_id.bat_id); @@ -763,7 +763,7 @@ sfw_add_test_instance(struct sfw_batch *tsb, struct srpc_server_rpc *rpc) rc = sfw_load_test(tsi); if (rc) { - LIBCFS_FREE(tsi, sizeof(*tsi)); + kfree(tsi); return rc; } @@ -795,7 +795,7 @@ sfw_add_test_instance(struct sfw_batch *tsb, struct srpc_server_rpc *rpc) sfw_unpack_id(id); for (j = 0; j < tsi->tsi_concur; j++) { - LIBCFS_ALLOC(tsu, sizeof(struct sfw_test_unit)); + tsu = kzalloc(sizeof(struct sfw_test_unit), GFP_NOFS); if (!tsu) { rc = -ENOMEM; CERROR("Can't allocate tsu for %d\n", @@ -941,15 +941,13 @@ sfw_create_test_rpc(struct sfw_test_unit *tsu, struct lnet_process_id peer, return 0; } -static int +static void sfw_run_test(struct swi_workitem *wi) { - struct sfw_test_unit *tsu = wi->swi_workitem.wi_data; + struct sfw_test_unit *tsu = container_of(wi, struct sfw_test_unit, tsu_worker); struct sfw_test_instance *tsi = tsu->tsu_instance; struct srpc_client_rpc *rpc = NULL; - LASSERT(wi == &tsu->tsu_worker); - if (tsi->tsi_ops->tso_prep_rpc(tsu, tsu->tsu_dest, &rpc)) { LASSERT(!rpc); goto test_done; @@ -975,7 +973,7 @@ sfw_run_test(struct swi_workitem *wi) rpc->crpc_timeout = rpc_timeout; srpc_post_rpc(rpc); spin_unlock(&rpc->crpc_lock); - return 0; + return; test_done: /* @@ -985,9 +983,7 @@ test_done: * - my batch is still active; no one can run it again now. * Cancel pending schedules and prevent future schedule attempts: */ - swi_exit_workitem(wi); sfw_test_unit_done(tsu); - return 1; } static int @@ -1016,8 +1012,8 @@ sfw_run_batch(struct sfw_batch *tsb) atomic_inc(&tsi->tsi_nactive); tsu->tsu_loop = tsi->tsi_loop; wi = &tsu->tsu_worker; - swi_init_workitem(wi, tsu, sfw_run_test, - lst_sched_test[lnet_cpt_of_nid(tsu->tsu_dest.nid)]); + swi_init_workitem(wi, sfw_run_test, + lst_test_wq[lnet_cpt_of_nid(tsu->tsu_dest.nid)]); swi_schedule_workitem(wi); } } @@ -1767,7 +1763,7 @@ sfw_shutdown(void) struct srpc_client_rpc, crpc_list); list_del(&rpc->crpc_list); - LIBCFS_FREE(rpc, srpc_client_rpc_size(rpc)); + kfree(rpc); } for (i = 0; ; i++) { @@ -1785,6 +1781,6 @@ sfw_shutdown(void) srpc_wait_service_shutdown(tsc->tsc_srv_service); list_del(&tsc->tsc_list); - LIBCFS_FREE(tsc, sizeof(*tsc)); + kfree(tsc); } } diff --git a/drivers/staging/lustre/lnet/selftest/module.c b/drivers/staging/lustre/lnet/selftest/module.c index 1d44d912f014..7359aa56d9b3 100644 --- a/drivers/staging/lustre/lnet/selftest/module.c +++ b/drivers/staging/lustre/lnet/selftest/module.c @@ -47,8 +47,8 @@ enum { static int lst_init_step = LST_INIT_NONE; -struct cfs_wi_sched *lst_sched_serial; -struct cfs_wi_sched **lst_sched_test; +struct workqueue_struct *lst_serial_wq; +struct workqueue_struct **lst_test_wq; static void lnet_selftest_exit(void) @@ -68,18 +68,16 @@ lnet_selftest_exit(void) case LST_INIT_WI_TEST: for (i = 0; i < cfs_cpt_number(lnet_cpt_table()); i++) { - if (!lst_sched_test[i]) + if (!lst_test_wq[i]) continue; - cfs_wi_sched_destroy(lst_sched_test[i]); + destroy_workqueue(lst_test_wq[i]); } - LIBCFS_FREE(lst_sched_test, - sizeof(lst_sched_test[0]) * - cfs_cpt_number(lnet_cpt_table())); - lst_sched_test = NULL; + kvfree(lst_test_wq); + lst_test_wq = NULL; /* fall through */ case LST_INIT_WI_SERIAL: - cfs_wi_sched_destroy(lst_sched_serial); - lst_sched_serial = NULL; + destroy_workqueue(lst_serial_wq); + lst_serial_wq = NULL; case LST_INIT_NONE: break; default: @@ -91,35 +89,45 @@ static int lnet_selftest_init(void) { int nscheds; - int rc; + int rc = -ENOMEM; int i; - rc = cfs_wi_sched_create("lst_s", lnet_cpt_table(), CFS_CPT_ANY, - 1, &lst_sched_serial); - if (rc) { + lst_serial_wq = alloc_ordered_workqueue("lst_s", 0); + if (!lst_serial_wq) { CERROR("Failed to create serial WI scheduler for LST\n"); - return rc; + return -ENOMEM; } lst_init_step = LST_INIT_WI_SERIAL; nscheds = cfs_cpt_number(lnet_cpt_table()); - LIBCFS_ALLOC(lst_sched_test, sizeof(lst_sched_test[0]) * nscheds); - if (!lst_sched_test) + lst_test_wq = kvmalloc_array(nscheds, sizeof(lst_test_wq[0]), + GFP_KERNEL | __GFP_ZERO); + if (!lst_test_wq) { + rc = -ENOMEM; goto error; + } lst_init_step = LST_INIT_WI_TEST; for (i = 0; i < nscheds; i++) { int nthrs = cfs_cpt_weight(lnet_cpt_table(), i); + struct workqueue_attrs attrs = {0}; + cpumask_var_t *mask = cfs_cpt_cpumask(lnet_cpt_table(), i); /* reserve at least one CPU for LND */ nthrs = max(nthrs - 1, 1); - rc = cfs_wi_sched_create("lst_t", lnet_cpt_table(), i, - nthrs, &lst_sched_test[i]); - if (rc) { + lst_test_wq[i] = alloc_workqueue("lst_t", WQ_UNBOUND, nthrs); + if (!lst_test_wq[i]) { CWARN("Failed to create CPU partition affinity WI scheduler %d for LST\n", i); + rc = -ENOMEM; goto error; } + + if (mask && alloc_cpumask_var(&attrs.cpumask, GFP_KERNEL)) { + cpumask_copy(attrs.cpumask, *mask); + apply_workqueue_attrs(lst_test_wq[i], &attrs); + free_cpumask_var(attrs.cpumask); + } } rc = srpc_startup(); diff --git a/drivers/staging/lustre/lnet/selftest/rpc.c b/drivers/staging/lustre/lnet/selftest/rpc.c index ab7e8a8e58b8..f8198ad1046e 100644 --- a/drivers/staging/lustre/lnet/selftest/rpc.c +++ b/drivers/staging/lustre/lnet/selftest/rpc.c @@ -68,7 +68,7 @@ srpc_serv_portal(int svc_id) } /* forward ref's */ -int srpc_handle_rpc(struct swi_workitem *wi); +void srpc_handle_rpc(struct swi_workitem *wi); void srpc_get_counters(struct srpc_counters *cnt) { @@ -113,7 +113,7 @@ srpc_free_bulk(struct srpc_bulk *bk) __free_page(pg); } - LIBCFS_FREE(bk, offsetof(struct srpc_bulk, bk_iovs[bk->bk_niov])); + kfree(bk); } struct srpc_bulk * @@ -125,8 +125,8 @@ srpc_alloc_bulk(int cpt, unsigned int bulk_off, unsigned int bulk_npg, LASSERT(bulk_npg > 0 && bulk_npg <= LNET_MAX_IOV); - LIBCFS_CPT_ALLOC(bk, lnet_cpt_table(), cpt, - offsetof(struct srpc_bulk, bk_iovs[bulk_npg])); + bk = kzalloc_cpt(offsetof(struct srpc_bulk, bk_iovs[bulk_npg]), + GFP_KERNEL, cpt); if (!bk) { CERROR("Can't allocate descriptor for %d pages\n", bulk_npg); return NULL; @@ -176,9 +176,9 @@ srpc_init_server_rpc(struct srpc_server_rpc *rpc, struct srpc_buffer *buffer) { memset(rpc, 0, sizeof(*rpc)); - swi_init_workitem(&rpc->srpc_wi, rpc, srpc_handle_rpc, + swi_init_workitem(&rpc->srpc_wi, srpc_handle_rpc, srpc_serv_is_framework(scd->scd_svc) ? - lst_sched_serial : lst_sched_test[scd->scd_cpt]); + lst_serial_wq : lst_test_wq[scd->scd_cpt]); rpc->srpc_ev.ev_fired = 1; /* no event expected now */ @@ -214,7 +214,7 @@ srpc_service_fini(struct srpc_service *svc) buf = list_entry(q->next, struct srpc_buffer, buf_list); list_del(&buf->buf_list); - LIBCFS_FREE(buf, sizeof(*buf)); + kfree(buf); } } @@ -225,7 +225,7 @@ srpc_service_fini(struct srpc_service *svc) struct srpc_server_rpc, srpc_list); list_del(&rpc->srpc_list); - LIBCFS_FREE(rpc, sizeof(*rpc)); + kfree(rpc); } } @@ -242,7 +242,7 @@ srpc_service_nrpcs(struct srpc_service *svc) max(nrpcs, SFW_FRWK_WI_MIN) : max(nrpcs, SFW_TEST_WI_MIN); } -int srpc_add_buffer(struct swi_workitem *wi); +void srpc_add_buffer(struct swi_workitem *wi); static int srpc_service_init(struct srpc_service *svc) @@ -277,11 +277,11 @@ srpc_service_init(struct srpc_service *svc) scd->scd_ev.ev_type = SRPC_REQUEST_RCVD; /* - * NB: don't use lst_sched_serial for adding buffer, + * NB: don't use lst_serial_wq for adding buffer, * see details in srpc_service_add_buffers() */ - swi_init_workitem(&scd->scd_buf_wi, scd, - srpc_add_buffer, lst_sched_test[i]); + swi_init_workitem(&scd->scd_buf_wi, + srpc_add_buffer, lst_test_wq[i]); if (i && srpc_serv_is_framework(svc)) { /* @@ -294,8 +294,7 @@ srpc_service_init(struct srpc_service *svc) } for (j = 0; j < nrpcs; j++) { - LIBCFS_CPT_ALLOC(rpc, lnet_cpt_table(), - i, sizeof(*rpc)); + rpc = kzalloc_cpt(sizeof(*rpc), GFP_NOFS, i); if (!rpc) { srpc_service_fini(svc); return -ENOMEM; @@ -508,16 +507,16 @@ __must_hold(&scd->scd_lock) list_del(&buf->buf_list); spin_unlock(&scd->scd_lock); - LIBCFS_FREE(buf, sizeof(*buf)); + kfree(buf); spin_lock(&scd->scd_lock); return rc; } -int +void srpc_add_buffer(struct swi_workitem *wi) { - struct srpc_service_cd *scd = wi->swi_workitem.wi_data; + struct srpc_service_cd *scd = container_of(wi, struct srpc_service_cd, scd_buf_wi); struct srpc_buffer *buf; int rc = 0; @@ -535,7 +534,7 @@ srpc_add_buffer(struct swi_workitem *wi) spin_unlock(&scd->scd_lock); - LIBCFS_ALLOC(buf, sizeof(*buf)); + buf = kzalloc(sizeof(*buf), GFP_NOFS); if (!buf) { CERROR("Failed to add new buf to service: %s\n", scd->scd_svc->sv_name); @@ -547,7 +546,7 @@ srpc_add_buffer(struct swi_workitem *wi) spin_lock(&scd->scd_lock); if (scd->scd_svc->sv_shuttingdown) { spin_unlock(&scd->scd_lock); - LIBCFS_FREE(buf, sizeof(*buf)); + kfree(buf); spin_lock(&scd->scd_lock); rc = -ESHUTDOWN; @@ -573,7 +572,6 @@ srpc_add_buffer(struct swi_workitem *wi) } spin_unlock(&scd->scd_lock); - return 0; } int @@ -605,15 +603,15 @@ srpc_service_add_buffers(struct srpc_service *sv, int nbuffer) spin_lock(&scd->scd_lock); /* * NB: srpc_service_add_buffers() can be called inside - * thread context of lst_sched_serial, and we don't normally + * thread context of lst_serial_wq, and we don't normally * allow to sleep inside thread context of WI scheduler * because it will block current scheduler thread from doing * anything else, even worse, it could deadlock if it's * waiting on result from another WI of the same scheduler. * However, it's safe at here because scd_buf_wi is scheduled - * by thread in a different WI scheduler (lst_sched_test), + * by thread in a different WI scheduler (lst_test_wq), * so we don't have any risk of deadlock, though this could - * block all WIs pending on lst_sched_serial for a moment + * block all WIs pending on lst_serial_wq for a moment * which is not good but not fatal. */ lst_wait_until(scd->scd_buf_err || @@ -660,11 +658,9 @@ srpc_finish_service(struct srpc_service *sv) LASSERT(sv->sv_shuttingdown); /* srpc_shutdown_service called */ cfs_percpt_for_each(scd, i, sv->sv_cpt_data) { + swi_cancel_workitem(&scd->scd_buf_wi); + spin_lock(&scd->scd_lock); - if (!swi_deschedule_workitem(&scd->scd_buf_wi)) { - spin_unlock(&scd->scd_lock); - return 0; - } if (scd->scd_buf_nposted > 0) { CDEBUG(D_NET, "waiting for %d posted buffers to unlink\n", @@ -680,11 +676,9 @@ srpc_finish_service(struct srpc_service *sv) rpc = list_entry(scd->scd_rpc_active.next, struct srpc_server_rpc, srpc_list); - CNETERR("Active RPC %p on shutdown: sv %s, peer %s, wi %s scheduled %d running %d, ev fired %d type %d status %d lnet %d\n", + CNETERR("Active RPC %p on shutdown: sv %s, peer %s, wi %s, ev fired %d type %d status %d lnet %d\n", rpc, sv->sv_name, libcfs_id2str(rpc->srpc_peer), swi_state2str(rpc->srpc_wi.swi_state), - rpc->srpc_wi.swi_workitem.wi_scheduled, - rpc->srpc_wi.swi_workitem.wi_running, rpc->srpc_ev.ev_fired, rpc->srpc_ev.ev_type, rpc->srpc_ev.ev_status, rpc->srpc_ev.ev_lnet); spin_unlock(&scd->scd_lock); @@ -725,7 +719,7 @@ __must_hold(&scd->scd_lock) } spin_unlock(&scd->scd_lock); - LIBCFS_FREE(buf, sizeof(*buf)); + kfree(buf); spin_lock(&scd->scd_lock); } @@ -947,7 +941,6 @@ srpc_server_rpc_done(struct srpc_server_rpc *rpc, int status) * Cancel pending schedules and prevent future schedule attempts: */ LASSERT(rpc->srpc_ev.ev_fired); - swi_exit_workitem(&rpc->srpc_wi); if (!sv->sv_shuttingdown && !list_empty(&scd->scd_buf_blocked)) { buffer = list_entry(scd->scd_buf_blocked.next, @@ -965,10 +958,10 @@ srpc_server_rpc_done(struct srpc_server_rpc *rpc, int status) } /* handles an incoming RPC */ -int +void srpc_handle_rpc(struct swi_workitem *wi) { - struct srpc_server_rpc *rpc = wi->swi_workitem.wi_data; + struct srpc_server_rpc *rpc = container_of(wi, struct srpc_server_rpc, srpc_wi); struct srpc_service_cd *scd = rpc->srpc_scd; struct srpc_service *sv = scd->scd_svc; struct srpc_event *ev = &rpc->srpc_ev; @@ -987,9 +980,8 @@ srpc_handle_rpc(struct swi_workitem *wi) if (ev->ev_fired) { /* no more event, OK to finish */ srpc_server_rpc_done(rpc, -ESHUTDOWN); - return 1; } - return 0; + return; } spin_unlock(&scd->scd_lock); @@ -1007,7 +999,7 @@ srpc_handle_rpc(struct swi_workitem *wi) if (!msg->msg_magic) { /* moaned already in srpc_lnet_ev_handler */ srpc_server_rpc_done(rpc, EBADMSG); - return 1; + return; } srpc_unpack_msg_hdr(msg); @@ -1023,7 +1015,7 @@ srpc_handle_rpc(struct swi_workitem *wi) LASSERT(!reply->status || !rpc->srpc_bulk); if (rc) { srpc_server_rpc_done(rpc, rc); - return 1; + return; } } @@ -1032,7 +1024,7 @@ srpc_handle_rpc(struct swi_workitem *wi) if (rpc->srpc_bulk) { rc = srpc_do_bulk(rpc); if (!rc) - return 0; /* wait for bulk */ + return; /* wait for bulk */ LASSERT(ev->ev_fired); ev->ev_status = rc; @@ -1050,16 +1042,16 @@ srpc_handle_rpc(struct swi_workitem *wi) if (rc) { srpc_server_rpc_done(rpc, rc); - return 1; + return; } } wi->swi_state = SWI_STATE_REPLY_SUBMITTED; rc = srpc_send_reply(rpc); if (!rc) - return 0; /* wait for reply */ + return; /* wait for reply */ srpc_server_rpc_done(rpc, rc); - return 1; + return; case SWI_STATE_REPLY_SUBMITTED: if (!ev->ev_fired) { @@ -1072,10 +1064,8 @@ srpc_handle_rpc(struct swi_workitem *wi) wi->swi_state = SWI_STATE_DONE; srpc_server_rpc_done(rpc, ev->ev_status); - return 1; + return; } - - return 0; } static void @@ -1170,7 +1160,6 @@ srpc_client_rpc_done(struct srpc_client_rpc *rpc, int status) * Cancel pending schedules and prevent future schedule attempts: */ LASSERT(!srpc_event_pending(rpc)); - swi_exit_workitem(wi); spin_unlock(&rpc->crpc_lock); @@ -1178,7 +1167,7 @@ srpc_client_rpc_done(struct srpc_client_rpc *rpc, int status) } /* sends an outgoing RPC */ -int +void srpc_send_rpc(struct swi_workitem *wi) { int rc = 0; @@ -1188,7 +1177,7 @@ srpc_send_rpc(struct swi_workitem *wi) LASSERT(wi); - rpc = wi->swi_workitem.wi_data; + rpc = container_of(wi, struct srpc_client_rpc, crpc_wi); LASSERT(rpc); LASSERT(wi == &rpc->crpc_wi); @@ -1214,7 +1203,7 @@ srpc_send_rpc(struct swi_workitem *wi) rc = srpc_prepare_reply(rpc); if (rc) { srpc_client_rpc_done(rpc, rc); - return 1; + return; } rc = srpc_prepare_bulk(rpc); @@ -1291,7 +1280,7 @@ srpc_send_rpc(struct swi_workitem *wi) wi->swi_state = SWI_STATE_DONE; srpc_client_rpc_done(rpc, rc); - return 1; + return; } if (rc) { @@ -1308,10 +1297,9 @@ abort: if (!srpc_event_pending(rpc)) { srpc_client_rpc_done(rpc, -EINTR); - return 1; + return; } } - return 0; } struct srpc_client_rpc * @@ -1322,8 +1310,8 @@ srpc_create_client_rpc(struct lnet_process_id peer, int service, { struct srpc_client_rpc *rpc; - LIBCFS_ALLOC(rpc, offsetof(struct srpc_client_rpc, - crpc_bulk.bk_iovs[nbulkiov])); + rpc = kzalloc(offsetof(struct srpc_client_rpc, + crpc_bulk.bk_iovs[nbulkiov]), GFP_KERNEL); if (!rpc) return NULL; diff --git a/drivers/staging/lustre/lnet/selftest/selftest.h b/drivers/staging/lustre/lnet/selftest/selftest.h index 8c10f0f149d5..ad04534f000c 100644 --- a/drivers/staging/lustre/lnet/selftest/selftest.h +++ b/drivers/staging/lustre/lnet/selftest/selftest.h @@ -169,11 +169,11 @@ struct srpc_buffer { }; struct swi_workitem; -typedef int (*swi_action_t) (struct swi_workitem *); +typedef void (*swi_action_t) (struct swi_workitem *); struct swi_workitem { - struct cfs_wi_sched *swi_sched; - struct cfs_workitem swi_workitem; + struct workqueue_struct *swi_wq; + struct work_struct swi_work; swi_action_t swi_action; int swi_state; }; @@ -444,7 +444,7 @@ void srpc_free_bulk(struct srpc_bulk *bk); struct srpc_bulk *srpc_alloc_bulk(int cpt, unsigned int off, unsigned int bulk_npg, unsigned int bulk_len, int sink); -int srpc_send_rpc(struct swi_workitem *wi); +void srpc_send_rpc(struct swi_workitem *wi); int srpc_send_reply(struct srpc_server_rpc *rpc); int srpc_add_service(struct srpc_service *sv); int srpc_remove_service(struct srpc_service *sv); @@ -456,8 +456,8 @@ void srpc_service_remove_buffers(struct srpc_service *sv, int nbuffer); void srpc_get_counters(struct srpc_counters *cnt); void srpc_set_counters(const struct srpc_counters *cnt); -extern struct cfs_wi_sched *lst_sched_serial; -extern struct cfs_wi_sched **lst_sched_test; +extern struct workqueue_struct *lst_serial_wq; +extern struct workqueue_struct **lst_test_wq; static inline int srpc_serv_is_framework(struct srpc_service *svc) @@ -465,42 +465,36 @@ srpc_serv_is_framework(struct srpc_service *svc) return svc->sv_id < SRPC_FRAMEWORK_SERVICE_MAX_ID; } -static inline int -swi_wi_action(struct cfs_workitem *wi) +static void +swi_wi_action(struct work_struct *wi) { struct swi_workitem *swi; - swi = container_of(wi, struct swi_workitem, swi_workitem); + swi = container_of(wi, struct swi_workitem, swi_work); - return swi->swi_action(swi); + swi->swi_action(swi); } static inline void -swi_init_workitem(struct swi_workitem *swi, void *data, - swi_action_t action, struct cfs_wi_sched *sched) +swi_init_workitem(struct swi_workitem *swi, + swi_action_t action, struct workqueue_struct *wq) { - swi->swi_sched = sched; + swi->swi_wq = wq; swi->swi_action = action; swi->swi_state = SWI_STATE_NEWBORN; - cfs_wi_init(&swi->swi_workitem, data, swi_wi_action); + INIT_WORK(&swi->swi_work, swi_wi_action); } static inline void swi_schedule_workitem(struct swi_workitem *wi) { - cfs_wi_schedule(wi->swi_sched, &wi->swi_workitem); -} - -static inline void -swi_exit_workitem(struct swi_workitem *swi) -{ - cfs_wi_exit(swi->swi_sched, &swi->swi_workitem); + queue_work(wi->swi_wq, &wi->swi_work); } static inline int -swi_deschedule_workitem(struct swi_workitem *swi) +swi_cancel_workitem(struct swi_workitem *swi) { - return cfs_wi_deschedule(swi->swi_sched, &swi->swi_workitem); + return cancel_work_sync(&swi->swi_work); } int sfw_startup(void); @@ -516,7 +510,7 @@ srpc_destroy_client_rpc(struct srpc_client_rpc *rpc) LASSERT(!atomic_read(&rpc->crpc_refcount)); if (!rpc->crpc_fini) - LIBCFS_FREE(rpc, srpc_client_rpc_size(rpc)); + kfree(rpc); else (*rpc->crpc_fini)(rpc); } @@ -533,8 +527,8 @@ srpc_init_client_rpc(struct srpc_client_rpc *rpc, struct lnet_process_id peer, crpc_bulk.bk_iovs[nbulkiov])); INIT_LIST_HEAD(&rpc->crpc_list); - swi_init_workitem(&rpc->crpc_wi, rpc, srpc_send_rpc, - lst_sched_test[lnet_cpt_of_nid(peer.nid)]); + swi_init_workitem(&rpc->crpc_wi, srpc_send_rpc, + lst_test_wq[lnet_cpt_of_nid(peer.nid)]); spin_lock_init(&rpc->crpc_lock); atomic_set(&rpc->crpc_refcount, 1); /* 1 ref for caller */ diff --git a/drivers/staging/lustre/lustre/fld/fld_cache.c b/drivers/staging/lustre/lustre/fld/fld_cache.c index 7d6a7106c0a5..ecf8b9e1ed5c 100644 --- a/drivers/staging/lustre/lustre/fld/fld_cache.c +++ b/drivers/staging/lustre/lustre/fld/fld_cache.c @@ -213,19 +213,18 @@ static inline void fld_cache_entry_add(struct fld_cache *cache, */ static int fld_cache_shrink(struct fld_cache *cache) { - struct fld_cache_entry *flde; - struct list_head *curr; int num = 0; if (cache->fci_cache_count < cache->fci_cache_size) return 0; - curr = cache->fci_lru.prev; - while (cache->fci_cache_count + cache->fci_threshold > - cache->fci_cache_size && curr != &cache->fci_lru) { - flde = list_entry(curr, struct fld_cache_entry, fce_lru); - curr = curr->prev; + cache->fci_cache_size && + !list_empty(&cache->fci_lru)) { + struct fld_cache_entry *flde = + list_last_entry(&cache->fci_lru, + struct fld_cache_entry, fce_lru); + fld_cache_entry_delete(cache, flde); num++; } diff --git a/drivers/staging/lustre/lustre/include/lustre_disk.h b/drivers/staging/lustre/lustre/include/lustre_disk.h index 8f1a22527006..100e993ab00b 100644 --- a/drivers/staging/lustre/lustre/include/lustre_disk.h +++ b/drivers/staging/lustre/lustre/include/lustre_disk.h @@ -141,9 +141,9 @@ struct lustre_sb_info { /* obd_mount.c */ int lustre_start_mgc(struct super_block *sb); -void lustre_register_client_fill_super(int (*cfs)(struct super_block *sb, - struct vfsmount *mnt)); -void lustre_register_kill_super_cb(void (*cfs)(struct super_block *sb)); +void lustre_register_super_ops(struct module *mod, + int (*cfs)(struct super_block *sb), + void (*ksc)(struct super_block *sb)); int lustre_common_put_super(struct super_block *sb); int mgc_fsname2resid(char *fsname, struct ldlm_res_id *res_id, int type); diff --git a/drivers/staging/lustre/lustre/include/lustre_sec.h b/drivers/staging/lustre/lustre/include/lustre_sec.h index a40f706a53a1..64b6fd4fed8f 100644 --- a/drivers/staging/lustre/lustre/include/lustre_sec.h +++ b/drivers/staging/lustre/lustre/include/lustre_sec.h @@ -341,8 +341,8 @@ void sptlrpc_conf_client_adapt(struct obd_device *obd); #define SPTLRPC_MAX_PAYLOAD (1024) struct vfs_cred { - uint32_t vc_uid; - uint32_t vc_gid; + u32 vc_uid; + u32 vc_gid; }; struct ptlrpc_ctx_ops { diff --git a/drivers/staging/lustre/lustre/include/obd_class.h b/drivers/staging/lustre/lustre/include/obd_class.h index 67c535c5aa98..531e8ddfa9e5 100644 --- a/drivers/staging/lustre/lustre/include/obd_class.h +++ b/drivers/staging/lustre/lustre/include/obd_class.h @@ -40,22 +40,19 @@ #include <lustre_lib.h> #include <lprocfs_status.h> -#define OBD_STATFS_NODELAY 0x0001 /* requests should be send without delay - * and resends for avoid deadlocks - */ -#define OBD_STATFS_FROM_CACHE 0x0002 /* the statfs callback should not update - * obd_osfs_age - */ -#define OBD_STATFS_FOR_MDT0 0x0004 /* The statfs is only for retrieving - * information from MDT0. - */ +/* requests should be send without delay and resends for avoid deadlocks */ +#define OBD_STATFS_NODELAY 0x0001 +/* the statfs callback should not update obd_osfs_age */ +#define OBD_STATFS_FROM_CACHE 0x0002 +/* the statfs is only for retrieving information from MDT0 */ +#define OBD_STATFS_FOR_MDT0 0x0004 /* OBD Device Declarations */ extern struct obd_device *obd_devs[MAX_OBD_DEVICES]; extern rwlock_t obd_dev_lock; /* OBD Operations Declarations */ -struct obd_device *class_exp2obd(struct obd_export *); +struct obd_device *class_exp2obd(struct obd_export *exp); int class_handle_ioctl(unsigned int cmd, unsigned long arg); int lustre_get_jobid(char *jobid); @@ -63,10 +60,10 @@ struct lu_device_type; /* genops.c */ extern struct list_head obd_types; -struct obd_export *class_conn2export(struct lustre_handle *); -int class_register_type(struct obd_ops *, struct md_ops *, - const char *nm, struct lu_device_type *ldt); -int class_unregister_type(const char *nm); +struct obd_export *class_conn2export(struct lustre_handle *conn); +int class_register_type(struct obd_ops *dt_ops, struct md_ops *md_ops, + const char *name, struct lu_device_type *ldt); +int class_unregister_type(const char *name); struct obd_device *class_newdev(const char *type_name, const char *name); void class_release_dev(struct obd_device *obd); @@ -137,7 +134,7 @@ int class_config_llog_handler(const struct lu_env *env, struct llog_rec_hdr *rec, void *data); int class_add_uuid(const char *uuid, __u64 nid); -/*obdecho*/ +/* obdecho */ void lprocfs_echo_init_vars(struct lprocfs_static_vars *lvars); #define CFG_F_START 0x01 /* Set when we start updating from a log */ @@ -148,13 +145,13 @@ void lprocfs_echo_init_vars(struct lprocfs_static_vars *lvars); /* Passed as data param to class_config_parse_llog */ struct config_llog_instance { - char *cfg_obdname; - void *cfg_instance; + char *cfg_obdname; + void *cfg_instance; struct super_block *cfg_sb; struct obd_uuid cfg_uuid; llog_cb_t cfg_callback; - int cfg_last_idx; /* for partial llog processing */ - int cfg_flags; + int cfg_last_idx; /* for partial llog processing */ + int cfg_flags; }; int class_config_parse_llog(const struct lu_env *env, struct llog_ctxt *ctxt, @@ -172,30 +169,31 @@ enum { /* list of active configuration logs */ struct config_llog_data { - struct ldlm_res_id cld_resid; + struct ldlm_res_id cld_resid; struct config_llog_instance cld_cfg; - struct list_head cld_list_chain; - atomic_t cld_refcount; + struct list_head cld_list_chain; + atomic_t cld_refcount; struct config_llog_data *cld_sptlrpc;/* depended sptlrpc log */ struct config_llog_data *cld_params; /* common parameters log */ struct config_llog_data *cld_recover;/* imperative recover log */ - struct obd_export *cld_mgcexp; + struct obd_export *cld_mgcexp; struct mutex cld_lock; - int cld_type; - unsigned int cld_stopping:1, /* we were told to stop - * watching - */ - cld_lostlock:1; /* lock not requeued */ - char cld_logname[0]; + int cld_type; + unsigned int cld_stopping:1, /* + * we were told to stop + * watching + */ + cld_lostlock:1; /* lock not requeued */ + char cld_logname[0]; }; struct lustre_profile { - struct list_head lp_list; - char *lp_profile; - char *lp_dt; - char *lp_md; - int lp_refs; - bool lp_list_deleted; + struct list_head lp_list; + char *lp_profile; + char *lp_dt; + char *lp_md; + int lp_refs; + bool lp_list_deleted; }; struct lustre_profile *class_get_profile(const char *prof); @@ -205,9 +203,11 @@ void class_del_profiles(void); #if LUSTRE_TRACKS_LOCK_EXP_REFS -void __class_export_add_lock_ref(struct obd_export *, struct ldlm_lock *); -void __class_export_del_lock_ref(struct obd_export *, struct ldlm_lock *); -extern void (*class_export_dump_hook)(struct obd_export *); +void __class_export_add_lock_ref(struct obd_export *exp, + struct ldlm_lock *lock); +void __class_export_del_lock_ref(struct obd_export *exp, + struct ldlm_lock *lock); +extern void (*class_export_dump_hook)(struct obd_export *exp); #else @@ -223,8 +223,8 @@ struct obd_export *class_new_export(struct obd_device *obddev, struct obd_uuid *cluuid); void class_unlink_export(struct obd_export *exp); -struct obd_import *class_import_get(struct obd_import *); -void class_import_put(struct obd_import *); +struct obd_import *class_import_get(struct obd_import *imp); +void class_import_put(struct obd_import *imp); struct obd_import *class_new_import(struct obd_device *obd); void class_destroy_import(struct obd_import *exp); @@ -299,7 +299,8 @@ void obdo_to_ioobj(const struct obdo *oa, struct obd_ioobj *ioobj); #define MDP(dev, op) (dev)->obd_type->typ_md_ops->op #define CTXTP(ctxt, op) (ctxt)->loc_logops->lop_##op -/* Ensure obd_setup: used for cleanup which must be called +/* + * Ensure obd_setup: used for cleanup which must be called * while obd is stopping */ static inline int obd_check_dev(struct obd_device *obd) @@ -326,108 +327,116 @@ static inline int obd_check_dev_active(struct obd_device *obd) return rc; } -#define OBD_COUNTER_OFFSET(op) \ - ((offsetof(struct obd_ops, op) - \ - offsetof(struct obd_ops, iocontrol)) \ - / sizeof(((struct obd_ops *)(0))->iocontrol)) - -#define OBD_COUNTER_INCREMENT(obdx, op) \ - if ((obdx)->obd_stats) { \ - unsigned int coffset; \ - coffset = (unsigned int)((obdx)->obd_cntr_base) + \ - OBD_COUNTER_OFFSET(op); \ - LASSERT(coffset < (obdx)->obd_stats->ls_num); \ - lprocfs_counter_incr((obdx)->obd_stats, coffset); \ - } +#define OBD_COUNTER_OFFSET(op) \ + ((offsetof(struct obd_ops, op) - \ + offsetof(struct obd_ops, iocontrol)) \ + / sizeof(((struct obd_ops *)(0))->iocontrol)) -#define EXP_COUNTER_INCREMENT(export, op) \ - if ((export)->exp_obd->obd_stats) { \ +#define OBD_COUNTER_INCREMENT(obdx, op) \ +do { \ + if ((obdx)->obd_stats) { \ unsigned int coffset; \ + coffset = (unsigned int)((obdx)->obd_cntr_base) + \ + OBD_COUNTER_OFFSET(op); \ + LASSERT(coffset < (obdx)->obd_stats->ls_num); \ + lprocfs_counter_incr((obdx)->obd_stats, coffset); \ + } \ +} while (0) + +#define EXP_COUNTER_INCREMENT(export, op) \ +do { \ + if ((export)->exp_obd->obd_stats) { \ + unsigned int coffset; \ coffset = (unsigned int)((export)->exp_obd->obd_cntr_base) + \ - OBD_COUNTER_OFFSET(op); \ + OBD_COUNTER_OFFSET(op); \ LASSERT(coffset < (export)->exp_obd->obd_stats->ls_num); \ lprocfs_counter_incr((export)->exp_obd->obd_stats, coffset); \ - } + } \ +} while (0) -#define MD_COUNTER_OFFSET(op) \ - ((offsetof(struct md_ops, op) - \ - offsetof(struct md_ops, getstatus)) \ - / sizeof(((struct md_ops *)(0))->getstatus)) +#define MD_COUNTER_OFFSET(op) \ + ((offsetof(struct md_ops, op) - \ + offsetof(struct md_ops, getstatus)) \ + / sizeof(((struct md_ops *)(0))->getstatus)) -#define MD_COUNTER_INCREMENT(obdx, op) \ - if ((obd)->md_stats) { \ - unsigned int coffset; \ +#define MD_COUNTER_INCREMENT(obdx, op) \ +do { \ + if ((obd)->md_stats) { \ + unsigned int coffset; \ coffset = (unsigned int)((obdx)->md_cntr_base) + \ - MD_COUNTER_OFFSET(op); \ - LASSERT(coffset < (obdx)->md_stats->ls_num); \ + MD_COUNTER_OFFSET(op); \ + LASSERT(coffset < (obdx)->md_stats->ls_num); \ lprocfs_counter_incr((obdx)->md_stats, coffset); \ - } + } \ +} while (0) -#define EXP_MD_COUNTER_INCREMENT(export, op) \ - if ((export)->exp_obd->obd_stats) { \ - unsigned int coffset; \ - coffset = (unsigned int)((export)->exp_obd->md_cntr_base) + \ - MD_COUNTER_OFFSET(op); \ - LASSERT(coffset < (export)->exp_obd->md_stats->ls_num); \ - lprocfs_counter_incr((export)->exp_obd->md_stats, coffset); \ - if ((export)->exp_md_stats) \ - lprocfs_counter_incr( \ +#define EXP_MD_COUNTER_INCREMENT(export, op) \ +do { \ + if ((export)->exp_obd->obd_stats) { \ + unsigned int coffset; \ + coffset = (unsigned int)((export)->exp_obd->md_cntr_base) + \ + MD_COUNTER_OFFSET(op); \ + LASSERT(coffset < (export)->exp_obd->md_stats->ls_num); \ + lprocfs_counter_incr((export)->exp_obd->md_stats, coffset); \ + if ((export)->exp_md_stats) \ + lprocfs_counter_incr( \ (export)->exp_md_stats, coffset); \ - } + } \ +} while (0) #define EXP_CHECK_MD_OP(exp, op) \ -do { \ - if (!(exp)) { \ - CERROR("obd_" #op ": NULL export\n"); \ - return -ENODEV; \ - } \ - if (!(exp)->exp_obd || !OBT((exp)->exp_obd)) { \ +do { \ + if (!(exp)) { \ + CERROR("obd_" #op ": NULL export\n"); \ + return -ENODEV; \ + } \ + if (!(exp)->exp_obd || !OBT((exp)->exp_obd)) { \ CERROR("obd_" #op ": cleaned up obd\n"); \ - return -EOPNOTSUPP; \ - } \ - if (!OBT((exp)->exp_obd) || !MDP((exp)->exp_obd, op)) { \ + return -EOPNOTSUPP; \ + } \ + if (!OBT((exp)->exp_obd) || !MDP((exp)->exp_obd, op)) { \ CERROR("obd_" #op ": dev %s/%d no operation\n", \ - (exp)->exp_obd->obd_name, \ - (exp)->exp_obd->obd_minor); \ - return -EOPNOTSUPP; \ - } \ + (exp)->exp_obd->obd_name, \ + (exp)->exp_obd->obd_minor); \ + return -EOPNOTSUPP; \ + } \ } while (0) -#define OBD_CHECK_DT_OP(obd, op, err) \ -do { \ - if (!OBT(obd) || !OBP((obd), op)) { \ - if (err) \ - CERROR("obd_" #op ": dev %d no operation\n", \ - obd->obd_minor); \ - return err; \ - } \ +#define OBD_CHECK_DT_OP(obd, op, err) \ +do { \ + if (!OBT(obd) || !OBP((obd), op)) { \ + if (err) \ + CERROR("obd_" #op ": dev %d no operation\n", \ + obd->obd_minor); \ + return err; \ + } \ } while (0) #define EXP_CHECK_DT_OP(exp, op) \ -do { \ - if (!(exp)) { \ - CERROR("obd_" #op ": NULL export\n"); \ - return -ENODEV; \ - } \ - if (!(exp)->exp_obd || !OBT((exp)->exp_obd)) { \ +do { \ + if (!(exp)) { \ + CERROR("obd_" #op ": NULL export\n"); \ + return -ENODEV; \ + } \ + if (!(exp)->exp_obd || !OBT((exp)->exp_obd)) { \ CERROR("obd_" #op ": cleaned up obd\n"); \ - return -EOPNOTSUPP; \ - } \ - if (!OBT((exp)->exp_obd) || !OBP((exp)->exp_obd, op)) { \ - CERROR("obd_" #op ": dev %d no operation\n", \ - (exp)->exp_obd->obd_minor); \ - return -EOPNOTSUPP; \ - } \ + return -EOPNOTSUPP; \ + } \ + if (!OBT((exp)->exp_obd) || !OBP((exp)->exp_obd, op)) { \ + CERROR("obd_" #op ": dev %d no operation\n", \ + (exp)->exp_obd->obd_minor); \ + return -EOPNOTSUPP; \ + } \ } while (0) -#define CTXT_CHECK_OP(ctxt, op, err) \ -do { \ - if (!OBT(ctxt->loc_obd) || !CTXTP((ctxt), op)) { \ - if (err) \ - CERROR("lop_" #op ": dev %d no operation\n", \ - ctxt->loc_obd->obd_minor); \ - return err; \ - } \ +#define CTXT_CHECK_OP(ctxt, op, err) \ +do { \ + if (!OBT(ctxt->loc_obd) || !CTXTP((ctxt), op)) { \ + if (err) \ + CERROR("lop_" #op ": dev %d no operation\n", \ + ctxt->loc_obd->obd_minor); \ + return err; \ + } \ } while (0) static inline int class_devno_max(void) @@ -481,14 +490,11 @@ static inline int obd_set_info_async(const struct lu_env *env, * obd_precleanup() and obd_cleanup() call both lu_device and obd operations. */ -#define DECLARE_LU_VARS(ldt, d) \ - struct lu_device_type *ldt; \ - struct lu_device *d - static inline int obd_setup(struct obd_device *obd, struct lustre_cfg *cfg) { int rc; - DECLARE_LU_VARS(ldt, d); + struct lu_device_type *ldt; + struct lu_device *d; ldt = obd->obd_type->typ_lu; if (ldt) { @@ -526,7 +532,8 @@ static inline int obd_setup(struct obd_device *obd, struct lustre_cfg *cfg) static inline int obd_precleanup(struct obd_device *obd) { int rc; - DECLARE_LU_VARS(ldt, d); + struct lu_device_type *ldt; + struct lu_device *d; rc = obd_check_dev(obd); if (rc) @@ -552,7 +559,8 @@ static inline int obd_precleanup(struct obd_device *obd) static inline int obd_cleanup(struct obd_device *obd) { int rc; - DECLARE_LU_VARS(ldt, d); + struct lu_device_type *ldt; + struct lu_device *d; rc = obd_check_dev(obd); if (rc) @@ -579,7 +587,8 @@ static inline int obd_cleanup(struct obd_device *obd) static inline void obd_cleanup_client_import(struct obd_device *obd) { - /* If we set up but never connected, the + /* + * If we set up but never connected, the * client import will not have been cleaned. */ down_write(&obd->u.cli.cl_sem); @@ -600,7 +609,8 @@ static inline int obd_process_config(struct obd_device *obd, int datalen, void *data) { int rc; - DECLARE_LU_VARS(ldt, d); + struct lu_device_type *ldt; + struct lu_device *d; rc = obd_check_dev(obd); if (rc) @@ -717,7 +727,8 @@ static inline struct obd_uuid *obd_get_uuid(struct obd_export *exp) return uuid; } -/** Create a new /a exp on device /a obd for the uuid /a cluuid +/* + * Create a new /a exp on device /a obd for the uuid /a cluuid * @param exp New export handle * @param d Connect data, supported flags are set, flags also understood * by obd are returned. @@ -729,7 +740,8 @@ static inline int obd_connect(const struct lu_env *env, void *localdata) { int rc; - __u64 ocf = data ? data->ocd_connect_flags : 0; /* for post-condition + __u64 ocf = data ? data->ocd_connect_flags : 0; /* + * for post-condition * check */ @@ -838,7 +850,9 @@ static inline int obd_pool_del(struct obd_device *obd, char *poolname) return rc; } -static inline int obd_pool_add(struct obd_device *obd, char *poolname, char *ostname) +static inline int obd_pool_add(struct obd_device *obd, + char *poolname, + char *ostname) { int rc; @@ -849,7 +863,9 @@ static inline int obd_pool_add(struct obd_device *obd, char *poolname, char *ost return rc; } -static inline int obd_pool_rem(struct obd_device *obd, char *poolname, char *ostname) +static inline int obd_pool_rem(struct obd_device *obd, + char *poolname, + char *ostname) { int rc; @@ -894,7 +910,8 @@ static inline int obd_destroy_export(struct obd_export *exp) return 0; } -/* @max_age is the oldest time in jiffies that we accept using a cached data. +/* + * @max_age is the oldest time in jiffies that we accept using a cached data. * If the cache is older than @max_age we will get a new value from the * target. Use a value of "cfs_time_current() + HZ" to guarantee freshness. */ @@ -955,7 +972,8 @@ static inline int obd_statfs_rqset(struct obd_export *exp, return rc; } -/* @max_age is the oldest time in jiffies that we accept using a cached data. +/* + * @max_age is the oldest time in jiffies that we accept using a cached data. * If the cache is older than @max_age we will get a new value from the * target. Use a value of "cfs_time_current() + HZ" to guarantee freshness. */ @@ -983,7 +1001,8 @@ static inline int obd_statfs(const struct lu_env *env, struct obd_export *exp, spin_unlock(&obd->obd_osfs_lock); } } else { - CDEBUG(D_SUPER, "%s: use %p cache blocks %llu/%llu objects %llu/%llu\n", + CDEBUG(D_SUPER, + "%s: use %p cache blocks %llu/%llu objects %llu/%llu\n", obd->obd_name, &obd->obd_osfs, obd->obd_osfs.os_bavail, obd->obd_osfs.os_blocks, obd->obd_osfs.os_ffree, obd->obd_osfs.os_files); @@ -1118,7 +1137,8 @@ static inline int obd_quotactl(struct obd_export *exp, static inline int obd_health_check(const struct lu_env *env, struct obd_device *obd) { - /* returns: 0 on healthy + /* + * returns: 0 on healthy * >0 on unhealthy + reason code/flag * however the only supported reason == 1 right now * We'll need to define some better reasons @@ -1491,7 +1511,8 @@ static inline int md_get_fid_from_lsm(struct obd_export *exp, return rc; } -/* Unpack an MD struct from disk to in-memory format. +/* + * Unpack an MD struct from disk to in-memory format. * Returns +ve size of unpacked MD (0 for free), or -ve error. * * If *plsm != NULL and lmm == NULL then *lsm will be freed. @@ -1523,11 +1544,12 @@ struct lwp_register_item { struct obd_export **lri_exp; register_lwp_cb lri_cb_func; void *lri_cb_data; - struct list_head lri_list; + struct list_head lri_list; char lri_name[MTI_NAME_MAXLEN]; }; -/* I'm as embarrassed about this as you are. +/* + * I'm as embarrassed about this as you are. * * <shaver> // XXX do not look into _superhack with remaining eye * <shaver> // XXX if this were any uglier, I'd get my own show on MTV @@ -1562,7 +1584,8 @@ int class_procfs_init(void); int class_procfs_clean(void); /* prng.c */ -#define ll_generate_random_uuid(uuid_out) cfs_get_random_bytes(uuid_out, sizeof(class_uuid_t)) +#define ll_generate_random_uuid(uuid_out) \ + get_random_bytes(uuid_out, sizeof(class_uuid_t)) /* statfs_pack.c */ struct kstatfs; diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c b/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c index fac9d19d50b6..11b11b5f3216 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_extent.c @@ -64,7 +64,6 @@ __u64 ldlm_extent_shift_kms(struct ldlm_lock *lock, __u64 old_kms) { struct ldlm_resource *res = lock->l_resource; - struct list_head *tmp; struct ldlm_lock *lck; __u64 kms = 0; @@ -74,8 +73,7 @@ __u64 ldlm_extent_shift_kms(struct ldlm_lock *lock, __u64 old_kms) */ ldlm_set_kms_ignore(lock); - list_for_each(tmp, &res->lr_granted) { - lck = list_entry(tmp, struct ldlm_lock, l_res_link); + list_for_each_entry(lck, &res->lr_granted, l_res_link) { if (ldlm_is_kms_ignore(lck)) continue; diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c index 7cb61e2e7d3b..7cbc6a06afec 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c @@ -886,17 +886,15 @@ static void search_granted_lock(struct list_head *queue, struct ldlm_lock *req, struct sl_insert_point *prev) { - struct list_head *tmp; struct ldlm_lock *lock, *mode_end, *policy_end; - list_for_each(tmp, queue) { - lock = list_entry(tmp, struct ldlm_lock, l_res_link); + list_for_each_entry(lock, queue, l_res_link) { mode_end = list_prev_entry(lock, l_sl_mode); if (lock->l_req_mode != req->l_req_mode) { /* jump to last lock of mode group */ - tmp = &mode_end->l_res_link; + lock = mode_end; continue; } @@ -933,9 +931,7 @@ static void search_granted_lock(struct list_head *queue, break; /* go to next policy group within mode group */ - tmp = policy_end->l_res_link.next; - lock = list_entry(tmp, struct ldlm_lock, - l_res_link); + lock = list_next_entry(policy_end, l_res_link); } /* loop over policy groups within the mode group */ /* insert point is last lock of the mode group, @@ -1687,7 +1683,7 @@ ldlm_work_bl_ast_lock(struct ptlrpc_request_set *rqset, void *opaq) if (list_empty(arg->list)) return -ENOENT; - lock = list_entry(arg->list->next, struct ldlm_lock, l_bl_ast); + lock = list_first_entry(arg->list, struct ldlm_lock, l_bl_ast); /* nobody should touch l_bl_ast */ lock_res_and_lock(lock); @@ -1723,7 +1719,7 @@ ldlm_work_cp_ast_lock(struct ptlrpc_request_set *rqset, void *opaq) if (list_empty(arg->list)) return -ENOENT; - lock = list_entry(arg->list->next, struct ldlm_lock, l_cp_ast); + lock = list_first_entry(arg->list, struct ldlm_lock, l_cp_ast); /* It's possible to receive a completion AST before we've set * the l_completion_ast pointer: either because the AST arrived @@ -1769,7 +1765,7 @@ ldlm_work_revoke_ast_lock(struct ptlrpc_request_set *rqset, void *opaq) if (list_empty(arg->list)) return -ENOENT; - lock = list_entry(arg->list->next, struct ldlm_lock, l_rk_ast); + lock = list_first_entry(arg->list, struct ldlm_lock, l_rk_ast); list_del_init(&lock->l_rk_ast); /* the desc just pretend to exclusive */ @@ -1796,7 +1792,7 @@ static int ldlm_work_gl_ast_lock(struct ptlrpc_request_set *rqset, void *opaq) if (list_empty(arg->list)) return -ENOENT; - gl_work = list_entry(arg->list->next, struct ldlm_glimpse_work, + gl_work = list_first_entry(arg->list, struct ldlm_glimpse_work, gl_list); list_del_init(&gl_work->gl_list); diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c index 2d5a2c932ddc..5f6e7c933b81 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c @@ -696,13 +696,13 @@ static int ldlm_bl_get_work(struct ldlm_bl_pool *blp, /* process a request from the blp_list at least every blp_num_threads */ if (!list_empty(&blp->blp_list) && (list_empty(&blp->blp_prio_list) || num_bl == 0)) - blwi = list_entry(blp->blp_list.next, - struct ldlm_bl_work_item, blwi_entry); + blwi = list_first_entry(&blp->blp_list, + struct ldlm_bl_work_item, blwi_entry); else if (!list_empty(&blp->blp_prio_list)) - blwi = list_entry(blp->blp_prio_list.next, - struct ldlm_bl_work_item, - blwi_entry); + blwi = list_first_entry(&blp->blp_prio_list, + struct ldlm_bl_work_item, + blwi_entry); if (blwi) { if (++num_bl >= num_th) @@ -1093,8 +1093,10 @@ static int ldlm_cleanup(void) kset_unregister(ldlm_ns_kset); if (ldlm_svc_kset) kset_unregister(ldlm_svc_kset); - if (ldlm_kobj) + if (ldlm_kobj) { + sysfs_remove_group(ldlm_kobj, &ldlm_attr_group); kobject_put(ldlm_kobj); + } ldlm_debugfs_cleanup(); diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c index da65d00a7811..8563bd32befa 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_pool.c @@ -1086,8 +1086,12 @@ int ldlm_pools_init(void) int rc; rc = ldlm_pools_thread_start(); - if (rc == 0) - register_shrinker(&ldlm_pools_cli_shrinker); + if (rc) + return rc; + + rc = register_shrinker(&ldlm_pools_cli_shrinker); + if (rc) + ldlm_pools_thread_stop(); return rc; } diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c index 02ea14c9b089..6aa37463db46 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c @@ -1656,7 +1656,7 @@ int ldlm_cli_cancel_list(struct list_head *cancels, int count, */ while (count > 0) { LASSERT(!list_empty(cancels)); - lock = list_entry(cancels->next, struct ldlm_lock, l_bl_ast); + lock = list_first_entry(cancels, struct ldlm_lock, l_bl_ast); LASSERT(lock->l_conn_export); if (exp_connect_cancelset(lock->l_conn_export)) { @@ -1780,7 +1780,7 @@ EXPORT_SYMBOL(ldlm_cli_cancel_unused); static int ldlm_resource_foreach(struct ldlm_resource *res, ldlm_iterator_t iter, void *closure) { - struct list_head *tmp, *next; + struct ldlm_lock *tmp; struct ldlm_lock *lock; int rc = LDLM_ITER_CONTINUE; @@ -1788,18 +1788,14 @@ static int ldlm_resource_foreach(struct ldlm_resource *res, return LDLM_ITER_CONTINUE; lock_res(res); - list_for_each_safe(tmp, next, &res->lr_granted) { - lock = list_entry(tmp, struct ldlm_lock, l_res_link); - + list_for_each_entry_safe(lock, tmp, &res->lr_granted, l_res_link) { if (iter(lock, closure) == LDLM_ITER_STOP) { rc = LDLM_ITER_STOP; goto out; } } - list_for_each_safe(tmp, next, &res->lr_waiting) { - lock = list_entry(tmp, struct ldlm_lock, l_res_link); - + list_for_each_entry_safe(lock, tmp, &res->lr_waiting, l_res_link) { if (iter(lock, closure) == LDLM_ITER_STOP) { rc = LDLM_ITER_STOP; goto out; diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c index 2689ffdf10e3..9958533cc227 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_resource.c @@ -752,24 +752,22 @@ extern struct ldlm_lock *ldlm_lock_get(struct ldlm_lock *lock); static void cleanup_resource(struct ldlm_resource *res, struct list_head *q, __u64 flags) { - struct list_head *tmp; int rc = 0; bool local_only = !!(flags & LDLM_FL_LOCAL_ONLY); do { - struct ldlm_lock *lock = NULL; + struct ldlm_lock *lock = NULL, *tmp; struct lustre_handle lockh; /* First, we look for non-cleaned-yet lock * all cleaned locks are marked by CLEANED flag. */ lock_res(res); - list_for_each(tmp, q) { - lock = list_entry(tmp, struct ldlm_lock, l_res_link); - if (ldlm_is_cleaned(lock)) { - lock = NULL; + list_for_each_entry(tmp, q, l_res_link) { + if (ldlm_is_cleaned(tmp)) continue; - } + + lock = tmp; LDLM_LOCK_GET(lock); ldlm_set_cleaned(lock); break; @@ -1283,19 +1281,15 @@ void ldlm_res2desc(struct ldlm_resource *res, struct ldlm_resource_desc *desc) */ void ldlm_dump_all_namespaces(enum ldlm_side client, int level) { - struct list_head *tmp; + struct ldlm_namespace *ns; if (!((libcfs_debug | D_ERROR) & level)) return; mutex_lock(ldlm_namespace_lock(client)); - list_for_each(tmp, ldlm_namespace_list(client)) { - struct ldlm_namespace *ns; - - ns = list_entry(tmp, struct ldlm_namespace, ns_list_chain); + list_for_each_entry(ns, ldlm_namespace_list(client), ns_list_chain) ldlm_namespace_dump(level, ns); - } mutex_unlock(ldlm_namespace_lock(client)); } diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c index 6f59045be0f9..99b0b77c75f5 100644 --- a/drivers/staging/lustre/lustre/llite/dir.c +++ b/drivers/staging/lustre/lustre/llite/dir.c @@ -1337,9 +1337,9 @@ finish_req: cmd == LL_IOC_MDC_GETINFO)) { rc = 0; goto skip_lmm; - } else { - goto out_req; } + + goto out_req; } if (cmd == IOC_MDC_GETFILESTRIPE || diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 0d62fcf016dc..f68c2e88f12b 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -792,7 +792,7 @@ int ll_revalidate_it_finish(struct ptlrpc_request *request, extern struct super_operations lustre_super_operations; void ll_lli_init(struct ll_inode_info *lli); -int ll_fill_super(struct super_block *sb, struct vfsmount *mnt); +int ll_fill_super(struct super_block *sb); void ll_put_super(struct super_block *sb); void ll_kill_super(struct super_block *sb); struct inode *ll_inode_from_resource_lock(struct ldlm_lock *lock); diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index 8666f1e81ade..6735a6f006d2 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -146,8 +146,7 @@ static void ll_free_sbi(struct super_block *sb) kfree(sbi); } -static int client_common_fill_super(struct super_block *sb, char *md, char *dt, - struct vfsmount *mnt) +static int client_common_fill_super(struct super_block *sb, char *md, char *dt) { struct inode *root = NULL; struct ll_sb_info *sbi = ll_s2sbi(sb); @@ -236,7 +235,9 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, "An MDT (md %s) is performing recovery, of which this client is not a part. Please wait for recovery to complete, abort, or time out.\n", md); goto out; - } else if (err) { + } + + if (err) { CERROR("cannot connect to %s: rc = %d\n", md, err); goto out; } @@ -865,7 +866,7 @@ void ll_lli_init(struct ll_inode_info *lli) mutex_init(&lli->lli_layout_mutex); } -int ll_fill_super(struct super_block *sb, struct vfsmount *mnt) +int ll_fill_super(struct super_block *sb) { struct lustre_profile *lprof = NULL; struct lustre_sb_info *lsi = s2lsi(sb); @@ -942,7 +943,7 @@ int ll_fill_super(struct super_block *sb, struct vfsmount *mnt) } /* connections, registrations, sb setup */ - err = client_common_fill_super(sb, md, dt, mnt); + err = client_common_fill_super(sb, md, dt); if (!err) sbi->ll_client_common_fill_super_succeeded = 1; diff --git a/drivers/staging/lustre/lustre/llite/super25.c b/drivers/staging/lustre/lustre/llite/super25.c index 0bda111a096e..9b0bb3541a84 100644 --- a/drivers/staging/lustre/lustre/llite/super25.c +++ b/drivers/staging/lustre/lustre/llite/super25.c @@ -86,8 +86,7 @@ MODULE_ALIAS_FS("lustre"); static int __init lustre_init(void) { struct lnet_process_id lnet_id; - struct timespec64 ts; - int i, rc, seed[2]; + int i, rc; BUILD_BUG_ON(sizeof(LUSTRE_VOLATILE_HDR) != LUSTRE_VOLATILE_HDR_LEN + 1); @@ -126,22 +125,20 @@ static int __init lustre_init(void) goto out_debugfs; } - cfs_get_random_bytes(seed, sizeof(seed)); - /* Nodes with small feet have little entropy. The NID for this * node gives the most entropy in the low bits */ for (i = 0;; i++) { + u32 seed; + if (LNetGetId(i, &lnet_id) == -ENOENT) break; - - if (LNET_NETTYP(LNET_NIDNET(lnet_id.nid)) != LOLND) - seed[0] ^= LNET_NIDADDR(lnet_id.nid); + if (LNET_NETTYP(LNET_NIDNET(lnet_id.nid)) != LOLND) { + seed = LNET_NIDADDR(lnet_id.nid); + add_device_randomness(&seed, sizeof(seed)); + } } - ktime_get_ts64(&ts); - cfs_srand(ts.tv_sec ^ seed[0], ts.tv_nsec ^ seed[1]); - rc = vvp_global_init(); if (rc != 0) goto out_sysfs; @@ -159,8 +156,7 @@ static int __init lustre_init(void) if (rc != 0) goto out_inode_fini_env; - lustre_register_client_fill_super(ll_fill_super); - lustre_register_kill_super_cb(ll_kill_super); + lustre_register_super_ops(THIS_MODULE, ll_fill_super, ll_kill_super); lustre_register_client_process_config(ll_process_config); return 0; @@ -181,8 +177,7 @@ out_cache: static void __exit lustre_exit(void) { - lustre_register_client_fill_super(NULL); - lustre_register_kill_super_cb(NULL); + lustre_register_super_ops(NULL, NULL, NULL); lustre_register_client_process_config(NULL); debugfs_remove(llite_root); diff --git a/drivers/staging/lustre/lustre/llite/vvp_dev.c b/drivers/staging/lustre/lustre/llite/vvp_dev.c index 8ccc8b799c02..987c03b058e6 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_dev.c +++ b/drivers/staging/lustre/lustre/llite/vvp_dev.c @@ -384,7 +384,7 @@ int cl_sb_fini(struct super_block *sb) struct vvp_pgcache_id { unsigned int vpi_bucket; unsigned int vpi_depth; - uint32_t vpi_index; + u32 vpi_index; unsigned int vpi_curdep; struct lu_object_header *vpi_obj; diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index bfae98e82d6f..e7a4778e02e4 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -699,7 +699,7 @@ static int vvp_io_read_start(const struct lu_env *env, result = vvp_prep_size(env, obj, io, pos, tot, &exceed); if (result != 0) return result; - else if (exceed != 0) + if (exceed != 0) goto out; LU_OBJECT_HEADER(D_INODE, env, &obj->co_lu, diff --git a/drivers/staging/lustre/lustre/lov/lov_internal.h b/drivers/staging/lustre/lustre/lov/lov_internal.h index ae28ddf80d9b..a56d71c2dda2 100644 --- a/drivers/staging/lustre/lustre/lov/lov_internal.h +++ b/drivers/staging/lustre/lustre/lov/lov_internal.h @@ -115,19 +115,19 @@ static inline const struct lsm_operations *lsm_op_find(int magic) */ #if BITS_PER_LONG == 64 # define lov_do_div64(n, base) ({ \ - uint64_t __base = (base); \ - uint64_t __rem; \ - __rem = ((uint64_t)(n)) % __base; \ - (n) = ((uint64_t)(n)) / __base; \ + u64 __base = (base); \ + u64 __rem; \ + __rem = ((u64)(n)) % __base; \ + (n) = ((u64)(n)) / __base; \ __rem; \ }) #elif BITS_PER_LONG == 32 # define lov_do_div64(n, base) ({ \ - uint64_t __rem; \ + u64 __rem; \ if ((sizeof(base) > 4) && (((base) & 0xffffffff00000000ULL) != 0)) { \ int __remainder; \ LASSERTF(!((base) & (LOV_MIN_STRIPE_SIZE - 1)), "64 bit lov " \ - "division %llu / %llu\n", (n), (uint64_t)(base)); \ + "division %llu / %llu\n", (n), (u64)(base)); \ __remainder = (n) & (LOV_MIN_STRIPE_SIZE - 1); \ (n) >>= LOV_MIN_STRIPE_BITS; \ __rem = do_div(n, (base) >> LOV_MIN_STRIPE_BITS); \ diff --git a/drivers/staging/lustre/lustre/lov/lov_obd.c b/drivers/staging/lustre/lustre/lov/lov_obd.c index 7ce01026a409..ec70c12e5b40 100644 --- a/drivers/staging/lustre/lustre/lov/lov_obd.c +++ b/drivers/staging/lustre/lustre/lov/lov_obd.c @@ -828,11 +828,9 @@ out: static int lov_cleanup(struct obd_device *obd) { struct lov_obd *lov = &obd->u.lov; - struct list_head *pos, *tmp; - struct pool_desc *pool; + struct pool_desc *pool, *tmp; - list_for_each_safe(pos, tmp, &lov->lov_pool_list) { - pool = list_entry(pos, struct pool_desc, pool_list); + list_for_each_entry_safe(pool, tmp, &lov->lov_pool_list, pool_list) { /* free pool structs */ CDEBUG(D_INFO, "delete pool %p\n", pool); /* In the function below, .hs_keycmp resolves to diff --git a/drivers/staging/lustre/lustre/lov/lov_object.c b/drivers/staging/lustre/lustre/lov/lov_object.c index 105b707eed14..897cf2cd4a24 100644 --- a/drivers/staging/lustre/lustre/lov/lov_object.c +++ b/drivers/staging/lustre/lustre/lov/lov_object.c @@ -1335,7 +1335,7 @@ static int lov_object_fiemap(const struct lu_env *env, struct cl_object *obj, int rc = 0; int cur_stripe; int stripe_count; - struct fiemap_state fs = { 0 }; + struct fiemap_state fs = { NULL }; lsm = lov_lsm_addref(cl2lov(obj)); if (!lsm) diff --git a/drivers/staging/lustre/lustre/lov/lov_request.c b/drivers/staging/lustre/lustre/lov/lov_request.c index 3bdf48e4edb4..cfa1d7f92b0f 100644 --- a/drivers/staging/lustre/lustre/lov/lov_request.c +++ b/drivers/staging/lustre/lustre/lov/lov_request.c @@ -49,15 +49,13 @@ static void lov_init_set(struct lov_request_set *set) static void lov_finish_set(struct lov_request_set *set) { - struct list_head *pos, *n; + struct lov_request *req; LASSERT(set); - list_for_each_safe(pos, n, &set->set_list) { - struct lov_request *req = list_entry(pos, - struct lov_request, - rq_link); + while ((req = list_first_entry_or_null(&set->set_list, + struct lov_request, + rq_link)) != NULL) { list_del_init(&req->rq_link); - kfree(req->rq_oi.oi_osfs); kfree(req); } diff --git a/drivers/staging/lustre/lustre/mgc/mgc_request.c b/drivers/staging/lustre/lustre/mgc/mgc_request.c index 77fa8fea0249..79ff85feab64 100644 --- a/drivers/staging/lustre/lustre/mgc/mgc_request.c +++ b/drivers/staging/lustre/lustre/mgc/mgc_request.c @@ -523,7 +523,7 @@ static void do_requeue(struct config_llog_data *cld) * in order to not flood the MGS. */ #define MGC_TIMEOUT_MIN_SECONDS 5 -#define MGC_TIMEOUT_RAND_CENTISEC 0x1ff /* ~500 */ +#define MGC_TIMEOUT_RAND_CENTISEC 500 static int mgc_requeue_thread(void *data) { @@ -537,7 +537,7 @@ static int mgc_requeue_thread(void *data) while (!(rq_state & RQ_STOP)) { struct l_wait_info lwi; struct config_llog_data *cld, *cld_prev; - int rand = cfs_rand() & MGC_TIMEOUT_RAND_CENTISEC; + int rand = prandom_u32_max(MGC_TIMEOUT_RAND_CENTISEC); int to; /* Any new or requeued lostlocks will change the state */ diff --git a/drivers/staging/lustre/lustre/obdclass/cl_lock.c b/drivers/staging/lustre/lustre/obdclass/cl_lock.c index d415f8396038..3b683b774fef 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_lock.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_lock.c @@ -79,13 +79,12 @@ EXPORT_SYMBOL(cl_lock_slice_add); void cl_lock_fini(const struct lu_env *env, struct cl_lock *lock) { + struct cl_lock_slice *slice; cl_lock_trace(D_DLMTRACE, env, "destroy lock", lock); - while (!list_empty(&lock->cll_layers)) { - struct cl_lock_slice *slice; - - slice = list_entry(lock->cll_layers.next, - struct cl_lock_slice, cls_linkage); + while ((slice = list_first_entry_or_null(&lock->cll_layers, + struct cl_lock_slice, + cls_linkage)) != NULL) { list_del_init(lock->cll_layers.next); slice->cls_ops->clo_fini(env, slice); } diff --git a/drivers/staging/lustre/lustre/obdclass/cl_object.c b/drivers/staging/lustre/lustre/obdclass/cl_object.c index fdd27ce46fda..7b18d775b001 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_object.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_object.c @@ -510,13 +510,13 @@ locks: ...... ...... ...... ...... ...... [...... ...... ...... ...... ......] */ lu_site_stats_print(&site->cs_lu, m); cache_stats_print(&site->cs_pages, m, 1); - seq_printf(m, " ["); + seq_puts(m, " ["); for (i = 0; i < ARRAY_SIZE(site->cs_pages_state); ++i) seq_printf(m, "%s: %u ", pstate[i], atomic_read(&site->cs_pages_state[i])); - seq_printf(m, "]\n"); + seq_puts(m, "]\n"); cache_stats_print(&cl_env_stats, m, 0); - seq_printf(m, "\n"); + seq_puts(m, "\n"); return 0; } EXPORT_SYMBOL(cl_site_stats_print); @@ -1017,7 +1017,7 @@ int cl_global_init(void) { int result; - cl_envs = kzalloc(sizeof(*cl_envs) * num_possible_cpus(), GFP_KERNEL); + cl_envs = kcalloc(num_possible_cpus(), sizeof(*cl_envs), GFP_KERNEL); if (!cl_envs) { result = -ENOMEM; goto out; diff --git a/drivers/staging/lustre/lustre/obdclass/cl_page.c b/drivers/staging/lustre/lustre/obdclass/cl_page.c index 7f65439f9b95..d3b25667bc3a 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_page.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_page.c @@ -202,7 +202,7 @@ struct cl_page *cl_page_find(const struct lu_env *env, * vmpage lock is used to protect the child/parent * relationship */ - KLASSERT(PageLocked(vmpage)); + LASSERT(PageLocked(vmpage)); /* * cl_vmpage_page() can be called here without any locks as * @@ -340,7 +340,7 @@ struct cl_page *cl_vmpage_page(struct page *vmpage, struct cl_object *obj) { struct cl_page *page; - KLASSERT(PageLocked(vmpage)); + LASSERT(PageLocked(vmpage)); /* * NOTE: absence of races and liveness of data are guaranteed by page diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c index 2985bca4dc4c..3e24b76f6301 100644 --- a/drivers/staging/lustre/lustre/obdclass/class_obd.c +++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c @@ -377,7 +377,8 @@ static int obd_init_checks(void) char buf[64]; int len, ret = 0; - CDEBUG(D_INFO, "LPU64=%s, LPD64=%s, LPX64=%s\n", "%llu", "%lld", "%#llx"); + CDEBUG(D_INFO, "LPU64=%s, LPD64=%s, LPX64=%s\n", "%llu", "%lld", + "%#llx"); CDEBUG(D_INFO, "OBD_OBJECT_EOF = %#llx\n", (__u64)OBD_OBJECT_EOF); diff --git a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c index fc59f29a4290..57951237def2 100644 --- a/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c +++ b/drivers/staging/lustre/lustre/obdclass/linux/linux-module.c @@ -501,6 +501,7 @@ int class_procfs_init(void) rc = debugfs_lustre_root ? PTR_ERR(debugfs_lustre_root) : -ENOMEM; debugfs_lustre_root = NULL; + sysfs_remove_group(lustre_kobj, &lustre_attr_group); kobject_put(lustre_kobj); goto out; } @@ -509,6 +510,7 @@ int class_procfs_init(void) &obd_device_list_fops); if (IS_ERR_OR_NULL(file)) { rc = file ? PTR_ERR(file) : -ENOMEM; + sysfs_remove_group(lustre_kobj, &lustre_attr_group); kobject_put(lustre_kobj); goto out; } @@ -522,6 +524,7 @@ int class_procfs_clean(void) debugfs_lustre_root = NULL; + sysfs_remove_group(lustre_kobj, &lustre_attr_group); kobject_put(lustre_kobj); return 0; diff --git a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c index 05d71f568837..e1f4ef2bddd4 100644 --- a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c +++ b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c @@ -1093,7 +1093,7 @@ int lprocfs_stats_alloc_one(struct lprocfs_stats *stats, unsigned int cpuid) LASSERT((stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) == 0); percpusize = lprocfs_stats_counter_size(stats); - LIBCFS_ALLOC_ATOMIC(stats->ls_percpu[cpuid], percpusize); + stats->ls_percpu[cpuid] = kzalloc(percpusize, GFP_ATOMIC); if (stats->ls_percpu[cpuid]) { rc = 0; if (unlikely(stats->ls_biggest_alloc_num <= cpuid)) { @@ -1137,7 +1137,8 @@ struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num, num_entry = num_possible_cpus(); /* alloc percpu pointers for all possible cpu slots */ - LIBCFS_ALLOC(stats, offsetof(typeof(*stats), ls_percpu[num_entry])); + stats = kvzalloc(offsetof(typeof(*stats), ls_percpu[num_entry]), + GFP_KERNEL); if (!stats) return NULL; @@ -1146,15 +1147,16 @@ struct lprocfs_stats *lprocfs_alloc_stats(unsigned int num, spin_lock_init(&stats->ls_lock); /* alloc num of counter headers */ - LIBCFS_ALLOC(stats->ls_cnt_header, - stats->ls_num * sizeof(struct lprocfs_counter_header)); + stats->ls_cnt_header = kvmalloc_array(stats->ls_num, + sizeof(struct lprocfs_counter_header), + GFP_KERNEL | __GFP_ZERO); if (!stats->ls_cnt_header) goto fail; if ((flags & LPROCFS_STATS_FLAG_NOPERCPU) != 0) { /* contains only one set counters */ percpusize = lprocfs_stats_counter_size(stats); - LIBCFS_ALLOC_ATOMIC(stats->ls_percpu[0], percpusize); + stats->ls_percpu[0] = kzalloc(percpusize, GFP_ATOMIC); if (!stats->ls_percpu[0]) goto fail; stats->ls_biggest_alloc_num = 1; @@ -1191,12 +1193,9 @@ void lprocfs_free_stats(struct lprocfs_stats **statsh) percpusize = lprocfs_stats_counter_size(stats); for (i = 0; i < num_entry; i++) - if (stats->ls_percpu[i]) - LIBCFS_FREE(stats->ls_percpu[i], percpusize); - if (stats->ls_cnt_header) - LIBCFS_FREE(stats->ls_cnt_header, stats->ls_num * - sizeof(struct lprocfs_counter_header)); - LIBCFS_FREE(stats, offsetof(typeof(*stats), ls_percpu[num_entry])); + kfree(stats->ls_percpu[i]); + kvfree(stats->ls_cnt_header); + kvfree(stats); } EXPORT_SYMBOL(lprocfs_free_stats); diff --git a/drivers/staging/lustre/lustre/obdclass/lu_object.c b/drivers/staging/lustre/lustre/obdclass/lu_object.c index b938a3f9d50a..2719abbff85f 100644 --- a/drivers/staging/lustre/lustre/obdclass/lu_object.c +++ b/drivers/staging/lustre/lustre/obdclass/lu_object.c @@ -1932,8 +1932,10 @@ int lu_global_init(void) LU_CONTEXT_KEY_INIT(&lu_global_key); result = lu_context_key_register(&lu_global_key); - if (result != 0) + if (result != 0) { + lu_ref_global_fini(); return result; + } /* * At this level, we don't know what tags are needed, so allocate them @@ -1943,17 +1945,31 @@ int lu_global_init(void) down_write(&lu_sites_guard); result = lu_env_init(&lu_shrink_env, LCT_SHRINKER); up_write(&lu_sites_guard); - if (result != 0) + if (result != 0) { + lu_context_key_degister(&lu_global_key); + lu_ref_global_fini(); return result; + } /* * seeks estimation: 3 seeks to read a record from oi, one to read * inode, one for ea. Unfortunately setting this high value results in * lu_object/inode cache consuming all the memory. */ - register_shrinker(&lu_site_shrinker); + result = register_shrinker(&lu_site_shrinker); + if (result != 0) { + /* Order explained in lu_global_fini(). */ + lu_context_key_degister(&lu_global_key); - return result; + down_write(&lu_sites_guard); + lu_env_fini(&lu_shrink_env); + up_write(&lu_sites_guard); + + lu_ref_global_fini(); + return result; + } + + return 0; } /** diff --git a/drivers/staging/lustre/lustre/obdclass/lustre_handles.c b/drivers/staging/lustre/lustre/obdclass/lustre_handles.c index 71329adc0318..2d6da2431a09 100644 --- a/drivers/staging/lustre/lustre/obdclass/lustre_handles.c +++ b/drivers/staging/lustre/lustre/obdclass/lustre_handles.c @@ -181,8 +181,6 @@ EXPORT_SYMBOL(class_handle_free_cb); int class_handle_init(void) { struct handle_bucket *bucket; - struct timespec64 ts; - int seed[2]; LASSERT(!handle_hash); @@ -198,12 +196,7 @@ int class_handle_init(void) spin_lock_init(&bucket->lock); } - /** bug 21430: add randomness to the initial base */ - cfs_get_random_bytes(seed, sizeof(seed)); - ktime_get_ts64(&ts); - cfs_srand(ts.tv_sec ^ seed[0], ts.tv_nsec ^ seed[1]); - - cfs_get_random_bytes(&handle_base, sizeof(handle_base)); + get_random_bytes(&handle_base, sizeof(handle_base)); LASSERT(handle_base != 0ULL); return 0; diff --git a/drivers/staging/lustre/lustre/obdclass/obd_config.c b/drivers/staging/lustre/lustre/obdclass/obd_config.c index c0e192ae22a9..997c0f9aafb5 100644 --- a/drivers/staging/lustre/lustre/obdclass/obd_config.c +++ b/drivers/staging/lustre/lustre/obdclass/obd_config.c @@ -236,7 +236,7 @@ static int class_attach(struct lustre_cfg *lcfg) uuid = lustre_cfg_string(lcfg, 2); CDEBUG(D_IOCTL, "attach type %s name: %s uuid: %s\n", - MKSTR(typename), MKSTR(name), MKSTR(uuid)); + typename, name, uuid); obd = class_newdev(typename, name); if (IS_ERR(obd)) { diff --git a/drivers/staging/lustre/lustre/obdclass/obd_mount.c b/drivers/staging/lustre/lustre/obdclass/obd_mount.c index 2a79a223b98a..acc1ea773c9c 100644 --- a/drivers/staging/lustre/lustre/obdclass/obd_mount.c +++ b/drivers/staging/lustre/lustre/obdclass/obd_mount.c @@ -49,9 +49,9 @@ #include <lustre_disk.h> #include <uapi/linux/lustre/lustre_param.h> -static int (*client_fill_super)(struct super_block *sb, - struct vfsmount *mnt); - +static DEFINE_SPINLOCK(client_lock); +static struct module *client_mod; +static int (*client_fill_super)(struct super_block *sb); static void (*kill_super_cb)(struct super_block *sb); /**************** config llog ********************/ @@ -1107,20 +1107,14 @@ invalid: return -EINVAL; } -struct lustre_mount_data2 { - void *lmd2_data; - struct vfsmount *lmd2_mnt; -}; - /** This is the entry point for the mount call into Lustre. * This is called when a server or client is mounted, * and this is where we start setting things up. * @param data Mount options (e.g. -o flock,abort_recov) */ -static int lustre_fill_super(struct super_block *sb, void *data, int silent) +static int lustre_fill_super(struct super_block *sb, void *lmd2_data, int silent) { struct lustre_mount_data *lmd; - struct lustre_mount_data2 *lmd2 = data; struct lustre_sb_info *lsi; int rc; @@ -1143,17 +1137,22 @@ static int lustre_fill_super(struct super_block *sb, void *data, int silent) obd_zombie_barrier(); /* Figure out the lmd from the mount options */ - if (lmd_parse((lmd2->lmd2_data), lmd)) { + if (lmd_parse(lmd2_data, lmd)) { lustre_put_lsi(sb); rc = -EINVAL; goto out; } if (lmd_is_client(lmd)) { + bool have_client = false; CDEBUG(D_MOUNT, "Mounting client %s\n", lmd->lmd_profile); if (!client_fill_super) request_module("lustre"); - if (!client_fill_super) { + spin_lock(&client_lock); + if (client_fill_super && try_module_get(client_mod)) + have_client = true; + spin_unlock(&client_lock); + if (!have_client) { LCONSOLE_ERROR_MSG(0x165, "Nothing registered for client mount! Is the 'lustre' module loaded?\n"); lustre_put_lsi(sb); rc = -ENODEV; @@ -1165,8 +1164,10 @@ static int lustre_fill_super(struct super_block *sb, void *data, int silent) } /* Connect and start */ /* (should always be ll_fill_super) */ - rc = (*client_fill_super)(sb, lmd2->lmd2_mnt); - /* c_f_s will call lustre_common_put_super on failure */ + rc = (*client_fill_super)(sb); + /* c_f_s will call lustre_common_put_super on failure, otherwise + * c_f_s will have taken another reference to the module */ + module_put(client_mod); } } else { CERROR("This is client-side-only module, cannot handle server mount.\n"); @@ -1192,29 +1193,23 @@ out: /* We can't call ll_fill_super by name because it lives in a module that * must be loaded after this one. */ -void lustre_register_client_fill_super(int (*cfs)(struct super_block *sb, - struct vfsmount *mnt)) +void lustre_register_super_ops(struct module *mod, + int (*cfs)(struct super_block *sb), + void (*ksc)(struct super_block *sb)) { + spin_lock(&client_lock); + client_mod = mod; client_fill_super = cfs; + kill_super_cb = ksc; + spin_unlock(&client_lock); } -EXPORT_SYMBOL(lustre_register_client_fill_super); - -void lustre_register_kill_super_cb(void (*cfs)(struct super_block *sb)) -{ - kill_super_cb = cfs; -} -EXPORT_SYMBOL(lustre_register_kill_super_cb); +EXPORT_SYMBOL(lustre_register_super_ops); /***************** FS registration ******************/ static struct dentry *lustre_mount(struct file_system_type *fs_type, int flags, const char *devname, void *data) { - struct lustre_mount_data2 lmd2 = { - .lmd2_data = data, - .lmd2_mnt = NULL - }; - - return mount_nodev(fs_type, flags, &lmd2, lustre_fill_super); + return mount_nodev(fs_type, flags, data, lustre_fill_super); } static void lustre_kill_super(struct super_block *sb) @@ -1230,11 +1225,11 @@ static void lustre_kill_super(struct super_block *sb) /** Register the "lustre" fs type */ static struct file_system_type lustre_fs_type = { - .owner = THIS_MODULE, - .name = "lustre", - .mount = lustre_mount, - .kill_sb = lustre_kill_super, - .fs_flags = FS_REQUIRES_DEV | FS_RENAME_DOES_D_MOVE, + .owner = THIS_MODULE, + .name = "lustre", + .mount = lustre_mount, + .kill_sb = lustre_kill_super, + .fs_flags = FS_RENAME_DOES_D_MOVE, }; MODULE_ALIAS_FS("lustre"); diff --git a/drivers/staging/lustre/lustre/osc/osc_internal.h b/drivers/staging/lustre/lustre/osc/osc_internal.h index feda61bcdb9b..32db150fd42e 100644 --- a/drivers/staging/lustre/lustre/osc/osc_internal.h +++ b/drivers/staging/lustre/lustre/osc/osc_internal.h @@ -168,9 +168,9 @@ struct osc_device { /* Write stats is actually protected by client_obd's lock. */ struct osc_stats { - uint64_t os_lockless_writes; /* by bytes */ - uint64_t os_lockless_reads; /* by bytes */ - uint64_t os_lockless_truncates; /* by times */ + u64 os_lockless_writes; /* by bytes */ + u64 os_lockless_reads; /* by bytes */ + u64 os_lockless_truncates; /* by times */ } od_stats; /* configuration item(s) */ diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index 53eda4c99142..45b1ebf33363 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -2844,7 +2844,9 @@ static int __init osc_init(void) if (rc) goto out_kmem; - register_shrinker(&osc_cache_shrinker); + rc = register_shrinker(&osc_cache_shrinker); + if (rc) + goto out_type; /* This is obviously too much memory, only prevent overflow here */ if (osc_reqpool_mem_max >= 1 << 12 || osc_reqpool_mem_max == 0) { diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c index 2a9f2f2ebaa8..bac4b2304bad 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/client.c +++ b/drivers/staging/lustre/lustre/ptlrpc/client.c @@ -3067,7 +3067,7 @@ void ptlrpc_init_xid(void) spin_lock_init(&ptlrpc_last_xid_lock); if (now < YEAR_2004) { - cfs_get_random_bytes(&ptlrpc_last_xid, sizeof(ptlrpc_last_xid)); + get_random_bytes(&ptlrpc_last_xid, sizeof(ptlrpc_last_xid)); ptlrpc_last_xid >>= 2; ptlrpc_last_xid |= (1ULL << 61); } else { diff --git a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c index 77a3721beaee..134ee727e8b7 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c +++ b/drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c @@ -396,6 +396,8 @@ static struct shrinker pools_shrinker = { int sptlrpc_enc_pool_init(void) { + int rc; + /* * maximum capacity is 1/8 of total physical memory. * is the 1/8 a good number? @@ -432,9 +434,11 @@ int sptlrpc_enc_pool_init(void) if (!page_pools.epp_pools) return -ENOMEM; - register_shrinker(&pools_shrinker); + rc = register_shrinker(&pools_shrinker); + if (rc) + enc_pools_free(); - return 0; + return rc; } void sptlrpc_enc_pool_fini(void) diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index bb1d6dafca83..26994b429cf2 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c @@ -207,13 +207,9 @@ static irqreturn_t csi_idmac_eof_interrupt(int irq, void *dev_id) goto unlock; } - if (priv->fim) { - struct timespec cur_ts; - - ktime_get_ts(&cur_ts); + if (priv->fim) /* call frame interval monitor */ - imx_media_fim_eof_monitor(priv->fim, &cur_ts); - } + imx_media_fim_eof_monitor(priv->fim, ktime_get()); csi_vb2_buf_done(priv); diff --git a/drivers/staging/media/imx/imx-media-fim.c b/drivers/staging/media/imx/imx-media-fim.c index 47275ef803f3..6df189135db8 100644 --- a/drivers/staging/media/imx/imx-media-fim.c +++ b/drivers/staging/media/imx/imx-media-fim.c @@ -66,7 +66,7 @@ struct imx_media_fim { int icap_flags; int counter; - struct timespec last_ts; + ktime_t last_ts; unsigned long sum; /* usec */ unsigned long nominal; /* usec */ @@ -147,22 +147,26 @@ static void send_fim_event(struct imx_media_fim *fim, unsigned long error) * (presumably random) interrupt latency. */ static void frame_interval_monitor(struct imx_media_fim *fim, - struct timespec *ts) + ktime_t timestamp) { - unsigned long interval, error, error_avg; + long long interval, error; + unsigned long error_avg; bool send_event = false; - struct timespec diff; if (!fim->enabled || ++fim->counter <= 0) goto out_update_ts; - diff = timespec_sub(*ts, fim->last_ts); - interval = diff.tv_sec * 1000 * 1000 + diff.tv_nsec / 1000; - error = abs(interval - fim->nominal); + /* max error is less than l00µs, so use 32-bit division or fail */ + interval = ktime_to_ns(ktime_sub(timestamp, fim->last_ts)); + error = abs(interval - NSEC_PER_USEC * (u64)fim->nominal); + if (error > U32_MAX) + error = U32_MAX; + else + error = abs((u32)error / NSEC_PER_USEC); if (fim->tolerance_max && error >= fim->tolerance_max) { dev_dbg(fim->sd->dev, - "FIM: %lu ignored, out of tolerance bounds\n", + "FIM: %llu ignored, out of tolerance bounds\n", error); fim->counter--; goto out_update_ts; @@ -184,7 +188,7 @@ static void frame_interval_monitor(struct imx_media_fim *fim, } out_update_ts: - fim->last_ts = *ts; + fim->last_ts = timestamp; if (send_event) send_fim_event(fim, error_avg); } @@ -195,14 +199,14 @@ out_update_ts: * to interrupt latency. */ static void fim_input_capture_handler(int channel, void *dev_id, - struct timespec *ts) + ktime_t timestamp) { struct imx_media_fim *fim = dev_id; unsigned long flags; spin_lock_irqsave(&fim->lock, flags); - frame_interval_monitor(fim, ts); + frame_interval_monitor(fim, timestamp); if (!completion_done(&fim->icap_first_event)) complete(&fim->icap_first_event); @@ -405,14 +409,14 @@ err_free: * the frame_interval_monitor() is called by the input capture event * callback handler in that case. */ -void imx_media_fim_eof_monitor(struct imx_media_fim *fim, struct timespec *ts) +void imx_media_fim_eof_monitor(struct imx_media_fim *fim, ktime_t timestamp) { unsigned long flags; spin_lock_irqsave(&fim->lock, flags); if (!icap_enabled(fim)) - frame_interval_monitor(fim, ts); + frame_interval_monitor(fim, timestamp); spin_unlock_irqrestore(&fim->lock, flags); } diff --git a/drivers/staging/media/imx/imx-media.h b/drivers/staging/media/imx/imx-media.h index d409170632bd..ac3ab115394f 100644 --- a/drivers/staging/media/imx/imx-media.h +++ b/drivers/staging/media/imx/imx-media.h @@ -280,7 +280,7 @@ int imx_media_pipeline_set_stream(struct imx_media_dev *imxmd, /* imx-media-fim.c */ struct imx_media_fim; -void imx_media_fim_eof_monitor(struct imx_media_fim *fim, struct timespec *ts); +void imx_media_fim_eof_monitor(struct imx_media_fim *fim, ktime_t timestamp); int imx_media_fim_set_stream(struct imx_media_fim *fim, const struct v4l2_fract *frame_interval, bool on); diff --git a/drivers/staging/most/Documentation/ABI/sysfs-bus-most.txt b/drivers/staging/most/Documentation/ABI/sysfs-bus-most.txt new file mode 100644 index 000000000000..d8fa841e3742 --- /dev/null +++ b/drivers/staging/most/Documentation/ABI/sysfs-bus-most.txt @@ -0,0 +1,313 @@ +What: /sys/bus/most/devices/.../description +Date: March 2017 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + Provides information about the interface type and the physical + location of the device. Hardware attached via USB, for instance, + might return <usb_device 1-1.1:1.0> +Users: + +What: /sys/bus/most/devices/.../interface +Date: March 2017 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + Indicates the type of peripheral interface the device uses. +Users: + +What: /sys/bus/most/devices/.../dci +Date: June 2016 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + If the network interface controller is attached via USB, a dci + directory is created that allows applications to read and + write the controller's DCI registers. +Users: + +What: /sys/bus/most/devices/.../dci/arb_address +Date: June 2016 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + This is used to set an arbitrary DCI register address an + application wants to read from or write to. +Users: + +What: /sys/bus/most/devices/.../dci/arb_value +Date: June 2016 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + This is used to read and write the DCI register whose address + is stored in arb_address. +Users: + +What: /sys/bus/most/devices/.../dci/mep_eui48_hi +Date: June 2016 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + This is used to check and configure the MAC address. +Users: + +What: /sys/bus/most/devices/.../dci/mep_eui48_lo +Date: June 2016 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + This is used to check and configure the MAC address. +Users: + +What: /sys/bus/most/devices/.../dci/mep_eui48_mi +Date: June 2016 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + This is used to check and configure the MAC address. +Users: + +What: /sys/bus/most/devices/.../dci/mep_filter +Date: June 2016 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + This is used to check and configure the MEP filter address. +Users: + +What: /sys/bus/most/devices/.../dci/mep_hash0 +Date: June 2016 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + This is used to check and configure the MEP hash table. +Users: + +What: /sys/bus/most/devices/.../dci/mep_hash1 +Date: June 2016 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + This is used to check and configure the MEP hash table. +Users: + +What: /sys/bus/most/devices/.../dci/mep_hash2 +Date: June 2016 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + This is used to check and configure the MEP hash table. +Users: + +What: /sys/bus/most/devices/.../dci/mep_hash3 +Date: June 2016 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + This is used to check and configure the MEP hash table. +Users: + +What: /sys/bus/most/devices/.../dci/ni_state +Date: June 2016 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + Indicates the current network interface state. +Users: + +What: /sys/bus/most/devices/.../dci/node_address +Date: June 2016 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + Indicates the current node address. +Users: + +What: /sys/bus/most/devices/.../dci/node_position +Date: June 2016 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + Indicates the current node position. +Users: + +What: /sys/bus/most/devices/.../dci/packet_bandwidth +Date: June 2016 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + Indicates the configured packet bandwidth. +Users: + +What: /sys/bus/most/devices/.../dci/sync_ep +Date: June 2016 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + Triggers the controller's synchronization process for a certain + endpoint. +Users: + +What: /sys/bus/most/devices/.../<channel>/ +Date: March 2017 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + For every channel of the device a directory is created, whose + name is dictated by the HDM. This enables an application to + collect information about the channel's capabilities and + configure it. +Users: + +What: /sys/bus/most/devices/.../<channel>/available_datatypes +Date: March 2017 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + Indicates the data types the current channel can transport. +Users: + +What: /sys/bus/most/devices/.../<channel>/available_directions +Date: March 2017 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + Indicates the directions the current channel is capable of. +Users: + +What: /sys/bus/most/devices/.../<channel>/number_of_packet_buffers +Date: March 2017 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + Indicates the number of packet buffers the current channel can + handle. +Users: + +What: /sys/bus/most/devices/.../<channel>/number_of_stream_buffers +Date: March 2017 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + Indicates the number of streaming buffers the current channel can + handle. +Users: + +What: /sys/bus/most/devices/.../<channel>/size_of_packet_buffer +Date: March 2017 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + Indicates the size of a packet buffer the current channel can + handle. +Users: + +What: /sys/bus/most/devices/.../<channel>/size_of_stream_buffer +Date: March 2017 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + Indicates the size of a streaming buffer the current channel can + handle. +Users: + +What: /sys/bus/most/devices/.../<channel>/set_number_of_buffers +Date: March 2017 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + This is to configure the number of buffers of the current channel. +Users: + +What: /sys/bus/most/devices/.../<channel>/set_buffer_size +Date: March 2017 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + This is to configure the size of a buffer of the current channel. +Users: + +What: /sys/bus/most/devices/.../<channel>/set_direction +Date: March 2017 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + This is to configure the direction of the current channel. + The following strings will be accepted: + 'dir_tx', + 'dir_rx' +Users: + +What: /sys/bus/most/devices/.../<channel>/set_datatype +Date: March 2017 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + This is to configure the data type of the current channel. + The following strings will be accepted: + 'control', + 'async', + 'sync', + 'isoc_avp' +Users: + +What: /sys/bus/most/devices/.../<channel>/set_subbuffer_size +Date: March 2017 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + This is to configure the subbuffer size of the current channel. +Users: + +What: /sys/bus/most/devices/.../<channel>/set_packets_per_xact +Date: March 2017 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + This is to configure the number of packets per transaction of + the current channel. This is only needed network interface + controller is attached via USB. +Users: + +What: /sys/bus/most/devices/.../<channel>/channel_starving +Date: March 2017 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + Indicates whether current channel ran out of buffers. +Users: + +What: /sys/bus/most/drivers/mostcore/add_link +Date: March 2017 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + This is used to link a channel to a component of the + mostcore. A link created by writing to this file is + referred to as pipe. +Users: + +What: /sys/bus/most/drivers/mostcore/remove_link +Date: March 2017 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + This is used to unlink a channel from a component. +Users: + +What: /sys/bus/most/drivers/mostcore/components +Date: March 2017 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + This is used to retrieve a list of registered components. +Users: + +What: /sys/bus/most/drivers/mostcore/links +Date: March 2017 +KernelVersion: 4.15 +Contact: Christian Gromm <christian.gromm@microchip.com> +Description: + This is used to retrieve a list of established links. +Users: diff --git a/drivers/staging/most/Documentation/driver_usage.txt b/drivers/staging/most/Documentation/driver_usage.txt index a4dc0c348fbc..bb9b4e870199 100644 --- a/drivers/staging/most/Documentation/driver_usage.txt +++ b/drivers/staging/most/Documentation/driver_usage.txt @@ -23,20 +23,29 @@ audio/video streaming. Therefore, the driver perfectly fits to the mission of Automotive Grade Linux to create open source software solutions for automotive applications. -The driver consists basically of three layers. The hardware layer, the -core layer and the application layer. The core layer consists of the core -module only. This module handles the communication flow through all three -layers, the configuration of the driver, the configuration interface -representation in sysfs, and the buffer management. -For each of the other two layers a selection of modules is provided. These -modules can arbitrarily be combined to meet the needs of the desired -system architecture. A module of the hardware layer is referred to as an -HDM (hardware dependent module). Each module of this layer handles exactly -one of the peripheral interfaces of a network interface controller (e.g. -USB, MediaLB, I2C). A module of the application layer is referred to as an -AIM (application interfacing module). The modules of this layer give access -to MOST via one the following ways: character devices, ALSA, Networking or -V4L2. +The MOST driver uses module stacking to divide the associated modules into +three layers. From bottom up these layers are: the adapter layer, the core +layer and the application layer. The core layer implements the MOST +subsystem and consists basically of the module core.c and its API. It +registers the MOST bus with the kernel's device model, handles the data +routing through all three layers, the configuration of the driver, the +representation of the configuration interface in sysfs and the buffer +management. + +For each of the other two layers a set of modules is provided. Those can be +arbitrarily combined with the core to meet the connectivity of the desired +system architecture. + +A module of the adapter layer is basically a device driver for a different +subsystem. It is registered with the core to connect the MOST subsystem to +the attached network interface controller hardware. Hence, a given module +of this layer is designed to handle exactly one of the peripheral +interfaces (e.g. USB, MediaLB, I2C) the hardware provides. + +A module of the application layer is referred to as a core comoponent, +which kind of extends the core by providing connectivity to the user space. +Applications, then, can access a MOST network via character devices, an +ALSA soundcard, a Network adapter or a V4L2 capture device. To physically access MOST, an Intelligent Network Interface Controller (INIC) is needed. For more information on available controllers visit: @@ -44,15 +53,14 @@ www.microchip.com - Section 1.1 Hardware Layer + Section 1.1 Adapter Layer -The hardware layer contains so called hardware dependent modules (HDM). For each -peripheral interface the hardware supports the driver has a suitable module -that handles the interface. - -The HDMs encapsulate the peripheral interface specific knowledge of the driver -and provides an easy way of extending the number of supported interfaces. -Currently the following HDMs are available: +The adapter layer contains a pool of device drivers. For each peripheral +interface the hardware supports there is one suitable module that handles +the interface. Adapter drivers encapsulate the peripheral interface +specific knowledge of the MOST driver stack and provide an easy way of +extending the number of supported interfaces. Currently the following +interfaces are available: 1) MediaLB (DIM2) Host wants to communicate with hardware via MediaLB. @@ -63,26 +71,34 @@ Currently the following HDMs are available: 3) USB Host wants to communicate with the hardware via USB. +Once an adapter driver recognizes a MOST device being attached, it +registers it with the core, which, in turn, assigns the necessary members +of the embedded struct device (e.g. the bus this device belongs to and +attribute groups) and registers it with the kernel's device model. - Section 1.2 Core Layer - -The core layer contains the mostcore module only, which processes the driver -configuration via sysfs, buffer management and data forwarding. + Section 1.2 Core Layer +This layer implements the MOST subsystem. It contains the core module and +the header file most.h that exposes the API of the core. When inserted in +the kernel, it registers the MOST bus_type with the kernel's device model +and registers itself as a device driver for this bus. Besides these meta +tasks the core populates the configuration directory for a registered MOST +device (represented by struct most_interface) in sysfs and processes the +configuration of the device's interface. The core layer also handles the +buffer management and the data/message routing. - Section 1.2 Application Layer -The application layer contains so called application interfacing modules (AIM). -Depending on how the driver should interface to the application, one or more -suitable modules can be selected. + Section 1.3 Application Layer -The AIMs encapsulate the application interface specific knowledge of the driver -and provides access to user space or other kernel subsystems. -Currently the following AIMs are available +This layer contains a pool of device drivers that are components of the +core designed to make up the userspace experience of the MOST driver stack. +Depending on how an application is meant to interface the driver, one or +more modules of this pool can be registered with the core. Currently the +following components are available 1) Character Device - Applications can access the driver by means of character devices. + Userspace can access the driver by means of character devices. 2) Networking Standard networking applications (e.g. iperf) can by used to access @@ -97,84 +113,86 @@ Currently the following AIMs are available used to access the driver via the ALSA subsystem. + Section 2 Usage of the MOST Driver - Section 2 Configuration + Section 2.1 Configuration -See ABI/sysfs-class-most.txt +See ABI/sysfs-bus-most.txt + Section 2.2 Routing Channels - Section 3 USB Padding +To connect a configured channel to a certain core component and make it +accessible for user space applications, the driver attribute 'add_link' is +used. The configuration string passed to it has the following format: -When transceiving synchronous or isochronous data, the number of packets per USB -transaction and the sub-buffer size need to be configured. These values -are needed for the driver to process buffer padding, as expected by hardware, -which is for performance optimization purposes of the USB transmission. + "device_name:channel_name:component_name:link_name[.param]" -When transmitting synchronous data the allocated channel width needs to be -written to 'set_subbuffer_size'. Additionally, the number of MOST frames that -should travel to the host within one USB transaction need to be written to -'packets_per_xact'. +It is the concatenation of up to four substrings separated by a colon. The +substrings contain the names of the MOST interface, the channel, the +component driver and a custom name with which the link is going to be +referenced with. Since some components need additional information, the +link name can be extended with a component-specific parameter (separated by +a dot). In case the character device component is loaded, the handle would +also appear as a device node in the /dev directory. -Internally the synchronous threshold is calculated as follows: +Cdev component example: + $ echo "mdev0:ep_81:cdev:my_rx_channel" >$(DRV_DIR)/add_link - frame_size = set_subbuffer_size * packets_per_xact -In case 'packets_per_xact' is set to 0xFF the maximum number of packets, -allocated within one MOST frame, is calculated that fit into _one_ 512 byte -USB full packet. +Sound component example: - frame_size = floor(MTU_USB / bandwidth_sync) * bandwidth_sync +The sound component needs an additional parameter to determine the audio +resolution that is going to be used. The following formats are available: -This frame_size is the number of synchronous data within an USB transaction, -which renders MTU_USB - frame_size bytes for padding. + - "1x8" (Mono) + - "2x16" (16-bit stereo) + - "2x24" (24-bit stereo) + - "2x32" (32-bit stereo) + - "6x16" (16-bit surround 5.1) -When transmitting isochronous AVP data the desired packet size needs to be -written to 'set_subbuffer_size' and hardware will always expect two isochronous -packets within one USB transaction. This renders + $ echo "mdev0:ep_81:sound:most51_playback.6x16" >$(DRV_DIR)/add_link - MTU_USB - (2 * set_subbuffer_size) -bytes for padding. - -Note that at least 2 times set_subbuffer_size bytes for isochronous data or -set_subbuffer_size times packts_per_xact bytes for synchronous data need to be -put in the transmission buffer and passed to the driver. -Since HDMs are allowed to change a chosen configuration to best fit its -constraints, it is recommended to always double check the configuration and read -back the previously written files. + Section 2.3 USB Padding +When transceiving synchronous or isochronous data, the number of packets +per USB transaction and the sub-buffer size need to be configured. These +values are needed for the driver to process buffer padding, as expected by +hardware, which is for performance optimization purposes of the USB +transmission. +When transmitting synchronous data the allocated channel width needs to be +written to 'set_subbuffer_size'. Additionally, the number of MOST frames +that should travel to the host within one USB transaction need to be +written to 'packets_per_xact'. - Section 4 Routing Channels +The driver, then, calculates the synchronous threshold as follows: -To connect a channel that has been configured as outlined above to an AIM and -make it accessible to user space applications, the attribute file 'add_link' is -used. To actually bind a channel to the AIM a string needs to be written to the -file that complies with the following syntax: + frame_size = set_subbuffer_size * packets_per_xact - "most_device:channel_name:link_name[.param]" +In case 'packets_per_xact' is set to 0xFF the maximum number of packets, +allocated within one MOST frame, is calculated that fit into _one_ 512 byte +USB full packet. -The example above links the channel "channel_name" of the device "most_device" -to the AIM. In case the AIM interfaces the VFS this would also create a device -node "link_name" in the /dev directory. The parameter "param" is an AIM dependent -string, which can be omitted in case the used AIM does not make any use of it. + frame_size = floor(MTU_USB / bandwidth_sync) * bandwidth_sync -Cdev AIM example: - $ echo "mdev0:ep_81:my_rx_channel" >add_link - $ echo "mdev0:ep_81" >add_link +This frame_size is the number of synchronous data within an USB +transaction, which renders MTU_USB - frame_size bytes for padding. +When transmitting isochronous AVP data the desired packet size needs to be +written to 'set_subbuffer_size' and hardware will always expect two +isochronous packets within one USB transaction. This renders -Sound/ALSA AIM example: + MTU_USB - (2 * set_subbuffer_size) -The sound/ALSA AIM needs an additional parameter to determine the audio resolution -that is going to be used. The following strings can be used: +bytes for padding. - - "1x8" (Mono) - - "2x16" (16-bit stereo) - - "2x24" (24-bit stereo) - - "2x32" (32-bit stereo) +Note that at least (2 * set_subbuffer_size) bytes for isochronous data or +(set_subbuffer_size * packts_per_xact) bytes for synchronous data need to +be put in the transmission buffer and passed to the driver. - $ echo "mdev0:ep_81:audio_rx.2x16" >add_link - $ echo "mdev0:ep_81" >add_link +Since adapter drivers are allowed to change a chosen configuration to best +fit its constraints, it is recommended to always double check the +configuration and read back the previously written files. diff --git a/drivers/staging/most/Kconfig b/drivers/staging/most/Kconfig index 0b9b9b539f70..20047abbe560 100644 --- a/drivers/staging/most/Kconfig +++ b/drivers/staging/most/Kconfig @@ -1,10 +1,15 @@ menuconfig MOST - tristate "MOST driver" + tristate "MOST support" depends on HAS_DMA - select MOSTCORE default n ---help--- - This option allows you to enable support for MOST Network transceivers. + Say Y here if you want to enable MOST support. + This driver needs at least one additional component to enable the + desired access from userspace (e.g. character devices) and one that + matches the network controller's hardware interface (e.g. USB). + + To compile this driver as a module, choose M here: the + module will be called most_core. If in doubt, say N here. @@ -12,20 +17,18 @@ menuconfig MOST if MOST -source "drivers/staging/most/mostcore/Kconfig" - -source "drivers/staging/most/aim-cdev/Kconfig" +source "drivers/staging/most/cdev/Kconfig" -source "drivers/staging/most/aim-network/Kconfig" +source "drivers/staging/most/net/Kconfig" -source "drivers/staging/most/aim-sound/Kconfig" +source "drivers/staging/most/sound/Kconfig" -source "drivers/staging/most/aim-v4l2/Kconfig" +source "drivers/staging/most/video/Kconfig" -source "drivers/staging/most/hdm-dim2/Kconfig" +source "drivers/staging/most/dim2/Kconfig" -source "drivers/staging/most/hdm-i2c/Kconfig" +source "drivers/staging/most/i2c/Kconfig" -source "drivers/staging/most/hdm-usb/Kconfig" +source "drivers/staging/most/usb/Kconfig" endif diff --git a/drivers/staging/most/Makefile b/drivers/staging/most/Makefile index f5bbb9deaab5..f8bcf488ecf2 100644 --- a/drivers/staging/most/Makefile +++ b/drivers/staging/most/Makefile @@ -1,9 +1,12 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_MOSTCORE) += mostcore/ -obj-$(CONFIG_AIM_CDEV) += aim-cdev/ -obj-$(CONFIG_AIM_NETWORK) += aim-network/ -obj-$(CONFIG_AIM_SOUND) += aim-sound/ -obj-$(CONFIG_AIM_V4L2) += aim-v4l2/ -obj-$(CONFIG_HDM_DIM2) += hdm-dim2/ -obj-$(CONFIG_HDM_I2C) += hdm-i2c/ -obj-$(CONFIG_HDM_USB) += hdm-usb/ +obj-$(CONFIG_MOST) += most_core.o +most_core-y := core.o +ccflags-y += -Idrivers/staging/ + +obj-$(CONFIG_MOST_CDEV) += cdev/ +obj-$(CONFIG_MOST_NET) += net/ +obj-$(CONFIG_MOST_SOUND) += sound/ +obj-$(CONFIG_MOST_VIDEO) += video/ +obj-$(CONFIG_MOST_DIM2) += dim2/ +obj-$(CONFIG_MOST_I2C) += i2c/ +obj-$(CONFIG_MOST_USB) += usb/ diff --git a/drivers/staging/most/aim-cdev/Makefile b/drivers/staging/most/aim-cdev/Makefile deleted file mode 100644 index 0bcc6c637b75..000000000000 --- a/drivers/staging/most/aim-cdev/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -obj-$(CONFIG_AIM_CDEV) += aim_cdev.o - -aim_cdev-objs := cdev.o -ccflags-y += -Idrivers/staging/most/mostcore/
\ No newline at end of file diff --git a/drivers/staging/most/aim-network/Makefile b/drivers/staging/most/aim-network/Makefile deleted file mode 100644 index 840c1dd94873..000000000000 --- a/drivers/staging/most/aim-network/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -obj-$(CONFIG_AIM_NETWORK) += aim_network.o - -aim_network-objs := networking.o -ccflags-y += -Idrivers/staging/most/mostcore/ diff --git a/drivers/staging/most/aim-sound/Makefile b/drivers/staging/most/aim-sound/Makefile deleted file mode 100644 index beba9586fd28..000000000000 --- a/drivers/staging/most/aim-sound/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -obj-$(CONFIG_AIM_SOUND) += aim_sound.o - -aim_sound-objs := sound.o -ccflags-y += -Idrivers/staging/most/mostcore/ diff --git a/drivers/staging/most/aim-v4l2/Makefile b/drivers/staging/most/aim-v4l2/Makefile deleted file mode 100644 index 69a7524b466c..000000000000 --- a/drivers/staging/most/aim-v4l2/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -obj-$(CONFIG_AIM_V4L2) += aim_v4l2.o - -aim_v4l2-objs := video.o - -ccflags-y += -Idrivers/staging/most/mostcore/ diff --git a/drivers/staging/most/aim-cdev/Kconfig b/drivers/staging/most/cdev/Kconfig index 3c59f1bac127..2b04e26bcbea 100644 --- a/drivers/staging/most/aim-cdev/Kconfig +++ b/drivers/staging/most/cdev/Kconfig @@ -2,11 +2,11 @@ # MOST Cdev configuration # -config AIM_CDEV - tristate "Cdev AIM" +config MOST_CDEV + tristate "Cdev" ---help--- Say Y here if you want to commumicate via character devices. To compile this driver as a module, choose M here: the - module will be called aim_cdev.
\ No newline at end of file + module will be called most_cdev. diff --git a/drivers/staging/most/cdev/Makefile b/drivers/staging/most/cdev/Makefile new file mode 100644 index 000000000000..afb9870eb50f --- /dev/null +++ b/drivers/staging/most/cdev/Makefile @@ -0,0 +1,4 @@ +obj-$(CONFIG_MOST_CDEV) += most_cdev.o + +most_cdev-objs := cdev.o +ccflags-y += -Idrivers/staging/ diff --git a/drivers/staging/most/aim-cdev/cdev.c b/drivers/staging/most/cdev/cdev.c index 69f530972273..c183489c4a1c 100644 --- a/drivers/staging/most/aim-cdev/cdev.c +++ b/drivers/staging/most/cdev/cdev.c @@ -1,14 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * cdev.c - Application interfacing module for character devices + * cdev.c - Character device component for Mostcore * * Copyright (C) 2013-2015 Microchip Technology Germany II GmbH & Co. KG - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This file is licensed under GPLv2. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -22,15 +16,17 @@ #include <linux/kfifo.h> #include <linux/uaccess.h> #include <linux/idr.h> -#include "mostcore.h" +#include "most/core.h" -static dev_t aim_devno; -static struct class *aim_class; -static struct ida minor_id; -static unsigned int major; -static struct most_aim cdev_aim; +static struct cdev_component { + dev_t devno; + struct ida minor_id; + unsigned int major; + struct class *class; + struct core_component cc; +} comp; -struct aim_channel { +struct comp_channel { wait_queue_head_t wq; spinlock_t unlink; /* synchronization lock to unlink channels */ struct cdev cdev; @@ -46,28 +42,28 @@ struct aim_channel { struct list_head list; }; -#define to_channel(d) container_of(d, struct aim_channel, cdev) +#define to_channel(d) container_of(d, struct comp_channel, cdev) static struct list_head channel_list; static spinlock_t ch_list_lock; -static inline bool ch_has_mbo(struct aim_channel *c) +static inline bool ch_has_mbo(struct comp_channel *c) { - return channel_has_mbo(c->iface, c->channel_id, &cdev_aim) > 0; + return channel_has_mbo(c->iface, c->channel_id, &comp.cc) > 0; } -static inline bool ch_get_mbo(struct aim_channel *c, struct mbo **mbo) +static inline bool ch_get_mbo(struct comp_channel *c, struct mbo **mbo) { if (!kfifo_peek(&c->fifo, mbo)) { - *mbo = most_get_mbo(c->iface, c->channel_id, &cdev_aim); + *mbo = most_get_mbo(c->iface, c->channel_id, &comp.cc); if (*mbo) kfifo_in(&c->fifo, mbo, 1); } return *mbo; } -static struct aim_channel *get_channel(struct most_interface *iface, int id) +static struct comp_channel *get_channel(struct most_interface *iface, int id) { - struct aim_channel *c, *tmp; + struct comp_channel *c, *tmp; unsigned long flags; int found_channel = 0; @@ -84,44 +80,44 @@ static struct aim_channel *get_channel(struct most_interface *iface, int id) return c; } -static void stop_channel(struct aim_channel *c) +static void stop_channel(struct comp_channel *c) { struct mbo *mbo; while (kfifo_out((struct kfifo *)&c->fifo, &mbo, 1)) most_put_mbo(mbo); - most_stop_channel(c->iface, c->channel_id, &cdev_aim); + most_stop_channel(c->iface, c->channel_id, &comp.cc); } -static void destroy_cdev(struct aim_channel *c) +static void destroy_cdev(struct comp_channel *c) { unsigned long flags; - device_destroy(aim_class, c->devno); + device_destroy(comp.class, c->devno); cdev_del(&c->cdev); spin_lock_irqsave(&ch_list_lock, flags); list_del(&c->list); spin_unlock_irqrestore(&ch_list_lock, flags); } -static void destroy_channel(struct aim_channel *c) +static void destroy_channel(struct comp_channel *c) { - ida_simple_remove(&minor_id, MINOR(c->devno)); + ida_simple_remove(&comp.minor_id, MINOR(c->devno)); kfifo_free(&c->fifo); kfree(c); } /** - * aim_open - implements the syscall to open the device + * comp_open - implements the syscall to open the device * @inode: inode pointer * @filp: file pointer * * This stores the channel pointer in the private data field of * the file structure and activates the channel within the core. */ -static int aim_open(struct inode *inode, struct file *filp) +static int comp_open(struct inode *inode, struct file *filp) { - struct aim_channel *c; + struct comp_channel *c; int ret; c = to_channel(inode->i_cdev); @@ -149,7 +145,7 @@ static int aim_open(struct inode *inode, struct file *filp) } c->mbo_offs = 0; - ret = most_start_channel(c->iface, c->channel_id, &cdev_aim); + ret = most_start_channel(c->iface, c->channel_id, &comp.cc); if (!ret) c->access_ref = 1; mutex_unlock(&c->io_mutex); @@ -157,15 +153,15 @@ static int aim_open(struct inode *inode, struct file *filp) } /** - * aim_close - implements the syscall to close the device + * comp_close - implements the syscall to close the device * @inode: inode pointer * @filp: file pointer * * This stops the channel within the core. */ -static int aim_close(struct inode *inode, struct file *filp) +static int comp_close(struct inode *inode, struct file *filp) { - struct aim_channel *c = to_channel(inode->i_cdev); + struct comp_channel *c = to_channel(inode->i_cdev); mutex_lock(&c->io_mutex); spin_lock(&c->unlink); @@ -182,19 +178,19 @@ static int aim_close(struct inode *inode, struct file *filp) } /** - * aim_write - implements the syscall to write to the device + * comp_write - implements the syscall to write to the device * @filp: file pointer * @buf: pointer to user buffer * @count: number of bytes to write * @offset: offset from where to start writing */ -static ssize_t aim_write(struct file *filp, const char __user *buf, - size_t count, loff_t *offset) +static ssize_t comp_write(struct file *filp, const char __user *buf, + size_t count, loff_t *offset) { int ret; size_t to_copy, left; struct mbo *mbo = NULL; - struct aim_channel *c = filp->private_data; + struct comp_channel *c = filp->private_data; mutex_lock(&c->io_mutex); while (c->dev && !ch_get_mbo(c, &mbo)) { @@ -236,18 +232,18 @@ unlock: } /** - * aim_read - implements the syscall to read from the device + * comp_read - implements the syscall to read from the device * @filp: file pointer * @buf: pointer to user buffer * @count: number of bytes to read * @offset: offset from where to start reading */ static ssize_t -aim_read(struct file *filp, char __user *buf, size_t count, loff_t *offset) +comp_read(struct file *filp, char __user *buf, size_t count, loff_t *offset) { size_t to_copy, not_copied, copied; struct mbo *mbo; - struct aim_channel *c = filp->private_data; + struct comp_channel *c = filp->private_data; mutex_lock(&c->io_mutex); while (c->dev && !kfifo_peek(&c->fifo, &mbo)) { @@ -287,9 +283,9 @@ aim_read(struct file *filp, char __user *buf, size_t count, loff_t *offset) return copied; } -static __poll_t aim_poll(struct file *filp, poll_table *wait) +static __poll_t comp_poll(struct file *filp, poll_table *wait) { - struct aim_channel *c = filp->private_data; + struct comp_channel *c = filp->private_data; __poll_t mask = 0; poll_wait(filp, &c->wq, wait); @@ -309,24 +305,24 @@ static __poll_t aim_poll(struct file *filp, poll_table *wait) */ static const struct file_operations channel_fops = { .owner = THIS_MODULE, - .read = aim_read, - .write = aim_write, - .open = aim_open, - .release = aim_close, - .poll = aim_poll, + .read = comp_read, + .write = comp_write, + .open = comp_open, + .release = comp_close, + .poll = comp_poll, }; /** - * aim_disconnect_channel - disconnect a channel + * comp_disconnect_channel - disconnect a channel * @iface: pointer to interface instance * @channel_id: channel index * * This frees allocated memory and removes the cdev that represents this * channel in user space. */ -static int aim_disconnect_channel(struct most_interface *iface, int channel_id) +static int comp_disconnect_channel(struct most_interface *iface, int channel_id) { - struct aim_channel *c; + struct comp_channel *c; if (!iface) { pr_info("Bad interface pointer\n"); @@ -354,15 +350,15 @@ static int aim_disconnect_channel(struct most_interface *iface, int channel_id) } /** - * aim_rx_completion - completion handler for rx channels + * comp_rx_completion - completion handler for rx channels * @mbo: pointer to buffer object that has completed * * This searches for the channel linked to this MBO and stores it in the local * fifo buffer. */ -static int aim_rx_completion(struct mbo *mbo) +static int comp_rx_completion(struct mbo *mbo) { - struct aim_channel *c; + struct comp_channel *c; if (!mbo) return -EINVAL; @@ -387,15 +383,15 @@ static int aim_rx_completion(struct mbo *mbo) } /** - * aim_tx_completion - completion handler for tx channels + * comp_tx_completion - completion handler for tx channels * @iface: pointer to interface instance * @channel_id: channel index/ID * * This wakes sleeping processes in the wait-queue. */ -static int aim_tx_completion(struct most_interface *iface, int channel_id) +static int comp_tx_completion(struct most_interface *iface, int channel_id) { - struct aim_channel *c; + struct comp_channel *c; if (!iface) { pr_info("Bad interface pointer\n"); @@ -414,35 +410,33 @@ static int aim_tx_completion(struct most_interface *iface, int channel_id) } /** - * aim_probe - probe function of the driver module + * comp_probe - probe function of the driver module * @iface: pointer to interface instance * @channel_id: channel index/ID * @cfg: pointer to actual channel configuration - * @parent: pointer to kobject (needed for sysfs hook-up) * @name: name of the device to be created * * This allocates achannel object and creates the device node in /dev * * Returns 0 on success or error code otherwise. */ -static int aim_probe(struct most_interface *iface, int channel_id, - struct most_channel_config *cfg, - struct kobject *parent, char *name) +static int comp_probe(struct most_interface *iface, int channel_id, + struct most_channel_config *cfg, char *name) { - struct aim_channel *c; + struct comp_channel *c; unsigned long cl_flags; int retval; int current_minor; - if ((!iface) || (!cfg) || (!parent) || (!name)) { - pr_info("Probing AIM with bad arguments"); + if ((!iface) || (!cfg) || (!name)) { + pr_info("Probing component with bad arguments"); return -EINVAL; } c = get_channel(iface, channel_id); if (c) return -EEXIST; - current_minor = ida_simple_get(&minor_id, 0, 0, GFP_KERNEL); + current_minor = ida_simple_get(&comp.minor_id, 0, 0, GFP_KERNEL); if (current_minor < 0) return current_minor; @@ -452,7 +446,7 @@ static int aim_probe(struct most_interface *iface, int channel_id, goto error_alloc_channel; } - c->devno = MKDEV(major, current_minor); + c->devno = MKDEV(comp.major, current_minor); cdev_init(&c->cdev, &channel_fops); c->cdev.owner = THIS_MODULE; cdev_add(&c->cdev, c->devno, 1); @@ -472,11 +466,7 @@ static int aim_probe(struct most_interface *iface, int channel_id, spin_lock_irqsave(&ch_list_lock, cl_flags); list_add_tail(&c->list, &channel_list); spin_unlock_irqrestore(&ch_list_lock, cl_flags); - c->dev = device_create(aim_class, - NULL, - c->devno, - NULL, - "%s", name); + c->dev = device_create(comp.class, NULL, c->devno, NULL, "%s", name); if (IS_ERR(c->dev)) { retval = PTR_ERR(c->dev); @@ -493,16 +483,18 @@ error_alloc_kfifo: cdev_del(&c->cdev); kfree(c); error_alloc_channel: - ida_simple_remove(&minor_id, current_minor); + ida_simple_remove(&comp.minor_id, current_minor); return retval; } -static struct most_aim cdev_aim = { - .name = "cdev", - .probe_channel = aim_probe, - .disconnect_channel = aim_disconnect_channel, - .rx_completion = aim_rx_completion, - .tx_completion = aim_tx_completion, +static struct cdev_component comp = { + .cc = { + .name = "cdev", + .probe_channel = comp_probe, + .disconnect_channel = comp_disconnect_channel, + .rx_completion = comp_rx_completion, + .tx_completion = comp_tx_completion, + }, }; static int __init mod_init(void) @@ -511,54 +503,52 @@ static int __init mod_init(void) pr_info("init()\n"); + comp.class = class_create(THIS_MODULE, "most_cdev"); + if (IS_ERR(comp.class)) { + pr_info("No udev support.\n"); + return PTR_ERR(comp.class); + } + INIT_LIST_HEAD(&channel_list); spin_lock_init(&ch_list_lock); - ida_init(&minor_id); + ida_init(&comp.minor_id); - err = alloc_chrdev_region(&aim_devno, 0, 50, "cdev"); + err = alloc_chrdev_region(&comp.devno, 0, 50, "cdev"); if (err < 0) goto dest_ida; - major = MAJOR(aim_devno); - - aim_class = class_create(THIS_MODULE, "most_cdev_aim"); - if (IS_ERR(aim_class)) { - pr_err("no udev support\n"); - err = PTR_ERR(aim_class); - goto free_cdev; - } - err = most_register_aim(&cdev_aim); + comp.major = MAJOR(comp.devno); + err = most_register_component(&comp.cc); if (err) - goto dest_class; + goto free_cdev; return 0; -dest_class: - class_destroy(aim_class); free_cdev: - unregister_chrdev_region(aim_devno, 1); + unregister_chrdev_region(comp.devno, 1); dest_ida: - ida_destroy(&minor_id); + ida_destroy(&comp.minor_id); + class_destroy(comp.class); return err; } static void __exit mod_exit(void) { - struct aim_channel *c, *tmp; + struct comp_channel *c, *tmp; pr_info("exit module\n"); - most_deregister_aim(&cdev_aim); + most_deregister_component(&comp.cc); list_for_each_entry_safe(c, tmp, &channel_list, list) { destroy_cdev(c); destroy_channel(c); } - class_destroy(aim_class); - unregister_chrdev_region(aim_devno, 1); - ida_destroy(&minor_id); + unregister_chrdev_region(comp.devno, 1); + ida_destroy(&comp.minor_id); + class_destroy(comp.class); } module_init(mod_init); module_exit(mod_exit); MODULE_AUTHOR("Christian Gromm <christian.gromm@microchip.com>"); MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("character device AIM for mostcore"); +MODULE_DESCRIPTION("character device component for mostcore"); diff --git a/drivers/staging/most/core.c b/drivers/staging/most/core.c new file mode 100644 index 000000000000..3dda8d81bf0b --- /dev/null +++ b/drivers/staging/most/core.c @@ -0,0 +1,1603 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * core.c - Implementation of core module of MOST Linux driver stack + * + * Copyright (C) 2013-2015 Microchip Technology Germany II GmbH & Co. KG + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include <linux/module.h> +#include <linux/fs.h> +#include <linux/slab.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/list.h> +#include <linux/poll.h> +#include <linux/wait.h> +#include <linux/kobject.h> +#include <linux/mutex.h> +#include <linux/completion.h> +#include <linux/sysfs.h> +#include <linux/kthread.h> +#include <linux/dma-mapping.h> +#include <linux/idr.h> +#include <most/core.h> + +#define MAX_CHANNELS 64 +#define STRING_SIZE 80 + +static struct ida mdev_id; +static int dummy_num_buffers; + +static struct mostcore { + struct device dev; + struct device_driver drv; + struct bus_type bus; + struct list_head comp_list; +} mc; + +#define to_driver(d) container_of(d, struct mostcore, drv) + +struct pipe { + struct core_component *comp; + int refs; + int num_buffers; +}; + +struct most_channel { + struct device dev; + struct completion cleanup; + atomic_t mbo_ref; + atomic_t mbo_nq_level; + u16 channel_id; + char name[STRING_SIZE]; + bool is_poisoned; + struct mutex start_mutex; + struct mutex nq_mutex; /* nq thread synchronization */ + int is_starving; + struct most_interface *iface; + struct most_channel_config cfg; + bool keep_mbo; + bool enqueue_halt; + struct list_head fifo; + spinlock_t fifo_lock; + struct list_head halt_fifo; + struct list_head list; + struct pipe pipe0; + struct pipe pipe1; + struct list_head trash_fifo; + struct task_struct *hdm_enqueue_task; + wait_queue_head_t hdm_fifo_wq; + +}; + +#define to_channel(d) container_of(d, struct most_channel, dev) + +struct interface_private { + int dev_id; + char name[STRING_SIZE]; + struct most_channel *channel[MAX_CHANNELS]; + struct list_head channel_list; +}; + +static const struct { + int most_ch_data_type; + const char *name; +} ch_data_type[] = { + { MOST_CH_CONTROL, "control\n" }, + { MOST_CH_ASYNC, "async\n" }, + { MOST_CH_SYNC, "sync\n" }, + { MOST_CH_ISOC, "isoc\n"}, + { MOST_CH_ISOC, "isoc_avp\n"}, +}; + +/** + * list_pop_mbo - retrieves the first MBO of the list and removes it + * @ptr: the list head to grab the MBO from. + */ +#define list_pop_mbo(ptr) \ +({ \ + struct mbo *_mbo = list_first_entry(ptr, struct mbo, list); \ + list_del(&_mbo->list); \ + _mbo; \ +}) + +/** + * most_free_mbo_coherent - free an MBO and its coherent buffer + * @mbo: most buffer + */ +static void most_free_mbo_coherent(struct mbo *mbo) +{ + struct most_channel *c = mbo->context; + u16 const coherent_buf_size = c->cfg.buffer_size + c->cfg.extra_len; + + dma_free_coherent(NULL, coherent_buf_size, mbo->virt_address, + mbo->bus_address); + kfree(mbo); + if (atomic_sub_and_test(1, &c->mbo_ref)) + complete(&c->cleanup); +} + +/** + * flush_channel_fifos - clear the channel fifos + * @c: pointer to channel object + */ +static void flush_channel_fifos(struct most_channel *c) +{ + unsigned long flags, hf_flags; + struct mbo *mbo, *tmp; + + if (list_empty(&c->fifo) && list_empty(&c->halt_fifo)) + return; + + spin_lock_irqsave(&c->fifo_lock, flags); + list_for_each_entry_safe(mbo, tmp, &c->fifo, list) { + list_del(&mbo->list); + spin_unlock_irqrestore(&c->fifo_lock, flags); + most_free_mbo_coherent(mbo); + spin_lock_irqsave(&c->fifo_lock, flags); + } + spin_unlock_irqrestore(&c->fifo_lock, flags); + + spin_lock_irqsave(&c->fifo_lock, hf_flags); + list_for_each_entry_safe(mbo, tmp, &c->halt_fifo, list) { + list_del(&mbo->list); + spin_unlock_irqrestore(&c->fifo_lock, hf_flags); + most_free_mbo_coherent(mbo); + spin_lock_irqsave(&c->fifo_lock, hf_flags); + } + spin_unlock_irqrestore(&c->fifo_lock, hf_flags); + + if (unlikely((!list_empty(&c->fifo) || !list_empty(&c->halt_fifo)))) + pr_info("WARN: fifo | trash fifo not empty\n"); +} + +/** + * flush_trash_fifo - clear the trash fifo + * @c: pointer to channel object + */ +static int flush_trash_fifo(struct most_channel *c) +{ + struct mbo *mbo, *tmp; + unsigned long flags; + + spin_lock_irqsave(&c->fifo_lock, flags); + list_for_each_entry_safe(mbo, tmp, &c->trash_fifo, list) { + list_del(&mbo->list); + spin_unlock_irqrestore(&c->fifo_lock, flags); + most_free_mbo_coherent(mbo); + spin_lock_irqsave(&c->fifo_lock, flags); + } + spin_unlock_irqrestore(&c->fifo_lock, flags); + return 0; +} + +static ssize_t available_directions_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct most_channel *c = to_channel(dev); + unsigned int i = c->channel_id; + + strcpy(buf, ""); + if (c->iface->channel_vector[i].direction & MOST_CH_RX) + strcat(buf, "rx "); + if (c->iface->channel_vector[i].direction & MOST_CH_TX) + strcat(buf, "tx "); + strcat(buf, "\n"); + return strlen(buf); +} + +static ssize_t available_datatypes_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct most_channel *c = to_channel(dev); + unsigned int i = c->channel_id; + + strcpy(buf, ""); + if (c->iface->channel_vector[i].data_type & MOST_CH_CONTROL) + strcat(buf, "control "); + if (c->iface->channel_vector[i].data_type & MOST_CH_ASYNC) + strcat(buf, "async "); + if (c->iface->channel_vector[i].data_type & MOST_CH_SYNC) + strcat(buf, "sync "); + if (c->iface->channel_vector[i].data_type & MOST_CH_ISOC) + strcat(buf, "isoc "); + strcat(buf, "\n"); + return strlen(buf); +} + +static ssize_t number_of_packet_buffers_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct most_channel *c = to_channel(dev); + unsigned int i = c->channel_id; + + return snprintf(buf, PAGE_SIZE, "%d\n", + c->iface->channel_vector[i].num_buffers_packet); +} + +static ssize_t number_of_stream_buffers_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct most_channel *c = to_channel(dev); + unsigned int i = c->channel_id; + + return snprintf(buf, PAGE_SIZE, "%d\n", + c->iface->channel_vector[i].num_buffers_streaming); +} + +static ssize_t size_of_packet_buffer_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct most_channel *c = to_channel(dev); + unsigned int i = c->channel_id; + + return snprintf(buf, PAGE_SIZE, "%d\n", + c->iface->channel_vector[i].buffer_size_packet); +} + +static ssize_t size_of_stream_buffer_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct most_channel *c = to_channel(dev); + unsigned int i = c->channel_id; + + return snprintf(buf, PAGE_SIZE, "%d\n", + c->iface->channel_vector[i].buffer_size_streaming); +} + +static ssize_t channel_starving_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct most_channel *c = to_channel(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", c->is_starving); +} + +static ssize_t set_number_of_buffers_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct most_channel *c = to_channel(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", c->cfg.num_buffers); +} + +static ssize_t set_number_of_buffers_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct most_channel *c = to_channel(dev); + int ret = kstrtou16(buf, 0, &c->cfg.num_buffers); + + if (ret) + return ret; + return count; +} + +static ssize_t set_buffer_size_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct most_channel *c = to_channel(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", c->cfg.buffer_size); +} + +static ssize_t set_buffer_size_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct most_channel *c = to_channel(dev); + int ret = kstrtou16(buf, 0, &c->cfg.buffer_size); + + if (ret) + return ret; + return count; +} + +static ssize_t set_direction_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct most_channel *c = to_channel(dev); + + if (c->cfg.direction & MOST_CH_TX) + return snprintf(buf, PAGE_SIZE, "tx\n"); + else if (c->cfg.direction & MOST_CH_RX) + return snprintf(buf, PAGE_SIZE, "rx\n"); + return snprintf(buf, PAGE_SIZE, "unconfigured\n"); +} + +static ssize_t set_direction_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct most_channel *c = to_channel(dev); + + if (!strcmp(buf, "dir_rx\n")) { + c->cfg.direction = MOST_CH_RX; + } else if (!strcmp(buf, "rx\n")) { + c->cfg.direction = MOST_CH_RX; + } else if (!strcmp(buf, "dir_tx\n")) { + c->cfg.direction = MOST_CH_TX; + } else if (!strcmp(buf, "tx\n")) { + c->cfg.direction = MOST_CH_TX; + } else { + pr_info("WARN: invalid attribute settings\n"); + return -EINVAL; + } + return count; +} + +static ssize_t set_datatype_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int i; + struct most_channel *c = to_channel(dev); + + for (i = 0; i < ARRAY_SIZE(ch_data_type); i++) { + if (c->cfg.data_type & ch_data_type[i].most_ch_data_type) + return snprintf(buf, PAGE_SIZE, ch_data_type[i].name); + } + return snprintf(buf, PAGE_SIZE, "unconfigured\n"); +} + +static ssize_t set_datatype_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + int i; + struct most_channel *c = to_channel(dev); + + for (i = 0; i < ARRAY_SIZE(ch_data_type); i++) { + if (!strcmp(buf, ch_data_type[i].name)) { + c->cfg.data_type = ch_data_type[i].most_ch_data_type; + break; + } + } + + if (i == ARRAY_SIZE(ch_data_type)) { + pr_info("WARN: invalid attribute settings\n"); + return -EINVAL; + } + return count; +} + +static ssize_t set_subbuffer_size_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct most_channel *c = to_channel(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", c->cfg.subbuffer_size); +} + +static ssize_t set_subbuffer_size_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct most_channel *c = to_channel(dev); + int ret = kstrtou16(buf, 0, &c->cfg.subbuffer_size); + + if (ret) + return ret; + return count; +} + +static ssize_t set_packets_per_xact_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct most_channel *c = to_channel(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", c->cfg.packets_per_xact); +} + +static ssize_t set_packets_per_xact_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct most_channel *c = to_channel(dev); + int ret = kstrtou16(buf, 0, &c->cfg.packets_per_xact); + + if (ret) + return ret; + return count; +} + +#define DEV_ATTR(_name) (&dev_attr_##_name.attr) + +static DEVICE_ATTR_RO(available_directions); +static DEVICE_ATTR_RO(available_datatypes); +static DEVICE_ATTR_RO(number_of_packet_buffers); +static DEVICE_ATTR_RO(number_of_stream_buffers); +static DEVICE_ATTR_RO(size_of_stream_buffer); +static DEVICE_ATTR_RO(size_of_packet_buffer); +static DEVICE_ATTR_RO(channel_starving); +static DEVICE_ATTR_RW(set_buffer_size); +static DEVICE_ATTR_RW(set_number_of_buffers); +static DEVICE_ATTR_RW(set_direction); +static DEVICE_ATTR_RW(set_datatype); +static DEVICE_ATTR_RW(set_subbuffer_size); +static DEVICE_ATTR_RW(set_packets_per_xact); + +static struct attribute *channel_attrs[] = { + DEV_ATTR(available_directions), + DEV_ATTR(available_datatypes), + DEV_ATTR(number_of_packet_buffers), + DEV_ATTR(number_of_stream_buffers), + DEV_ATTR(size_of_stream_buffer), + DEV_ATTR(size_of_packet_buffer), + DEV_ATTR(channel_starving), + DEV_ATTR(set_buffer_size), + DEV_ATTR(set_number_of_buffers), + DEV_ATTR(set_direction), + DEV_ATTR(set_datatype), + DEV_ATTR(set_subbuffer_size), + DEV_ATTR(set_packets_per_xact), + NULL, +}; + +static struct attribute_group channel_attr_group = { + .attrs = channel_attrs, +}; + +static const struct attribute_group *channel_attr_groups[] = { + &channel_attr_group, + NULL, +}; + +static ssize_t description_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct most_interface *iface = to_most_interface(dev); + + return snprintf(buf, PAGE_SIZE, "%s\n", iface->description); +} + +static ssize_t interface_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct most_interface *iface = to_most_interface(dev); + + switch (iface->interface) { + case ITYPE_LOOPBACK: + return snprintf(buf, PAGE_SIZE, "loopback\n"); + case ITYPE_I2C: + return snprintf(buf, PAGE_SIZE, "i2c\n"); + case ITYPE_I2S: + return snprintf(buf, PAGE_SIZE, "i2s\n"); + case ITYPE_TSI: + return snprintf(buf, PAGE_SIZE, "tsi\n"); + case ITYPE_HBI: + return snprintf(buf, PAGE_SIZE, "hbi\n"); + case ITYPE_MEDIALB_DIM: + return snprintf(buf, PAGE_SIZE, "mlb_dim\n"); + case ITYPE_MEDIALB_DIM2: + return snprintf(buf, PAGE_SIZE, "mlb_dim2\n"); + case ITYPE_USB: + return snprintf(buf, PAGE_SIZE, "usb\n"); + case ITYPE_PCIE: + return snprintf(buf, PAGE_SIZE, "pcie\n"); + } + return snprintf(buf, PAGE_SIZE, "unknown\n"); +} + +static DEVICE_ATTR_RO(description); +static DEVICE_ATTR_RO(interface); + +static struct attribute *interface_attrs[] = { + DEV_ATTR(description), + DEV_ATTR(interface), + NULL, +}; + +static struct attribute_group interface_attr_group = { + .attrs = interface_attrs, +}; + +static const struct attribute_group *interface_attr_groups[] = { + &interface_attr_group, + NULL, +}; + +static struct core_component *match_component(char *name) +{ + struct core_component *comp; + + list_for_each_entry(comp, &mc.comp_list, list) { + if (!strcmp(comp->name, name)) + return comp; + } + return NULL; +} + +struct show_links_data { + int offs; + char *buf; +}; + +static int print_links(struct device *dev, void *data) +{ + struct show_links_data *d = data; + int offs = d->offs; + char *buf = d->buf; + struct most_channel *c; + struct most_interface *iface = to_most_interface(dev); + + list_for_each_entry(c, &iface->p->channel_list, list) { + if (c->pipe0.comp) { + offs += snprintf(buf + offs, + PAGE_SIZE - offs, + "%s:%s:%s\n", + c->pipe0.comp->name, + dev_name(&iface->dev), + dev_name(&c->dev)); + } + if (c->pipe1.comp) { + offs += snprintf(buf + offs, + PAGE_SIZE - offs, + "%s:%s:%s\n", + c->pipe1.comp->name, + dev_name(&iface->dev), + dev_name(&c->dev)); + } + } + d->offs = offs; + return 0; +} + +static ssize_t links_show(struct device_driver *drv, char *buf) +{ + struct show_links_data d = { .buf = buf }; + + bus_for_each_dev(&mc.bus, NULL, &d, print_links); + return d.offs; +} + +static ssize_t components_show(struct device_driver *drv, char *buf) +{ + struct core_component *comp; + int offs = 0; + + list_for_each_entry(comp, &mc.comp_list, list) { + offs += snprintf(buf + offs, PAGE_SIZE - offs, "%s\n", + comp->name); + } + return offs; +} +/** + * split_string - parses buf and extracts ':' separated substrings. + * + * @buf: complete string from attribute 'add_channel' + * @a: storage for 1st substring (=interface name) + * @b: storage for 2nd substring (=channel name) + * @c: storage for 3rd substring (=component name) + * @d: storage optional 4th substring (=user defined name) + * + * Examples: + * + * Input: "mdev0:ch6:cdev:my_channel\n" or + * "mdev0:ch6:cdev:my_channel" + * + * Output: *a -> "mdev0", *b -> "ch6", *c -> "cdev" *d -> "my_channel" + * + * Input: "mdev1:ep81:cdev\n" + * Output: *a -> "mdev1", *b -> "ep81", *c -> "cdev" *d -> "" + * + * Input: "mdev1:ep81" + * Output: *a -> "mdev1", *b -> "ep81", *c -> "cdev" *d == NULL + */ +static int split_string(char *buf, char **a, char **b, char **c, char **d) +{ + *a = strsep(&buf, ":"); + if (!*a) + return -EIO; + + *b = strsep(&buf, ":\n"); + if (!*b) + return -EIO; + + *c = strsep(&buf, ":\n"); + if (!*c) + return -EIO; + + if (d) + *d = strsep(&buf, ":\n"); + + return 0; +} + +static int match_bus_dev(struct device *dev, void *data) +{ + char *mdev_name = data; + + return !strcmp(dev_name(dev), mdev_name); +} + +/** + * get_channel - get pointer to channel + * @mdev: name of the device interface + * @mdev_ch: name of channel + */ +static struct most_channel *get_channel(char *mdev, char *mdev_ch) +{ + struct device *dev = NULL; + struct most_interface *iface; + struct most_channel *c, *tmp; + + dev = bus_find_device(&mc.bus, NULL, mdev, match_bus_dev); + if (!dev) + return NULL; + iface = to_most_interface(dev); + list_for_each_entry_safe(c, tmp, &iface->p->channel_list, list) { + if (!strcmp(dev_name(&c->dev), mdev_ch)) + return c; + } + return NULL; +} + +static +inline int link_channel_to_component(struct most_channel *c, + struct core_component *comp, + char *comp_param) +{ + int ret; + struct core_component **comp_ptr; + + if (!c->pipe0.comp) + comp_ptr = &c->pipe0.comp; + else if (!c->pipe1.comp) + comp_ptr = &c->pipe1.comp; + else + return -ENOSPC; + + *comp_ptr = comp; + ret = comp->probe_channel(c->iface, c->channel_id, &c->cfg, comp_param); + if (ret) { + *comp_ptr = NULL; + return ret; + } + return 0; +} + +/** + * add_link_store - store function for add_link attribute + * @drv: device driver + * @buf: buffer + * @len: buffer length + * + * This parses the string given by buf and splits it into + * four substrings. Note: last substring is optional. In case a cdev + * component is loaded the optional 4th substring will make up the name of + * device node in the /dev directory. If omitted, the device node will + * inherit the channel's name within sysfs. + * + * Searches for (device, channel) pair and probes the component + * + * Example: + * (1) echo "mdev0:ch6:cdev:my_rxchannel" >add_link + * (2) echo "mdev1:ep81:cdev" >add_link + * + * (1) would create the device node /dev/my_rxchannel + * (2) would create the device node /dev/mdev1-ep81 + */ +static ssize_t add_link_store(struct device_driver *drv, + const char *buf, + size_t len) +{ + struct most_channel *c; + struct core_component *comp; + char buffer[STRING_SIZE]; + char *mdev; + char *mdev_ch; + char *comp_name; + char *comp_param; + char devnod_buf[STRING_SIZE]; + int ret; + size_t max_len = min_t(size_t, len + 1, STRING_SIZE); + + strlcpy(buffer, buf, max_len); + ret = split_string(buffer, &mdev, &mdev_ch, &comp_name, &comp_param); + if (ret) + return ret; + comp = match_component(comp_name); + if (!comp) + return -ENODEV; + if (!comp_param || *comp_param == 0) { + snprintf(devnod_buf, sizeof(devnod_buf), "%s-%s", mdev, + mdev_ch); + comp_param = devnod_buf; + } + + c = get_channel(mdev, mdev_ch); + if (!c) + return -ENODEV; + + ret = link_channel_to_component(c, comp, comp_param); + if (ret) + return ret; + return len; +} + +/** + * remove_link_store - store function for remove_link attribute + * @drv: device driver + * @buf: buffer + * @len: buffer length + * + * Example: + * echo "mdev0:ep81" >remove_link + */ +static ssize_t remove_link_store(struct device_driver *drv, + const char *buf, + size_t len) +{ + struct most_channel *c; + struct core_component *comp; + char buffer[STRING_SIZE]; + char *mdev; + char *mdev_ch; + char *comp_name; + int ret; + size_t max_len = min_t(size_t, len + 1, STRING_SIZE); + + strlcpy(buffer, buf, max_len); + ret = split_string(buffer, &mdev, &mdev_ch, &comp_name, NULL); + if (ret) + return ret; + comp = match_component(comp_name); + if (!comp) + return -ENODEV; + c = get_channel(mdev, mdev_ch); + if (!c) + return -ENODEV; + + if (comp->disconnect_channel(c->iface, c->channel_id)) + return -EIO; + if (c->pipe0.comp == comp) + c->pipe0.comp = NULL; + if (c->pipe1.comp == comp) + c->pipe1.comp = NULL; + return len; +} + +#define DRV_ATTR(_name) (&driver_attr_##_name.attr) + +static DRIVER_ATTR_RO(links); +static DRIVER_ATTR_RO(components); +static DRIVER_ATTR_WO(add_link); +static DRIVER_ATTR_WO(remove_link); + +static struct attribute *mc_attrs[] = { + DRV_ATTR(links), + DRV_ATTR(components), + DRV_ATTR(add_link), + DRV_ATTR(remove_link), + NULL, +}; + +static struct attribute_group mc_attr_group = { + .attrs = mc_attrs, +}; + +static const struct attribute_group *mc_attr_groups[] = { + &mc_attr_group, + NULL, +}; + +static int most_match(struct device *dev, struct device_driver *drv) +{ + if (!strcmp(dev_name(dev), "most")) + return 0; + else + return 1; +} + +static inline void trash_mbo(struct mbo *mbo) +{ + unsigned long flags; + struct most_channel *c = mbo->context; + + spin_lock_irqsave(&c->fifo_lock, flags); + list_add(&mbo->list, &c->trash_fifo); + spin_unlock_irqrestore(&c->fifo_lock, flags); +} + +static bool hdm_mbo_ready(struct most_channel *c) +{ + bool empty; + + if (c->enqueue_halt) + return false; + + spin_lock_irq(&c->fifo_lock); + empty = list_empty(&c->halt_fifo); + spin_unlock_irq(&c->fifo_lock); + + return !empty; +} + +static void nq_hdm_mbo(struct mbo *mbo) +{ + unsigned long flags; + struct most_channel *c = mbo->context; + + spin_lock_irqsave(&c->fifo_lock, flags); + list_add_tail(&mbo->list, &c->halt_fifo); + spin_unlock_irqrestore(&c->fifo_lock, flags); + wake_up_interruptible(&c->hdm_fifo_wq); +} + +static int hdm_enqueue_thread(void *data) +{ + struct most_channel *c = data; + struct mbo *mbo; + int ret; + typeof(c->iface->enqueue) enqueue = c->iface->enqueue; + + while (likely(!kthread_should_stop())) { + wait_event_interruptible(c->hdm_fifo_wq, + hdm_mbo_ready(c) || + kthread_should_stop()); + + mutex_lock(&c->nq_mutex); + spin_lock_irq(&c->fifo_lock); + if (unlikely(c->enqueue_halt || list_empty(&c->halt_fifo))) { + spin_unlock_irq(&c->fifo_lock); + mutex_unlock(&c->nq_mutex); + continue; + } + + mbo = list_pop_mbo(&c->halt_fifo); + spin_unlock_irq(&c->fifo_lock); + + if (c->cfg.direction == MOST_CH_RX) + mbo->buffer_length = c->cfg.buffer_size; + + ret = enqueue(mbo->ifp, mbo->hdm_channel_id, mbo); + mutex_unlock(&c->nq_mutex); + + if (unlikely(ret)) { + pr_err("hdm enqueue failed\n"); + nq_hdm_mbo(mbo); + c->hdm_enqueue_task = NULL; + return 0; + } + } + + return 0; +} + +static int run_enqueue_thread(struct most_channel *c, int channel_id) +{ + struct task_struct *task = + kthread_run(hdm_enqueue_thread, c, "hdm_fifo_%d", + channel_id); + + if (IS_ERR(task)) + return PTR_ERR(task); + + c->hdm_enqueue_task = task; + return 0; +} + +/** + * arm_mbo - recycle MBO for further usage + * @mbo: most buffer + * + * This puts an MBO back to the list to have it ready for up coming + * tx transactions. + * + * In case the MBO belongs to a channel that recently has been + * poisoned, the MBO is scheduled to be trashed. + * Calls the completion handler of an attached component. + */ +static void arm_mbo(struct mbo *mbo) +{ + unsigned long flags; + struct most_channel *c; + + BUG_ON((!mbo) || (!mbo->context)); + c = mbo->context; + + if (c->is_poisoned) { + trash_mbo(mbo); + return; + } + + spin_lock_irqsave(&c->fifo_lock, flags); + ++*mbo->num_buffers_ptr; + list_add_tail(&mbo->list, &c->fifo); + spin_unlock_irqrestore(&c->fifo_lock, flags); + + if (c->pipe0.refs && c->pipe0.comp->tx_completion) + c->pipe0.comp->tx_completion(c->iface, c->channel_id); + + if (c->pipe1.refs && c->pipe1.comp->tx_completion) + c->pipe1.comp->tx_completion(c->iface, c->channel_id); +} + +/** + * arm_mbo_chain - helper function that arms an MBO chain for the HDM + * @c: pointer to interface channel + * @dir: direction of the channel + * @compl: pointer to completion function + * + * This allocates buffer objects including the containing DMA coherent + * buffer and puts them in the fifo. + * Buffers of Rx channels are put in the kthread fifo, hence immediately + * submitted to the HDM. + * + * Returns the number of allocated and enqueued MBOs. + */ +static int arm_mbo_chain(struct most_channel *c, int dir, + void (*compl)(struct mbo *)) +{ + unsigned int i; + int retval; + struct mbo *mbo; + u32 coherent_buf_size = c->cfg.buffer_size + c->cfg.extra_len; + + atomic_set(&c->mbo_nq_level, 0); + + for (i = 0; i < c->cfg.num_buffers; i++) { + mbo = kzalloc(sizeof(*mbo), GFP_KERNEL); + if (!mbo) { + retval = i; + goto _exit; + } + mbo->context = c; + mbo->ifp = c->iface; + mbo->hdm_channel_id = c->channel_id; + mbo->virt_address = dma_alloc_coherent(NULL, + coherent_buf_size, + &mbo->bus_address, + GFP_KERNEL); + if (!mbo->virt_address) { + pr_info("WARN: No DMA coherent buffer.\n"); + retval = i; + goto _error1; + } + mbo->complete = compl; + mbo->num_buffers_ptr = &dummy_num_buffers; + if (dir == MOST_CH_RX) { + nq_hdm_mbo(mbo); + atomic_inc(&c->mbo_nq_level); + } else { + arm_mbo(mbo); + } + } + return i; + +_error1: + kfree(mbo); +_exit: + return retval; +} + +/** + * most_submit_mbo - submits an MBO to fifo + * @mbo: most buffer + */ +void most_submit_mbo(struct mbo *mbo) +{ + if (WARN_ONCE(!mbo || !mbo->context, + "bad mbo or missing channel reference\n")) + return; + + nq_hdm_mbo(mbo); +} +EXPORT_SYMBOL_GPL(most_submit_mbo); + +/** + * most_write_completion - write completion handler + * @mbo: most buffer + * + * This recycles the MBO for further usage. In case the channel has been + * poisoned, the MBO is scheduled to be trashed. + */ +static void most_write_completion(struct mbo *mbo) +{ + struct most_channel *c; + + BUG_ON((!mbo) || (!mbo->context)); + + c = mbo->context; + if (mbo->status == MBO_E_INVAL) + pr_info("WARN: Tx MBO status: invalid\n"); + if (unlikely(c->is_poisoned || (mbo->status == MBO_E_CLOSE))) + trash_mbo(mbo); + else + arm_mbo(mbo); +} + +int channel_has_mbo(struct most_interface *iface, int id, + struct core_component *comp) +{ + struct most_channel *c = iface->p->channel[id]; + unsigned long flags; + int empty; + + if (unlikely(!c)) + return -EINVAL; + + if (c->pipe0.refs && c->pipe1.refs && + ((comp == c->pipe0.comp && c->pipe0.num_buffers <= 0) || + (comp == c->pipe1.comp && c->pipe1.num_buffers <= 0))) + return 0; + + spin_lock_irqsave(&c->fifo_lock, flags); + empty = list_empty(&c->fifo); + spin_unlock_irqrestore(&c->fifo_lock, flags); + return !empty; +} +EXPORT_SYMBOL_GPL(channel_has_mbo); + +/** + * most_get_mbo - get pointer to an MBO of pool + * @iface: pointer to interface instance + * @id: channel ID + * @comp: driver component + * + * This attempts to get a free buffer out of the channel fifo. + * Returns a pointer to MBO on success or NULL otherwise. + */ +struct mbo *most_get_mbo(struct most_interface *iface, int id, + struct core_component *comp) +{ + struct mbo *mbo; + struct most_channel *c; + unsigned long flags; + int *num_buffers_ptr; + + c = iface->p->channel[id]; + if (unlikely(!c)) + return NULL; + + if (c->pipe0.refs && c->pipe1.refs && + ((comp == c->pipe0.comp && c->pipe0.num_buffers <= 0) || + (comp == c->pipe1.comp && c->pipe1.num_buffers <= 0))) + return NULL; + + if (comp == c->pipe0.comp) + num_buffers_ptr = &c->pipe0.num_buffers; + else if (comp == c->pipe1.comp) + num_buffers_ptr = &c->pipe1.num_buffers; + else + num_buffers_ptr = &dummy_num_buffers; + + spin_lock_irqsave(&c->fifo_lock, flags); + if (list_empty(&c->fifo)) { + spin_unlock_irqrestore(&c->fifo_lock, flags); + return NULL; + } + mbo = list_pop_mbo(&c->fifo); + --*num_buffers_ptr; + spin_unlock_irqrestore(&c->fifo_lock, flags); + + mbo->num_buffers_ptr = num_buffers_ptr; + mbo->buffer_length = c->cfg.buffer_size; + return mbo; +} +EXPORT_SYMBOL_GPL(most_get_mbo); + +/** + * most_put_mbo - return buffer to pool + * @mbo: most buffer + */ +void most_put_mbo(struct mbo *mbo) +{ + struct most_channel *c = mbo->context; + + if (c->cfg.direction == MOST_CH_TX) { + arm_mbo(mbo); + return; + } + nq_hdm_mbo(mbo); + atomic_inc(&c->mbo_nq_level); +} +EXPORT_SYMBOL_GPL(most_put_mbo); + +/** + * most_read_completion - read completion handler + * @mbo: most buffer + * + * This function is called by the HDM when data has been received from the + * hardware and copied to the buffer of the MBO. + * + * In case the channel has been poisoned it puts the buffer in the trash queue. + * Otherwise, it passes the buffer to an component for further processing. + */ +static void most_read_completion(struct mbo *mbo) +{ + struct most_channel *c = mbo->context; + + if (unlikely(c->is_poisoned || (mbo->status == MBO_E_CLOSE))) { + trash_mbo(mbo); + return; + } + + if (mbo->status == MBO_E_INVAL) { + nq_hdm_mbo(mbo); + atomic_inc(&c->mbo_nq_level); + return; + } + + if (atomic_sub_and_test(1, &c->mbo_nq_level)) + c->is_starving = 1; + + if (c->pipe0.refs && c->pipe0.comp->rx_completion && + c->pipe0.comp->rx_completion(mbo) == 0) + return; + + if (c->pipe1.refs && c->pipe1.comp->rx_completion && + c->pipe1.comp->rx_completion(mbo) == 0) + return; + + most_put_mbo(mbo); +} + +/** + * most_start_channel - prepares a channel for communication + * @iface: pointer to interface instance + * @id: channel ID + * @comp: driver component + * + * This prepares the channel for usage. Cross-checks whether the + * channel's been properly configured. + * + * Returns 0 on success or error code otherwise. + */ +int most_start_channel(struct most_interface *iface, int id, + struct core_component *comp) +{ + int num_buffer; + int ret; + struct most_channel *c = iface->p->channel[id]; + + if (unlikely(!c)) + return -EINVAL; + + mutex_lock(&c->start_mutex); + if (c->pipe0.refs + c->pipe1.refs > 0) + goto out; /* already started by another component */ + + if (!try_module_get(iface->mod)) { + pr_info("failed to acquire HDM lock\n"); + mutex_unlock(&c->start_mutex); + return -ENOLCK; + } + + c->cfg.extra_len = 0; + if (c->iface->configure(c->iface, c->channel_id, &c->cfg)) { + pr_info("channel configuration failed. Go check settings...\n"); + ret = -EINVAL; + goto error; + } + + init_waitqueue_head(&c->hdm_fifo_wq); + + if (c->cfg.direction == MOST_CH_RX) + num_buffer = arm_mbo_chain(c, c->cfg.direction, + most_read_completion); + else + num_buffer = arm_mbo_chain(c, c->cfg.direction, + most_write_completion); + if (unlikely(!num_buffer)) { + pr_info("failed to allocate memory\n"); + ret = -ENOMEM; + goto error; + } + + ret = run_enqueue_thread(c, id); + if (ret) + goto error; + + c->is_starving = 0; + c->pipe0.num_buffers = c->cfg.num_buffers / 2; + c->pipe1.num_buffers = c->cfg.num_buffers - c->pipe0.num_buffers; + atomic_set(&c->mbo_ref, num_buffer); + +out: + if (comp == c->pipe0.comp) + c->pipe0.refs++; + if (comp == c->pipe1.comp) + c->pipe1.refs++; + mutex_unlock(&c->start_mutex); + return 0; + +error: + module_put(iface->mod); + mutex_unlock(&c->start_mutex); + return ret; +} +EXPORT_SYMBOL_GPL(most_start_channel); + +/** + * most_stop_channel - stops a running channel + * @iface: pointer to interface instance + * @id: channel ID + * @comp: driver component + */ +int most_stop_channel(struct most_interface *iface, int id, + struct core_component *comp) +{ + struct most_channel *c; + + if (unlikely((!iface) || (id >= iface->num_channels) || (id < 0))) { + pr_err("Bad interface or index out of range\n"); + return -EINVAL; + } + c = iface->p->channel[id]; + if (unlikely(!c)) + return -EINVAL; + + mutex_lock(&c->start_mutex); + if (c->pipe0.refs + c->pipe1.refs >= 2) + goto out; + + if (c->hdm_enqueue_task) + kthread_stop(c->hdm_enqueue_task); + c->hdm_enqueue_task = NULL; + + if (iface->mod) + module_put(iface->mod); + + c->is_poisoned = true; + if (c->iface->poison_channel(c->iface, c->channel_id)) { + pr_err("Cannot stop channel %d of mdev %s\n", c->channel_id, + c->iface->description); + mutex_unlock(&c->start_mutex); + return -EAGAIN; + } + flush_trash_fifo(c); + flush_channel_fifos(c); + +#ifdef CMPL_INTERRUPTIBLE + if (wait_for_completion_interruptible(&c->cleanup)) { + pr_info("Interrupted while clean up ch %d\n", c->channel_id); + mutex_unlock(&c->start_mutex); + return -EINTR; + } +#else + wait_for_completion(&c->cleanup); +#endif + c->is_poisoned = false; + +out: + if (comp == c->pipe0.comp) + c->pipe0.refs--; + if (comp == c->pipe1.comp) + c->pipe1.refs--; + mutex_unlock(&c->start_mutex); + return 0; +} +EXPORT_SYMBOL_GPL(most_stop_channel); + +/** + * most_register_component - registers a driver component with the core + * @comp: driver component + */ +int most_register_component(struct core_component *comp) +{ + if (!comp) { + pr_err("Bad component\n"); + return -EINVAL; + } + list_add_tail(&comp->list, &mc.comp_list); + pr_info("registered new core component %s\n", comp->name); + return 0; +} +EXPORT_SYMBOL_GPL(most_register_component); + +static int disconnect_channels(struct device *dev, void *data) +{ + struct most_interface *iface; + struct most_channel *c, *tmp; + struct core_component *comp = data; + + iface = to_most_interface(dev); + list_for_each_entry_safe(c, tmp, &iface->p->channel_list, list) { + if (c->pipe0.comp == comp || c->pipe1.comp == comp) + comp->disconnect_channel(c->iface, c->channel_id); + if (c->pipe0.comp == comp) + c->pipe0.comp = NULL; + if (c->pipe1.comp == comp) + c->pipe1.comp = NULL; + } + return 0; +} + +/** + * most_deregister_component - deregisters a driver component with the core + * @comp: driver component + */ +int most_deregister_component(struct core_component *comp) +{ + if (!comp) { + pr_err("Bad component\n"); + return -EINVAL; + } + + bus_for_each_dev(&mc.bus, NULL, comp, disconnect_channels); + list_del(&comp->list); + pr_info("deregistering component %s\n", comp->name); + return 0; +} +EXPORT_SYMBOL_GPL(most_deregister_component); + +static void release_interface(struct device *dev) +{ + pr_info("releasing interface dev %s...\n", dev_name(dev)); +} + +static void release_channel(struct device *dev) +{ + pr_info("releasing channel dev %s...\n", dev_name(dev)); +} + +/** + * most_register_interface - registers an interface with core + * @iface: device interface + * + * Allocates and initializes a new interface instance and all of its channels. + * Returns a pointer to kobject or an error pointer. + */ +int most_register_interface(struct most_interface *iface) +{ + unsigned int i; + int id; + struct most_channel *c; + + if (!iface || !iface->enqueue || !iface->configure || + !iface->poison_channel || (iface->num_channels > MAX_CHANNELS)) { + pr_err("Bad interface or channel overflow\n"); + return -EINVAL; + } + + id = ida_simple_get(&mdev_id, 0, 0, GFP_KERNEL); + if (id < 0) { + pr_info("Failed to alloc mdev ID\n"); + return id; + } + + iface->p = kzalloc(sizeof(*iface->p), GFP_KERNEL); + if (!iface->p) { + pr_info("Failed to allocate interface instance\n"); + ida_simple_remove(&mdev_id, id); + return -ENOMEM; + } + + INIT_LIST_HEAD(&iface->p->channel_list); + iface->p->dev_id = id; + snprintf(iface->p->name, STRING_SIZE, "mdev%d", id); + iface->dev.init_name = iface->p->name; + iface->dev.bus = &mc.bus; + iface->dev.parent = &mc.dev; + iface->dev.groups = interface_attr_groups; + iface->dev.release = release_interface; + if (device_register(&iface->dev)) { + pr_err("registering iface->dev failed\n"); + kfree(iface->p); + ida_simple_remove(&mdev_id, id); + return -ENOMEM; + } + + for (i = 0; i < iface->num_channels; i++) { + const char *name_suffix = iface->channel_vector[i].name_suffix; + + c = kzalloc(sizeof(*c), GFP_KERNEL); + if (!c) + goto free_instance; + if (!name_suffix) + snprintf(c->name, STRING_SIZE, "ch%d", i); + else + snprintf(c->name, STRING_SIZE, "%s", name_suffix); + c->dev.init_name = c->name; + c->dev.parent = &iface->dev; + c->dev.groups = channel_attr_groups; + c->dev.release = release_channel; + if (device_register(&c->dev)) { + pr_err("registering c->dev failed\n"); + goto free_instance_nodev; + } + iface->p->channel[i] = c; + c->is_starving = 0; + c->iface = iface; + c->channel_id = i; + c->keep_mbo = false; + c->enqueue_halt = false; + c->is_poisoned = false; + c->cfg.direction = 0; + c->cfg.data_type = 0; + c->cfg.num_buffers = 0; + c->cfg.buffer_size = 0; + c->cfg.subbuffer_size = 0; + c->cfg.packets_per_xact = 0; + spin_lock_init(&c->fifo_lock); + INIT_LIST_HEAD(&c->fifo); + INIT_LIST_HEAD(&c->trash_fifo); + INIT_LIST_HEAD(&c->halt_fifo); + init_completion(&c->cleanup); + atomic_set(&c->mbo_ref, 0); + mutex_init(&c->start_mutex); + mutex_init(&c->nq_mutex); + list_add_tail(&c->list, &iface->p->channel_list); + } + pr_info("registered new device mdev%d (%s)\n", + id, iface->description); + return 0; + +free_instance_nodev: + kfree(c); + +free_instance: + while (i > 0) { + c = iface->p->channel[--i]; + device_unregister(&c->dev); + kfree(c); + } + kfree(iface->p); + device_unregister(&iface->dev); + ida_simple_remove(&mdev_id, id); + return -ENOMEM; +} +EXPORT_SYMBOL_GPL(most_register_interface); + +/** + * most_deregister_interface - deregisters an interface with core + * @iface: device interface + * + * Before removing an interface instance from the list, all running + * channels are stopped and poisoned. + */ +void most_deregister_interface(struct most_interface *iface) +{ + int i; + struct most_channel *c; + + pr_info("deregistering device %s (%s)\n", dev_name(&iface->dev), iface->description); + for (i = 0; i < iface->num_channels; i++) { + c = iface->p->channel[i]; + if (c->pipe0.comp) + c->pipe0.comp->disconnect_channel(c->iface, + c->channel_id); + if (c->pipe1.comp) + c->pipe1.comp->disconnect_channel(c->iface, + c->channel_id); + c->pipe0.comp = NULL; + c->pipe1.comp = NULL; + list_del(&c->list); + device_unregister(&c->dev); + kfree(c); + } + + ida_simple_remove(&mdev_id, iface->p->dev_id); + kfree(iface->p); + device_unregister(&iface->dev); +} +EXPORT_SYMBOL_GPL(most_deregister_interface); + +/** + * most_stop_enqueue - prevents core from enqueueing MBOs + * @iface: pointer to interface + * @id: channel id + * + * This is called by an HDM that _cannot_ attend to its duties and + * is imminent to get run over by the core. The core is not going to + * enqueue any further packets unless the flagging HDM calls + * most_resume enqueue(). + */ +void most_stop_enqueue(struct most_interface *iface, int id) +{ + struct most_channel *c = iface->p->channel[id]; + + if (!c) + return; + + mutex_lock(&c->nq_mutex); + c->enqueue_halt = true; + mutex_unlock(&c->nq_mutex); +} +EXPORT_SYMBOL_GPL(most_stop_enqueue); + +/** + * most_resume_enqueue - allow core to enqueue MBOs again + * @iface: pointer to interface + * @id: channel id + * + * This clears the enqueue halt flag and enqueues all MBOs currently + * sitting in the wait fifo. + */ +void most_resume_enqueue(struct most_interface *iface, int id) +{ + struct most_channel *c = iface->p->channel[id]; + + if (!c) + return; + + mutex_lock(&c->nq_mutex); + c->enqueue_halt = false; + mutex_unlock(&c->nq_mutex); + + wake_up_interruptible(&c->hdm_fifo_wq); +} +EXPORT_SYMBOL_GPL(most_resume_enqueue); + +static void release_most_sub(struct device *dev) +{ + pr_info("releasing most_subsystem\n"); +} + +static int __init most_init(void) +{ + int err; + + pr_info("init()\n"); + INIT_LIST_HEAD(&mc.comp_list); + ida_init(&mdev_id); + + mc.bus.name = "most", + mc.bus.match = most_match, + mc.drv.name = "most_core", + mc.drv.bus = &mc.bus, + mc.drv.groups = mc_attr_groups; + + err = bus_register(&mc.bus); + if (err) { + pr_info("Cannot register most bus\n"); + return err; + } + err = driver_register(&mc.drv); + if (err) { + pr_info("Cannot register core driver\n"); + goto exit_bus; + } + mc.dev.init_name = "most_bus"; + mc.dev.release = release_most_sub; + if (device_register(&mc.dev)) { + err = -ENOMEM; + goto exit_driver; + } + + return 0; + +exit_driver: + driver_unregister(&mc.drv); +exit_bus: + bus_unregister(&mc.bus); + return err; +} + +static void __exit most_exit(void) +{ + pr_info("exit core module\n"); + device_unregister(&mc.dev); + driver_unregister(&mc.drv); + bus_unregister(&mc.bus); + ida_destroy(&mdev_id); +} + +module_init(most_init); +module_exit(most_exit); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Christian Gromm <christian.gromm@microchip.com>"); +MODULE_DESCRIPTION("Core module of stacked MOST Linux driver"); diff --git a/drivers/staging/most/mostcore/mostcore.h b/drivers/staging/most/core.h index 915e5159d1eb..74a29163b68a 100644 --- a/drivers/staging/most/mostcore/mostcore.h +++ b/drivers/staging/most/core.h @@ -1,31 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * mostcore.h - Interface between MostCore, - * Hardware Dependent Module (HDM) and Application Interface Module (AIM). + * most.h - API for component and adapter drivers * * Copyright (C) 2013-2015, Microchip Technology Germany II GmbH & Co. KG - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This file is licensed under GPLv2. - */ - -/* - * Authors: - * Andrey Shvetsov <andrey.shvetsov@k2l.de> - * Christian Gromm <christian.gromm@microchip.com> - * Sebastian Graf */ #ifndef __MOST_CORE_H__ #define __MOST_CORE_H__ #include <linux/types.h> +#include <linux/device.h> -struct kobject; struct module; +struct interface_private; /** * Interface type @@ -79,22 +66,22 @@ enum mbo_status_flags { * The value is bitwise OR-combination of the values from the * enumeration most_channel_data_type. Zero is allowed value and means * "channel may not be used". - * @num_buffer_packet: Maximum number of buffers supported by this channel + * @num_buffers_packet: Maximum number of buffers supported by this channel * for packet data types (Async,Control,QoS) * @buffer_size_packet: Maximum buffer size supported by this channel * for packet data types (Async,Control,QoS) - * @num_buffer_streaming: Maximum number of buffers supported by this channel + * @num_buffers_streaming: Maximum number of buffers supported by this channel * for streaming data types (Sync,AV Packetized) * @buffer_size_streaming: Maximum buffer size supported by this channel * for streaming data types (Sync,AV Packetized) * @name_suffix: Optional suffix providean by an HDM that is attached to the * regular channel name. * - * Describes the capabilities of a MostCore channel like supported Data Types + * Describes the capabilities of a MOST channel like supported Data Types * and directions. This information is provided by an HDM for the MostCore. * * The Core creates read only sysfs attribute files in - * /sys/devices/virtual/most/mostcore/devices/mdev-#/mdev#-ch#/ with the + * /sys/devices/most/mdev#/<channel>/ with the * following attributes: * -available_directions * -available_datatypes @@ -129,7 +116,7 @@ struct most_channel_capability { * @packets_per_xact: number of MOST frames that are packet inside one USB * packet. This is USB specific * - * Describes the configuration for a MostCore channel. This information is + * Describes the configuration for a MOST channel. This information is * provided from the MostCore to a HDM (like the Medusa PCIe Interface) as a * parameter of the "configure" function call. */ @@ -153,6 +140,7 @@ struct most_channel_config { * * @list: list head for use by the mbo's current owner * @ifp: (in) associated interface instance + * @num_buffers_ptr: amount of pool buffers * @hdm_channel_id: (in) HDM channel instance * @virt_address: (in) kernel virtual address of the buffer * @bus_address: (in) bus address of the buffer @@ -161,15 +149,15 @@ struct most_channel_config { * @status: (out) transfer status * @complete: (in) completion routine * - * The MostCore allocates and initializes the MBO. + * The core allocates and initializes the MBO. * - * The HDM receives MBO for transfer from MostCore with the call to enqueue(). + * The HDM receives MBO for transfer from the core with the call to enqueue(). * The HDM copies the data to- or from the buffer depending on configured * channel direction, set "processed_length" and "status" and completes * the transfer procedure by calling the completion routine. * - * At the end the MostCore deallocates the MBO or recycles it for further - * transfers for the same or different HDM. + * Finally, the MBO is being deallocated or recycled for further + * transfers of the same or a different HDM. * * Directions of usage: * The core driver should never access any MBO fields (even if marked @@ -202,10 +190,12 @@ struct mbo { /** * Interface instance description. * - * Describes one instance of an interface like Medusa PCIe or Vantage USB. + * Describes an interface of a MOST device the core driver is bound to. * This structure is allocated and initialized in the HDM. MostCore may not * modify this structure. * + * @dev: the actual device + * @mod: module * @interface Interface type. \sa most_interface_type. * @description PRELIMINARY. * Unique description of the device instance from point of view of the @@ -238,10 +228,11 @@ struct mbo { * @priv Private field used by mostcore to store context information. */ struct most_interface { + struct device dev; struct module *mod; enum most_interface_type interface; const char *description; - int num_channels; + unsigned int num_channels; struct most_channel_capability *channel_vector; int (*configure)(struct most_interface *iface, int channel_idx, struct most_channel_config *channel_config); @@ -253,27 +244,29 @@ struct most_interface { unsigned char link_stat, unsigned char *mac_addr)); void *priv; + struct interface_private *p; }; +#define to_most_interface(d) container_of(d, struct most_interface, dev) + /** - * struct most_aim - identifies MOST device driver to mostcore - * @name: Driver name + * struct core_component - identifies a loadable component for the mostcore + * @list: list_head + * @name: component name * @probe_channel: function for core to notify driver about channel connection * @disconnect_channel: callback function to disconnect a certain channel * @rx_completion: completion handler for received packets * @tx_completion: completion handler for transmitted packets - * @context: context pointer to be used by mostcore */ -struct most_aim { +struct core_component { + struct list_head list; const char *name; int (*probe_channel)(struct most_interface *iface, int channel_idx, - struct most_channel_config *cfg, - struct kobject *parent, char *name); + struct most_channel_config *cfg, char *name); int (*disconnect_channel)(struct most_interface *iface, int channel_idx); int (*rx_completion)(struct mbo *mbo); int (*tx_completion)(struct most_interface *iface, int channel_idx); - void *context; }; /** @@ -285,7 +278,7 @@ struct most_aim { * Note: HDM has to ensure that any reference held on the kobj is * released before deregistering the interface. */ -struct kobject *most_register_interface(struct most_interface *iface); +int most_register_interface(struct most_interface *iface); /** * Deregisters instance of the interface. @@ -310,16 +303,16 @@ void most_stop_enqueue(struct most_interface *iface, int channel_idx); * in wait fifo. */ void most_resume_enqueue(struct most_interface *iface, int channel_idx); -int most_register_aim(struct most_aim *aim); -int most_deregister_aim(struct most_aim *aim); +int most_register_component(struct core_component *comp); +int most_deregister_component(struct core_component *comp); struct mbo *most_get_mbo(struct most_interface *iface, int channel_idx, - struct most_aim *); + struct core_component *comp); void most_put_mbo(struct mbo *mbo); int channel_has_mbo(struct most_interface *iface, int channel_idx, - struct most_aim *aim); + struct core_component *comp); int most_start_channel(struct most_interface *iface, int channel_idx, - struct most_aim *); + struct core_component *comp); int most_stop_channel(struct most_interface *iface, int channel_idx, - struct most_aim *); + struct core_component *comp); #endif /* MOST_CORE_H_ */ diff --git a/drivers/staging/most/hdm-dim2/Kconfig b/drivers/staging/most/dim2/Kconfig index 663bfebff674..e39c4e525cac 100644 --- a/drivers/staging/most/hdm-dim2/Kconfig +++ b/drivers/staging/most/dim2/Kconfig @@ -2,8 +2,8 @@ # MediaLB configuration # -config HDM_DIM2 - tristate "DIM2 HDM" +config MOST_DIM2 + tristate "DIM2" depends on HAS_IOMEM ---help--- @@ -13,4 +13,4 @@ config HDM_DIM2 maintainer of this driver. To compile this driver as a module, choose M here: the - module will be called hdm_dim2. + module will be called most_dim2. diff --git a/drivers/staging/most/dim2/Makefile b/drivers/staging/most/dim2/Makefile new file mode 100644 index 000000000000..66676f5907ee --- /dev/null +++ b/drivers/staging/most/dim2/Makefile @@ -0,0 +1,4 @@ +obj-$(CONFIG_MOST_DIM2) += most_dim2.o + +most_dim2-objs := dim2.o hal.o sysfs.o +ccflags-y += -Idrivers/staging/ diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.c b/drivers/staging/most/dim2/dim2.c index df7021c522b3..f9bc7dea75b8 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hdm.c +++ b/drivers/staging/most/dim2/dim2.c @@ -1,14 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * dim2_hdm.c - MediaLB DIM2 Hardware Dependent Module + * dim2.c - MediaLB DIM2 Hardware Dependent Module * * Copyright (C) 2015-2016, Microchip Technology Germany II GmbH & Co. KG - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This file is licensed under GPLv2. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -25,11 +19,11 @@ #include <linux/sched.h> #include <linux/kthread.h> -#include <mostcore.h> -#include "dim2_hal.h" -#include "dim2_hdm.h" -#include "dim2_errors.h" -#include "dim2_sysfs.h" +#include "most/core.h" +#include "hal.h" +#include "dim2.h" +#include "errors.h" +#include "sysfs.h" #define DMA_CHANNELS (32 - 1) /* channel 0 is a system channel */ @@ -93,6 +87,7 @@ struct hdm_channel { * @atx_idx: index of async tx channel */ struct dim2_hdm { + struct device dev; struct hdm_channel hch[DMA_CHANNELS]; struct most_channel_capability capabilities[DMA_CHANNELS]; struct most_interface most_iface; @@ -106,8 +101,8 @@ struct dim2_hdm { unsigned char link_state; int atx_idx; struct medialb_bus bus; - void (*on_netinfo)(struct most_interface *, - unsigned char, unsigned char *); + void (*on_netinfo)(struct most_interface *most_iface, + unsigned char link_state, unsigned char *addrs); }; #define iface_to_hdm(iface) container_of(iface, struct dim2_hdm, most_iface) @@ -156,7 +151,7 @@ void dimcb_io_write(u32 __iomem *ptr32, u32 value) */ void dimcb_on_error(u8 error_id, const char *error_message) { - pr_err("dimcb_on_error: error_id - %d, error_message - %s\n", error_id, + pr_err("%s: error_id - %d, error_message - %s\n", __func__, error_id, error_message); } @@ -744,7 +739,6 @@ static int dim2_probe(struct platform_device *pdev) struct dim2_hdm *dev; struct resource *res; int ret, i; - struct kobject *kobj; int irq; dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); @@ -832,17 +826,20 @@ static int dim2_probe(struct platform_device *pdev) dev->most_iface.enqueue = enqueue; dev->most_iface.poison_channel = poison_channel; dev->most_iface.request_netinfo = request_netinfo; + dev->dev.init_name = "dim2_state"; + dev->dev.parent = &dev->most_iface.dev; - kobj = most_register_interface(&dev->most_iface); - if (IS_ERR(kobj)) { - ret = PTR_ERR(kobj); + ret = most_register_interface(&dev->most_iface); + if (ret) { dev_err(&pdev->dev, "failed to register MOST interface\n"); goto err_stop_thread; } - ret = dim2_sysfs_probe(&dev->bus, kobj); - if (ret) + ret = dim2_sysfs_probe(&dev->dev); + if (ret) { + dev_err(&pdev->dev, "failed to create sysfs attribute\n"); goto err_unreg_iface; + } ret = startup_dim(pdev); if (ret) { @@ -853,7 +850,7 @@ static int dim2_probe(struct platform_device *pdev) return 0; err_destroy_bus: - dim2_sysfs_destroy(&dev->bus); + dim2_sysfs_destroy(&dev->dev); err_unreg_iface: most_deregister_interface(&dev->most_iface); err_stop_thread: @@ -881,7 +878,7 @@ static int dim2_remove(struct platform_device *pdev) if (pdata && pdata->destroy) pdata->destroy(pdata); - dim2_sysfs_destroy(&dev->bus); + dim2_sysfs_destroy(&dev->dev); most_deregister_interface(&dev->most_iface); kthread_stop(dev->netinfo_task); diff --git a/drivers/staging/most/hdm-dim2/dim2_hdm.h b/drivers/staging/most/dim2/dim2.h index 4050e7c764ed..6a9fc51a2eb4 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hdm.h +++ b/drivers/staging/most/dim2/dim2.h @@ -1,14 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * dim2_hdm.h - MediaLB DIM2 HDM Header + * dim2.h - MediaLB DIM2 HDM Header * * Copyright (C) 2015, Microchip Technology Germany II GmbH & Co. KG - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This file is licensed under GPLv2. */ #ifndef DIM2_HDM_H diff --git a/drivers/staging/most/hdm-dim2/dim2_errors.h b/drivers/staging/most/dim2/errors.h index 66343ba426c1..3487510fbd2f 100644 --- a/drivers/staging/most/hdm-dim2/dim2_errors.h +++ b/drivers/staging/most/dim2/errors.h @@ -1,15 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * dim2_errors.h - Definitions of errors for DIM2 HAL API + * errors.h - Definitions of errors for DIM2 HAL API * (MediaLB, Device Interface Macro IP, OS62420) * * Copyright (C) 2015, Microchip Technology Germany II GmbH & Co. KG - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This file is licensed under GPLv2. */ #ifndef _MOST_DIM_ERRORS_H diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.c b/drivers/staging/most/dim2/hal.c index 91484643d289..17c04e1c5e62 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.c +++ b/drivers/staging/most/dim2/hal.c @@ -1,22 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * dim2_hal.c - DIM2 HAL implementation + * hal.c - DIM2 HAL implementation * (MediaLB, Device Interface Macro IP, OS62420) * * Copyright (C) 2015-2016, Microchip Technology Germany II GmbH & Co. KG - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This file is licensed under GPLv2. */ /* Author: Andrey Shvetsov <andrey.shvetsov@k2l.de> */ -#include "dim2_hal.h" -#include "dim2_errors.h" -#include "dim2_reg.h" +#include "hal.h" +#include "errors.h" +#include "reg.h" #include <linux/stddef.h> #include <linux/kernel.h> diff --git a/drivers/staging/most/hdm-dim2/dim2_hal.h b/drivers/staging/most/dim2/hal.h index 6df6ea5f7da4..e04a5350f134 100644 --- a/drivers/staging/most/hdm-dim2/dim2_hal.h +++ b/drivers/staging/most/dim2/hal.h @@ -1,22 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * dim2_hal.h - DIM2 HAL interface + * hal.h - DIM2 HAL interface * (MediaLB, Device Interface Macro IP, OS62420) * * Copyright (C) 2015, Microchip Technology Germany II GmbH & Co. KG - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This file is licensed under GPLv2. */ #ifndef _DIM2_HAL_H #define _DIM2_HAL_H #include <linux/types.h> -#include "dim2_reg.h" +#include "reg.h" /* * The values below are specified in the hardware specification. diff --git a/drivers/staging/most/hdm-dim2/dim2_reg.h b/drivers/staging/most/dim2/reg.h index f7d9fbcd29f2..69cbf78239f1 100644 --- a/drivers/staging/most/hdm-dim2/dim2_reg.h +++ b/drivers/staging/most/dim2/reg.h @@ -1,15 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * dim2_reg.h - Definitions for registers of DIM2 + * reg.h - Definitions for registers of DIM2 * (MediaLB, Device Interface Macro IP, OS62420) * * Copyright (C) 2015, Microchip Technology Germany II GmbH & Co. KG - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This file is licensed under GPLv2. */ #ifndef DIM2_OS62420_H diff --git a/drivers/staging/most/dim2/sysfs.c b/drivers/staging/most/dim2/sysfs.c new file mode 100644 index 000000000000..c85b2cdcdca3 --- /dev/null +++ b/drivers/staging/most/dim2/sysfs.c @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * sysfs.c - MediaLB sysfs information + * + * Copyright (C) 2015, Microchip Technology Germany II GmbH & Co. KG + */ + +/* Author: Andrey Shvetsov <andrey.shvetsov@k2l.de> */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/kernel.h> +#include "sysfs.h" +#include <linux/device.h> + +static ssize_t state_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + bool state = dim2_sysfs_get_state_cb(); + + return sprintf(buf, "%s\n", state ? "locked" : ""); +} + +static DEVICE_ATTR_RO(state); + +static struct attribute *dev_attrs[] = { + &dev_attr_state.attr, + NULL, +}; + +static struct attribute_group dev_attr_group = { + .attrs = dev_attrs, +}; + +static const struct attribute_group *dev_attr_groups[] = { + &dev_attr_group, + NULL, +}; + +int dim2_sysfs_probe(struct device *dev) +{ + dev->groups = dev_attr_groups; + return device_register(dev); +} + +void dim2_sysfs_destroy(struct device *dev) +{ + device_unregister(dev); +} diff --git a/drivers/staging/most/dim2/sysfs.h b/drivers/staging/most/dim2/sysfs.h new file mode 100644 index 000000000000..33756a3bffe2 --- /dev/null +++ b/drivers/staging/most/dim2/sysfs.h @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * sysfs.h - MediaLB sysfs information + * + * Copyright (C) 2015, Microchip Technology Germany II GmbH & Co. KG + */ + +/* Author: Andrey Shvetsov <andrey.shvetsov@k2l.de> */ + +#ifndef DIM2_SYSFS_H +#define DIM2_SYSFS_H + +#include <linux/kobject.h> + +struct medialb_bus { + struct kobject kobj_group; +}; + +struct device; + +int dim2_sysfs_probe(struct device *dev); +void dim2_sysfs_destroy(struct device *dev); + +/* + * callback, + * must deliver MediaLB state as true if locked or false if unlocked + */ +bool dim2_sysfs_get_state_cb(void); + +#endif /* DIM2_SYSFS_H */ diff --git a/drivers/staging/most/hdm-dim2/Makefile b/drivers/staging/most/hdm-dim2/Makefile deleted file mode 100644 index 6bbee879a8ea..000000000000 --- a/drivers/staging/most/hdm-dim2/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -obj-$(CONFIG_HDM_DIM2) += hdm_dim2.o - -hdm_dim2-objs := dim2_hdm.o dim2_hal.o dim2_sysfs.o -ccflags-y += -Idrivers/staging/most/mostcore/ -ccflags-y += -Idrivers/staging/most/aim-network/ diff --git a/drivers/staging/most/hdm-dim2/dim2_sysfs.c b/drivers/staging/most/hdm-dim2/dim2_sysfs.c deleted file mode 100644 index d8b22f91d2c3..000000000000 --- a/drivers/staging/most/hdm-dim2/dim2_sysfs.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * dim2_sysfs.c - MediaLB sysfs information - * - * Copyright (C) 2015, Microchip Technology Germany II GmbH & Co. KG - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This file is licensed under GPLv2. - */ - -/* Author: Andrey Shvetsov <andrey.shvetsov@k2l.de> */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/kernel.h> -#include "dim2_sysfs.h" - -struct bus_attr { - struct attribute attr; - ssize_t (*show)(struct medialb_bus *bus, char *buf); - ssize_t (*store)(struct medialb_bus *bus, const char *buf, - size_t count); -}; - -static ssize_t state_show(struct medialb_bus *bus, char *buf) -{ - bool state = dim2_sysfs_get_state_cb(); - - return sprintf(buf, "%s\n", state ? "locked" : ""); -} - -static struct bus_attr state_attr = __ATTR_RO(state); - -static struct attribute *bus_default_attrs[] = { - &state_attr.attr, - NULL, -}; - -static const struct attribute_group bus_attr_group = { - .attrs = bus_default_attrs, -}; - -static void bus_kobj_release(struct kobject *kobj) -{ -} - -static ssize_t bus_kobj_attr_show(struct kobject *kobj, struct attribute *attr, - char *buf) -{ - struct medialb_bus *bus = - container_of(kobj, struct medialb_bus, kobj_group); - struct bus_attr *xattr = container_of(attr, struct bus_attr, attr); - - if (!xattr->show) - return -EIO; - - return xattr->show(bus, buf); -} - -static ssize_t bus_kobj_attr_store(struct kobject *kobj, struct attribute *attr, - const char *buf, size_t count) -{ - struct medialb_bus *bus = - container_of(kobj, struct medialb_bus, kobj_group); - struct bus_attr *xattr = container_of(attr, struct bus_attr, attr); - - if (!xattr->store) - return -EIO; - - return xattr->store(bus, buf, count); -} - -static struct sysfs_ops const bus_kobj_sysfs_ops = { - .show = bus_kobj_attr_show, - .store = bus_kobj_attr_store, -}; - -static struct kobj_type bus_ktype = { - .release = bus_kobj_release, - .sysfs_ops = &bus_kobj_sysfs_ops, -}; - -int dim2_sysfs_probe(struct medialb_bus *bus, struct kobject *parent_kobj) -{ - int err; - - kobject_init(&bus->kobj_group, &bus_ktype); - err = kobject_add(&bus->kobj_group, parent_kobj, "bus"); - if (err) { - pr_err("kobject_add() failed: %d\n", err); - goto err_kobject_add; - } - - err = sysfs_create_group(&bus->kobj_group, &bus_attr_group); - if (err) { - pr_err("sysfs_create_group() failed: %d\n", err); - goto err_create_group; - } - - return 0; - -err_create_group: - kobject_put(&bus->kobj_group); - -err_kobject_add: - return err; -} - -void dim2_sysfs_destroy(struct medialb_bus *bus) -{ - kobject_put(&bus->kobj_group); -} diff --git a/drivers/staging/most/hdm-dim2/dim2_sysfs.h b/drivers/staging/most/hdm-dim2/dim2_sysfs.h deleted file mode 100644 index b71dd027ebc7..000000000000 --- a/drivers/staging/most/hdm-dim2/dim2_sysfs.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * dim2_sysfs.h - MediaLB sysfs information - * - * Copyright (C) 2015, Microchip Technology Germany II GmbH & Co. KG - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This file is licensed under GPLv2. - */ - -/* Author: Andrey Shvetsov <andrey.shvetsov@k2l.de> */ - -#ifndef DIM2_SYSFS_H -#define DIM2_SYSFS_H - -#include <linux/kobject.h> - -struct medialb_bus { - struct kobject kobj_group; -}; - -struct dim2_hdm; - -int dim2_sysfs_probe(struct medialb_bus *bus, struct kobject *parent_kobj); -void dim2_sysfs_destroy(struct medialb_bus *bus); - -/* - * callback, - * must deliver MediaLB state as true if locked or false if unlocked - */ -bool dim2_sysfs_get_state_cb(void); - -#endif /* DIM2_SYSFS_H */ diff --git a/drivers/staging/most/hdm-i2c/Makefile b/drivers/staging/most/hdm-i2c/Makefile deleted file mode 100644 index 03a4a59b1f9f..000000000000 --- a/drivers/staging/most/hdm-i2c/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -obj-$(CONFIG_HDM_I2C) += hdm_i2c.o - -ccflags-y += -Idrivers/staging/most/mostcore/ diff --git a/drivers/staging/most/hdm-usb/Makefile b/drivers/staging/most/hdm-usb/Makefile deleted file mode 100644 index 6bbacb41e94b..000000000000 --- a/drivers/staging/most/hdm-usb/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -obj-$(CONFIG_HDM_USB) += hdm_usb.o - -ccflags-y += -Idrivers/staging/most/mostcore/ -ccflags-y += -Idrivers/staging/most/aim-network/ diff --git a/drivers/staging/most/hdm-i2c/Kconfig b/drivers/staging/most/i2c/Kconfig index 6fd7983668ad..79d0ff27f56d 100644 --- a/drivers/staging/most/hdm-i2c/Kconfig +++ b/drivers/staging/most/i2c/Kconfig @@ -2,11 +2,11 @@ # MOST I2C configuration # -config HDM_I2C - tristate "I2C HDM" +config MOST_I2C + tristate "I2C" depends on I2C ---help--- Say Y here if you want to connect via I2C to network tranceiver. To compile this driver as a module, choose M here: the - module will be called hdm_i2c. + module will be called most_i2c. diff --git a/drivers/staging/most/i2c/Makefile b/drivers/staging/most/i2c/Makefile new file mode 100644 index 000000000000..a7d094c1e1c2 --- /dev/null +++ b/drivers/staging/most/i2c/Makefile @@ -0,0 +1,4 @@ +obj-$(CONFIG_MOST_I2C) += most_i2c.o + +most_i2c-objs := i2c.o +ccflags-y += -Idrivers/staging/ diff --git a/drivers/staging/most/hdm-i2c/hdm_i2c.c b/drivers/staging/most/i2c/i2c.c index 2b4de404e46a..141239fc9f51 100644 --- a/drivers/staging/most/hdm-i2c/hdm_i2c.c +++ b/drivers/staging/most/i2c/i2c.c @@ -1,14 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * hdm_i2c.c - Hardware Dependent Module for I2C Interface + * i2c.c - Hardware Dependent Module for I2C Interface * * Copyright (C) 2013-2015, Microchip Technology Germany II GmbH & Co. KG - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This file is licensed under GPLv2. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -21,7 +15,7 @@ #include <linux/interrupt.h> #include <linux/err.h> -#include <mostcore.h> +#include "most/core.h" enum { CH_RX, CH_TX, NUM_CHANNELS }; @@ -309,7 +303,6 @@ static int i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct hdm_i2c *dev; int ret, i; - struct kobject *kobj; dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) @@ -347,11 +340,11 @@ static int i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) dev->client = client; i2c_set_clientdata(client, dev); - kobj = most_register_interface(&dev->most_iface); - if (IS_ERR(kobj)) { + ret = most_register_interface(&dev->most_iface); + if (ret) { pr_err("Failed to register i2c as a MOST interface\n"); kfree(dev); - return PTR_ERR(kobj); + return ret; } dev->polling_mode = polling_req || client->irq <= 0; diff --git a/drivers/staging/most/mostcore/Kconfig b/drivers/staging/most/mostcore/Kconfig deleted file mode 100644 index 47172546d728..000000000000 --- a/drivers/staging/most/mostcore/Kconfig +++ /dev/null @@ -1,14 +0,0 @@ -# -# MOSTCore configuration -# - -config MOSTCORE - tristate "MOST Core" - depends on HAS_DMA - - ---help--- - Say Y here if you want to enable MOST support. - This device driver needs at least an additional AIM and HDM to work. - - To compile this driver as a module, choose M here: the - module will be called mostcore. diff --git a/drivers/staging/most/mostcore/Makefile b/drivers/staging/most/mostcore/Makefile deleted file mode 100644 index a078f01cf7c2..000000000000 --- a/drivers/staging/most/mostcore/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -obj-$(CONFIG_MOSTCORE) += mostcore.o - -mostcore-objs := core.o diff --git a/drivers/staging/most/mostcore/core.c b/drivers/staging/most/mostcore/core.c deleted file mode 100644 index 069269db394c..000000000000 --- a/drivers/staging/most/mostcore/core.c +++ /dev/null @@ -1,1949 +0,0 @@ -/* - * core.c - Implementation of core module of MOST Linux driver stack - * - * Copyright (C) 2013-2015 Microchip Technology Germany II GmbH & Co. KG - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This file is licensed under GPLv2. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include <linux/module.h> -#include <linux/fs.h> -#include <linux/slab.h> -#include <linux/init.h> -#include <linux/device.h> -#include <linux/list.h> -#include <linux/poll.h> -#include <linux/wait.h> -#include <linux/kobject.h> -#include <linux/mutex.h> -#include <linux/completion.h> -#include <linux/sysfs.h> -#include <linux/kthread.h> -#include <linux/dma-mapping.h> -#include <linux/idr.h> -#include "mostcore.h" - -#define MAX_CHANNELS 64 -#define STRING_SIZE 80 - -static struct class *most_class; -static struct device *core_dev; -static struct ida mdev_id; -static int dummy_num_buffers; - -struct most_c_aim_obj { - struct most_aim *ptr; - int refs; - int num_buffers; -}; - -struct most_c_obj { - struct kobject kobj; - struct completion cleanup; - atomic_t mbo_ref; - atomic_t mbo_nq_level; - u16 channel_id; - bool is_poisoned; - struct mutex start_mutex; - struct mutex nq_mutex; /* nq thread synchronization */ - int is_starving; - struct most_interface *iface; - struct most_inst_obj *inst; - struct most_channel_config cfg; - bool keep_mbo; - bool enqueue_halt; - struct list_head fifo; - spinlock_t fifo_lock; - struct list_head halt_fifo; - struct list_head list; - struct most_c_aim_obj aim0; - struct most_c_aim_obj aim1; - struct list_head trash_fifo; - struct task_struct *hdm_enqueue_task; - wait_queue_head_t hdm_fifo_wq; -}; - -#define to_c_obj(d) container_of(d, struct most_c_obj, kobj) - -struct most_inst_obj { - int dev_id; - struct most_interface *iface; - struct list_head channel_list; - struct most_c_obj *channel[MAX_CHANNELS]; - struct kobject kobj; - struct list_head list; -}; - -static const struct { - int most_ch_data_type; - const char *name; -} ch_data_type[] = { - { MOST_CH_CONTROL, "control\n" }, - { MOST_CH_ASYNC, "async\n" }, - { MOST_CH_SYNC, "sync\n" }, - { MOST_CH_ISOC, "isoc\n"}, - { MOST_CH_ISOC, "isoc_avp\n"}, -}; - -#define to_inst_obj(d) container_of(d, struct most_inst_obj, kobj) - -/** - * list_pop_mbo - retrieves the first MBO of the list and removes it - * @ptr: the list head to grab the MBO from. - */ -#define list_pop_mbo(ptr) \ -({ \ - struct mbo *_mbo = list_first_entry(ptr, struct mbo, list); \ - list_del(&_mbo->list); \ - _mbo; \ -}) - -/* ___ ___ - * ___C H A N N E L___ - */ - -/** - * struct most_c_attr - to access the attributes of a channel object - * @attr: attributes of a channel - * @show: pointer to the show function - * @store: pointer to the store function - */ -struct most_c_attr { - struct attribute attr; - ssize_t (*show)(struct most_c_obj *d, - struct most_c_attr *attr, - char *buf); - ssize_t (*store)(struct most_c_obj *d, - struct most_c_attr *attr, - const char *buf, - size_t count); -}; - -#define to_channel_attr(a) container_of(a, struct most_c_attr, attr) - -/** - * channel_attr_show - show function of channel object - * @kobj: pointer to its kobject - * @attr: pointer to its attributes - * @buf: buffer - */ -static ssize_t channel_attr_show(struct kobject *kobj, struct attribute *attr, - char *buf) -{ - struct most_c_attr *channel_attr = to_channel_attr(attr); - struct most_c_obj *c_obj = to_c_obj(kobj); - - if (!channel_attr->show) - return -EIO; - - return channel_attr->show(c_obj, channel_attr, buf); -} - -/** - * channel_attr_store - store function of channel object - * @kobj: pointer to its kobject - * @attr: pointer to its attributes - * @buf: buffer - * @len: length of buffer - */ -static ssize_t channel_attr_store(struct kobject *kobj, - struct attribute *attr, - const char *buf, - size_t len) -{ - struct most_c_attr *channel_attr = to_channel_attr(attr); - struct most_c_obj *c_obj = to_c_obj(kobj); - - if (!channel_attr->store) - return -EIO; - return channel_attr->store(c_obj, channel_attr, buf, len); -} - -static const struct sysfs_ops most_channel_sysfs_ops = { - .show = channel_attr_show, - .store = channel_attr_store, -}; - -/** - * most_free_mbo_coherent - free an MBO and its coherent buffer - * @mbo: buffer to be released - * - */ -static void most_free_mbo_coherent(struct mbo *mbo) -{ - struct most_c_obj *c = mbo->context; - u16 const coherent_buf_size = c->cfg.buffer_size + c->cfg.extra_len; - - dma_free_coherent(NULL, coherent_buf_size, mbo->virt_address, - mbo->bus_address); - kfree(mbo); - if (atomic_sub_and_test(1, &c->mbo_ref)) - complete(&c->cleanup); -} - -/** - * flush_channel_fifos - clear the channel fifos - * @c: pointer to channel object - */ -static void flush_channel_fifos(struct most_c_obj *c) -{ - unsigned long flags, hf_flags; - struct mbo *mbo, *tmp; - - if (list_empty(&c->fifo) && list_empty(&c->halt_fifo)) - return; - - spin_lock_irqsave(&c->fifo_lock, flags); - list_for_each_entry_safe(mbo, tmp, &c->fifo, list) { - list_del(&mbo->list); - spin_unlock_irqrestore(&c->fifo_lock, flags); - most_free_mbo_coherent(mbo); - spin_lock_irqsave(&c->fifo_lock, flags); - } - spin_unlock_irqrestore(&c->fifo_lock, flags); - - spin_lock_irqsave(&c->fifo_lock, hf_flags); - list_for_each_entry_safe(mbo, tmp, &c->halt_fifo, list) { - list_del(&mbo->list); - spin_unlock_irqrestore(&c->fifo_lock, hf_flags); - most_free_mbo_coherent(mbo); - spin_lock_irqsave(&c->fifo_lock, hf_flags); - } - spin_unlock_irqrestore(&c->fifo_lock, hf_flags); - - if (unlikely((!list_empty(&c->fifo) || !list_empty(&c->halt_fifo)))) - pr_info("WARN: fifo | trash fifo not empty\n"); -} - -/** - * flush_trash_fifo - clear the trash fifo - * @c: pointer to channel object - */ -static int flush_trash_fifo(struct most_c_obj *c) -{ - struct mbo *mbo, *tmp; - unsigned long flags; - - spin_lock_irqsave(&c->fifo_lock, flags); - list_for_each_entry_safe(mbo, tmp, &c->trash_fifo, list) { - list_del(&mbo->list); - spin_unlock_irqrestore(&c->fifo_lock, flags); - most_free_mbo_coherent(mbo); - spin_lock_irqsave(&c->fifo_lock, flags); - } - spin_unlock_irqrestore(&c->fifo_lock, flags); - return 0; -} - -/** - * most_channel_release - release function of channel object - * @kobj: pointer to channel's kobject - */ -static void most_channel_release(struct kobject *kobj) -{ - struct most_c_obj *c = to_c_obj(kobj); - - kfree(c); -} - -static ssize_t available_directions_show(struct most_c_obj *c, - struct most_c_attr *attr, - char *buf) -{ - unsigned int i = c->channel_id; - - strcpy(buf, ""); - if (c->iface->channel_vector[i].direction & MOST_CH_RX) - strcat(buf, "rx "); - if (c->iface->channel_vector[i].direction & MOST_CH_TX) - strcat(buf, "tx "); - strcat(buf, "\n"); - return strlen(buf); -} - -static ssize_t available_datatypes_show(struct most_c_obj *c, - struct most_c_attr *attr, - char *buf) -{ - unsigned int i = c->channel_id; - - strcpy(buf, ""); - if (c->iface->channel_vector[i].data_type & MOST_CH_CONTROL) - strcat(buf, "control "); - if (c->iface->channel_vector[i].data_type & MOST_CH_ASYNC) - strcat(buf, "async "); - if (c->iface->channel_vector[i].data_type & MOST_CH_SYNC) - strcat(buf, "sync "); - if (c->iface->channel_vector[i].data_type & MOST_CH_ISOC) - strcat(buf, "isoc "); - strcat(buf, "\n"); - return strlen(buf); -} - -static ssize_t number_of_packet_buffers_show(struct most_c_obj *c, - struct most_c_attr *attr, - char *buf) -{ - unsigned int i = c->channel_id; - - return snprintf(buf, PAGE_SIZE, "%d\n", - c->iface->channel_vector[i].num_buffers_packet); -} - -static ssize_t number_of_stream_buffers_show(struct most_c_obj *c, - struct most_c_attr *attr, - char *buf) -{ - unsigned int i = c->channel_id; - - return snprintf(buf, PAGE_SIZE, "%d\n", - c->iface->channel_vector[i].num_buffers_streaming); -} - -static ssize_t size_of_packet_buffer_show(struct most_c_obj *c, - struct most_c_attr *attr, - char *buf) -{ - unsigned int i = c->channel_id; - - return snprintf(buf, PAGE_SIZE, "%d\n", - c->iface->channel_vector[i].buffer_size_packet); -} - -static ssize_t size_of_stream_buffer_show(struct most_c_obj *c, - struct most_c_attr *attr, - char *buf) -{ - unsigned int i = c->channel_id; - - return snprintf(buf, PAGE_SIZE, "%d\n", - c->iface->channel_vector[i].buffer_size_streaming); -} - -static ssize_t channel_starving_show(struct most_c_obj *c, - struct most_c_attr *attr, - char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", c->is_starving); -} - -static ssize_t set_number_of_buffers_show(struct most_c_obj *c, - struct most_c_attr *attr, - char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", c->cfg.num_buffers); -} - -static ssize_t set_number_of_buffers_store(struct most_c_obj *c, - struct most_c_attr *attr, - const char *buf, - size_t count) -{ - int ret = kstrtou16(buf, 0, &c->cfg.num_buffers); - - if (ret) - return ret; - return count; -} - -static ssize_t set_buffer_size_show(struct most_c_obj *c, - struct most_c_attr *attr, - char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", c->cfg.buffer_size); -} - -static ssize_t set_buffer_size_store(struct most_c_obj *c, - struct most_c_attr *attr, - const char *buf, - size_t count) -{ - int ret = kstrtou16(buf, 0, &c->cfg.buffer_size); - - if (ret) - return ret; - return count; -} - -static ssize_t set_direction_show(struct most_c_obj *c, - struct most_c_attr *attr, - char *buf) -{ - if (c->cfg.direction & MOST_CH_TX) - return snprintf(buf, PAGE_SIZE, "tx\n"); - else if (c->cfg.direction & MOST_CH_RX) - return snprintf(buf, PAGE_SIZE, "rx\n"); - return snprintf(buf, PAGE_SIZE, "unconfigured\n"); -} - -static ssize_t set_direction_store(struct most_c_obj *c, - struct most_c_attr *attr, - const char *buf, - size_t count) -{ - if (!strcmp(buf, "dir_rx\n")) { - c->cfg.direction = MOST_CH_RX; - } else if (!strcmp(buf, "rx\n")) { - c->cfg.direction = MOST_CH_RX; - } else if (!strcmp(buf, "dir_tx\n")) { - c->cfg.direction = MOST_CH_TX; - } else if (!strcmp(buf, "tx\n")) { - c->cfg.direction = MOST_CH_TX; - } else { - pr_info("WARN: invalid attribute settings\n"); - return -EINVAL; - } - return count; -} - -static ssize_t set_datatype_show(struct most_c_obj *c, - struct most_c_attr *attr, - char *buf) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(ch_data_type); i++) { - if (c->cfg.data_type & ch_data_type[i].most_ch_data_type) - return snprintf(buf, PAGE_SIZE, ch_data_type[i].name); - } - return snprintf(buf, PAGE_SIZE, "unconfigured\n"); -} - -static ssize_t set_datatype_store(struct most_c_obj *c, - struct most_c_attr *attr, - const char *buf, - size_t count) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(ch_data_type); i++) { - if (!strcmp(buf, ch_data_type[i].name)) { - c->cfg.data_type = ch_data_type[i].most_ch_data_type; - break; - } - } - - if (i == ARRAY_SIZE(ch_data_type)) { - pr_info("WARN: invalid attribute settings\n"); - return -EINVAL; - } - return count; -} - -static ssize_t set_subbuffer_size_show(struct most_c_obj *c, - struct most_c_attr *attr, - char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", c->cfg.subbuffer_size); -} - -static ssize_t set_subbuffer_size_store(struct most_c_obj *c, - struct most_c_attr *attr, - const char *buf, - size_t count) -{ - int ret = kstrtou16(buf, 0, &c->cfg.subbuffer_size); - - if (ret) - return ret; - return count; -} - -static ssize_t set_packets_per_xact_show(struct most_c_obj *c, - struct most_c_attr *attr, - char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", c->cfg.packets_per_xact); -} - -static ssize_t set_packets_per_xact_store(struct most_c_obj *c, - struct most_c_attr *attr, - const char *buf, - size_t count) -{ - int ret = kstrtou16(buf, 0, &c->cfg.packets_per_xact); - - if (ret) - return ret; - return count; -} - -static struct most_c_attr most_c_attrs[] = { - __ATTR_RO(available_directions), - __ATTR_RO(available_datatypes), - __ATTR_RO(number_of_packet_buffers), - __ATTR_RO(number_of_stream_buffers), - __ATTR_RO(size_of_stream_buffer), - __ATTR_RO(size_of_packet_buffer), - __ATTR_RO(channel_starving), - __ATTR_RW(set_buffer_size), - __ATTR_RW(set_number_of_buffers), - __ATTR_RW(set_direction), - __ATTR_RW(set_datatype), - __ATTR_RW(set_subbuffer_size), - __ATTR_RW(set_packets_per_xact), -}; - -/** - * most_channel_def_attrs - array of default attributes of channel object - */ -static struct attribute *most_channel_def_attrs[] = { - &most_c_attrs[0].attr, - &most_c_attrs[1].attr, - &most_c_attrs[2].attr, - &most_c_attrs[3].attr, - &most_c_attrs[4].attr, - &most_c_attrs[5].attr, - &most_c_attrs[6].attr, - &most_c_attrs[7].attr, - &most_c_attrs[8].attr, - &most_c_attrs[9].attr, - &most_c_attrs[10].attr, - &most_c_attrs[11].attr, - &most_c_attrs[12].attr, - NULL, -}; - -static struct kobj_type most_channel_ktype = { - .sysfs_ops = &most_channel_sysfs_ops, - .release = most_channel_release, - .default_attrs = most_channel_def_attrs, -}; - -static struct kset *most_channel_kset; - -/** - * create_most_c_obj - allocates a channel object - * @name: name of the channel object - * @parent: parent kobject - * - * This create a channel object and registers it with sysfs. - * Returns a pointer to the object or NULL when something went wrong. - */ -static struct most_c_obj * -create_most_c_obj(const char *name, struct kobject *parent) -{ - struct most_c_obj *c; - int retval; - - c = kzalloc(sizeof(*c), GFP_KERNEL); - if (!c) - return NULL; - c->kobj.kset = most_channel_kset; - retval = kobject_init_and_add(&c->kobj, &most_channel_ktype, parent, - "%s", name); - if (retval) { - kobject_put(&c->kobj); - return NULL; - } - kobject_uevent(&c->kobj, KOBJ_ADD); - return c; -} - -/* ___ ___ - * ___I N S T A N C E___ - */ - -static struct list_head instance_list; - -/** - * struct most_inst_attribute - to access the attributes of instance object - * @attr: attributes of an instance - * @show: pointer to the show function - * @store: pointer to the store function - */ -struct most_inst_attribute { - struct attribute attr; - ssize_t (*show)(struct most_inst_obj *d, - struct most_inst_attribute *attr, - char *buf); - ssize_t (*store)(struct most_inst_obj *d, - struct most_inst_attribute *attr, - const char *buf, - size_t count); -}; - -#define to_instance_attr(a) \ - container_of(a, struct most_inst_attribute, attr) - -/** - * instance_attr_show - show function for an instance object - * @kobj: pointer to kobject - * @attr: pointer to attribute struct - * @buf: buffer - */ -static ssize_t instance_attr_show(struct kobject *kobj, - struct attribute *attr, - char *buf) -{ - struct most_inst_attribute *instance_attr; - struct most_inst_obj *instance_obj; - - instance_attr = to_instance_attr(attr); - instance_obj = to_inst_obj(kobj); - - if (!instance_attr->show) - return -EIO; - - return instance_attr->show(instance_obj, instance_attr, buf); -} - -/** - * instance_attr_store - store function for an instance object - * @kobj: pointer to kobject - * @attr: pointer to attribute struct - * @buf: buffer - * @len: length of buffer - */ -static ssize_t instance_attr_store(struct kobject *kobj, - struct attribute *attr, - const char *buf, - size_t len) -{ - struct most_inst_attribute *instance_attr; - struct most_inst_obj *instance_obj; - - instance_attr = to_instance_attr(attr); - instance_obj = to_inst_obj(kobj); - - if (!instance_attr->store) - return -EIO; - - return instance_attr->store(instance_obj, instance_attr, buf, len); -} - -static const struct sysfs_ops most_inst_sysfs_ops = { - .show = instance_attr_show, - .store = instance_attr_store, -}; - -/** - * most_inst_release - release function for instance object - * @kobj: pointer to instance's kobject - * - * This frees the allocated memory for the instance object - */ -static void most_inst_release(struct kobject *kobj) -{ - struct most_inst_obj *inst = to_inst_obj(kobj); - - kfree(inst); -} - -static ssize_t description_show(struct most_inst_obj *instance_obj, - struct most_inst_attribute *attr, - char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%s\n", - instance_obj->iface->description); -} - -static ssize_t interface_show(struct most_inst_obj *instance_obj, - struct most_inst_attribute *attr, - char *buf) -{ - switch (instance_obj->iface->interface) { - case ITYPE_LOOPBACK: - return snprintf(buf, PAGE_SIZE, "loopback\n"); - case ITYPE_I2C: - return snprintf(buf, PAGE_SIZE, "i2c\n"); - case ITYPE_I2S: - return snprintf(buf, PAGE_SIZE, "i2s\n"); - case ITYPE_TSI: - return snprintf(buf, PAGE_SIZE, "tsi\n"); - case ITYPE_HBI: - return snprintf(buf, PAGE_SIZE, "hbi\n"); - case ITYPE_MEDIALB_DIM: - return snprintf(buf, PAGE_SIZE, "mlb_dim\n"); - case ITYPE_MEDIALB_DIM2: - return snprintf(buf, PAGE_SIZE, "mlb_dim2\n"); - case ITYPE_USB: - return snprintf(buf, PAGE_SIZE, "usb\n"); - case ITYPE_PCIE: - return snprintf(buf, PAGE_SIZE, "pcie\n"); - } - return snprintf(buf, PAGE_SIZE, "unknown\n"); -} - -static struct most_inst_attribute most_inst_attr_description = - __ATTR_RO(description); - -static struct most_inst_attribute most_inst_attr_interface = - __ATTR_RO(interface); - -static struct attribute *most_inst_def_attrs[] = { - &most_inst_attr_description.attr, - &most_inst_attr_interface.attr, - NULL, -}; - -static struct kobj_type most_inst_ktype = { - .sysfs_ops = &most_inst_sysfs_ops, - .release = most_inst_release, - .default_attrs = most_inst_def_attrs, -}; - -static struct kset *most_inst_kset; - -/** - * create_most_inst_obj - creates an instance object - * @name: name of the object to be created - * - * This allocates memory for an instance structure, assigns the proper kset - * and registers it with sysfs. - * - * Returns a pointer to the instance object or NULL when something went wrong. - */ -static struct most_inst_obj *create_most_inst_obj(const char *name) -{ - struct most_inst_obj *inst; - int retval; - - inst = kzalloc(sizeof(*inst), GFP_KERNEL); - if (!inst) - return NULL; - inst->kobj.kset = most_inst_kset; - retval = kobject_init_and_add(&inst->kobj, &most_inst_ktype, NULL, - "%s", name); - if (retval) { - kobject_put(&inst->kobj); - return NULL; - } - kobject_uevent(&inst->kobj, KOBJ_ADD); - return inst; -} - -/** - * destroy_most_inst_obj - MOST instance release function - * @inst: pointer to the instance object - * - * This decrements the reference counter of the instance object. - * If the reference count turns zero, its release function is called - */ -static void destroy_most_inst_obj(struct most_inst_obj *inst) -{ - struct most_c_obj *c, *tmp; - - list_for_each_entry_safe(c, tmp, &inst->channel_list, list) { - flush_trash_fifo(c); - flush_channel_fifos(c); - kobject_put(&c->kobj); - } - kobject_put(&inst->kobj); -} - -/* ___ ___ - * ___A I M___ - */ -struct most_aim_obj { - struct kobject kobj; - struct list_head list; - struct most_aim *driver; -}; - -#define to_aim_obj(d) container_of(d, struct most_aim_obj, kobj) - -static struct list_head aim_list; - -/** - * struct most_aim_attribute - to access the attributes of AIM object - * @attr: attributes of an AIM - * @show: pointer to the show function - * @store: pointer to the store function - */ -struct most_aim_attribute { - struct attribute attr; - ssize_t (*show)(struct most_aim_obj *d, - struct most_aim_attribute *attr, - char *buf); - ssize_t (*store)(struct most_aim_obj *d, - struct most_aim_attribute *attr, - const char *buf, - size_t count); -}; - -#define to_aim_attr(a) container_of(a, struct most_aim_attribute, attr) - -/** - * aim_attr_show - show function of an AIM object - * @kobj: pointer to kobject - * @attr: pointer to attribute struct - * @buf: buffer - */ -static ssize_t aim_attr_show(struct kobject *kobj, - struct attribute *attr, - char *buf) -{ - struct most_aim_attribute *aim_attr; - struct most_aim_obj *aim_obj; - - aim_attr = to_aim_attr(attr); - aim_obj = to_aim_obj(kobj); - - if (!aim_attr->show) - return -EIO; - - return aim_attr->show(aim_obj, aim_attr, buf); -} - -/** - * aim_attr_store - store function of an AIM object - * @kobj: pointer to kobject - * @attr: pointer to attribute struct - * @buf: buffer - * @len: length of buffer - */ -static ssize_t aim_attr_store(struct kobject *kobj, - struct attribute *attr, - const char *buf, - size_t len) -{ - struct most_aim_attribute *aim_attr; - struct most_aim_obj *aim_obj; - - aim_attr = to_aim_attr(attr); - aim_obj = to_aim_obj(kobj); - - if (!aim_attr->store) - return -EIO; - return aim_attr->store(aim_obj, aim_attr, buf, len); -} - -static const struct sysfs_ops most_aim_sysfs_ops = { - .show = aim_attr_show, - .store = aim_attr_store, -}; - -/** - * most_aim_release - AIM release function - * @kobj: pointer to AIM's kobject - */ -static void most_aim_release(struct kobject *kobj) -{ - struct most_aim_obj *aim_obj = to_aim_obj(kobj); - - kfree(aim_obj); -} - -static ssize_t links_show(struct most_aim_obj *aim_obj, - struct most_aim_attribute *attr, - char *buf) -{ - struct most_c_obj *c; - struct most_inst_obj *i; - int offs = 0; - - list_for_each_entry(i, &instance_list, list) { - list_for_each_entry(c, &i->channel_list, list) { - if (c->aim0.ptr == aim_obj->driver || - c->aim1.ptr == aim_obj->driver) { - offs += snprintf(buf + offs, PAGE_SIZE - offs, - "%s:%s\n", - kobject_name(&i->kobj), - kobject_name(&c->kobj)); - } - } - } - - return offs; -} - -/** - * split_string - parses and changes string in the buffer buf and - * splits it into two mandatory and one optional substrings. - * - * @buf: complete string from attribute 'add_channel' - * @a: address of pointer to 1st substring (=instance name) - * @b: address of pointer to 2nd substring (=channel name) - * @c: optional address of pointer to 3rd substring (=user defined name) - * - * Examples: - * - * Input: "mdev0:ch6:my_channel\n" or - * "mdev0:ch6:my_channel" - * - * Output: *a -> "mdev0", *b -> "ch6", *c -> "my_channel" - * - * Input: "mdev1:ep81\n" - * Output: *a -> "mdev1", *b -> "ep81", *c -> "" - * - * Input: "mdev1:ep81" - * Output: *a -> "mdev1", *b -> "ep81", *c == NULL - */ -static int split_string(char *buf, char **a, char **b, char **c) -{ - *a = strsep(&buf, ":"); - if (!*a) - return -EIO; - - *b = strsep(&buf, ":\n"); - if (!*b) - return -EIO; - - if (c) - *c = strsep(&buf, ":\n"); - - return 0; -} - -/** - * get_channel_by_name - get pointer to channel object - * @mdev: name of the device instance - * @mdev_ch: name of the respective channel - * - * This retrieves the pointer to a channel object. - */ -static struct -most_c_obj *get_channel_by_name(char *mdev, char *mdev_ch) -{ - struct most_c_obj *c, *tmp; - struct most_inst_obj *i, *i_tmp; - int found = 0; - - list_for_each_entry_safe(i, i_tmp, &instance_list, list) { - if (!strcmp(kobject_name(&i->kobj), mdev)) { - found++; - break; - } - } - if (unlikely(!found)) - return ERR_PTR(-EIO); - - list_for_each_entry_safe(c, tmp, &i->channel_list, list) { - if (!strcmp(kobject_name(&c->kobj), mdev_ch)) { - found++; - break; - } - } - if (unlikely(found < 2)) - return ERR_PTR(-EIO); - return c; -} - -/** - * add_link_store - store() function for add_link attribute - * @aim_obj: pointer to AIM object - * @attr: its attributes - * @buf: buffer - * @len: buffer length - * - * This parses the string given by buf and splits it into - * three substrings. Note: third substring is optional. In case a cdev - * AIM is loaded the optional 3rd substring will make up the name of - * device node in the /dev directory. If omitted, the device node will - * inherit the channel's name within sysfs. - * - * Searches for a pair of device and channel and probes the AIM - * - * Example: - * (1) echo "mdev0:ch6:my_rxchannel" >add_link - * (2) echo "mdev1:ep81" >add_link - * - * (1) would create the device node /dev/my_rxchannel - * (2) would create the device node /dev/mdev1-ep81 - */ -static ssize_t add_link_store(struct most_aim_obj *aim_obj, - struct most_aim_attribute *attr, - const char *buf, - size_t len) -{ - struct most_c_obj *c; - struct most_aim **aim_ptr; - char buffer[STRING_SIZE]; - char *mdev; - char *mdev_ch; - char *mdev_devnod; - char devnod_buf[STRING_SIZE]; - int ret; - size_t max_len = min_t(size_t, len + 1, STRING_SIZE); - - strlcpy(buffer, buf, max_len); - - ret = split_string(buffer, &mdev, &mdev_ch, &mdev_devnod); - if (ret) - return ret; - - if (!mdev_devnod || *mdev_devnod == 0) { - snprintf(devnod_buf, sizeof(devnod_buf), "%s-%s", mdev, - mdev_ch); - mdev_devnod = devnod_buf; - } - - c = get_channel_by_name(mdev, mdev_ch); - if (IS_ERR(c)) - return -ENODEV; - - if (!c->aim0.ptr) - aim_ptr = &c->aim0.ptr; - else if (!c->aim1.ptr) - aim_ptr = &c->aim1.ptr; - else - return -ENOSPC; - - *aim_ptr = aim_obj->driver; - ret = aim_obj->driver->probe_channel(c->iface, c->channel_id, - &c->cfg, &c->kobj, mdev_devnod); - if (ret) { - *aim_ptr = NULL; - return ret; - } - - return len; -} - -/** - * remove_link_store - store function for remove_link attribute - * @aim_obj: pointer to AIM object - * @attr: its attributes - * @buf: buffer - * @len: buffer length - * - * Example: - * echo "mdev0:ep81" >remove_link - */ -static ssize_t remove_link_store(struct most_aim_obj *aim_obj, - struct most_aim_attribute *attr, - const char *buf, - size_t len) -{ - struct most_c_obj *c; - char buffer[STRING_SIZE]; - char *mdev; - char *mdev_ch; - int ret; - size_t max_len = min_t(size_t, len + 1, STRING_SIZE); - - strlcpy(buffer, buf, max_len); - ret = split_string(buffer, &mdev, &mdev_ch, NULL); - if (ret) - return ret; - - c = get_channel_by_name(mdev, mdev_ch); - if (IS_ERR(c)) - return -ENODEV; - - if (aim_obj->driver->disconnect_channel(c->iface, c->channel_id)) - return -EIO; - if (c->aim0.ptr == aim_obj->driver) - c->aim0.ptr = NULL; - if (c->aim1.ptr == aim_obj->driver) - c->aim1.ptr = NULL; - return len; -} - -static struct most_aim_attribute most_aim_attrs[] = { - __ATTR_RO(links), - __ATTR_WO(add_link), - __ATTR_WO(remove_link), -}; - -static struct attribute *most_aim_def_attrs[] = { - &most_aim_attrs[0].attr, - &most_aim_attrs[1].attr, - &most_aim_attrs[2].attr, - NULL, -}; - -static struct kobj_type most_aim_ktype = { - .sysfs_ops = &most_aim_sysfs_ops, - .release = most_aim_release, - .default_attrs = most_aim_def_attrs, -}; - -static struct kset *most_aim_kset; - -/** - * create_most_aim_obj - creates an AIM object - * @name: name of the AIM - * - * This creates an AIM object assigns the proper kset and registers - * it with sysfs. - * Returns a pointer to the object or NULL if something went wrong. - */ -static struct most_aim_obj *create_most_aim_obj(const char *name) -{ - struct most_aim_obj *most_aim; - int retval; - - most_aim = kzalloc(sizeof(*most_aim), GFP_KERNEL); - if (!most_aim) - return NULL; - most_aim->kobj.kset = most_aim_kset; - retval = kobject_init_and_add(&most_aim->kobj, &most_aim_ktype, - NULL, "%s", name); - if (retval) { - kobject_put(&most_aim->kobj); - return NULL; - } - kobject_uevent(&most_aim->kobj, KOBJ_ADD); - return most_aim; -} - -/** - * destroy_most_aim_obj - AIM release function - * @p: pointer to AIM object - * - * This decrements the reference counter of the AIM object. If the - * reference count turns zero, its release function will be called. - */ -static void destroy_most_aim_obj(struct most_aim_obj *p) -{ - kobject_put(&p->kobj); -} - -/* ___ ___ - * ___C O R E___ - */ - -/** - * Instantiation of the MOST bus - */ -static struct bus_type most_bus = { - .name = "most", -}; - -/** - * Instantiation of the core driver - */ -static struct device_driver mostcore = { - .name = "mostcore", - .bus = &most_bus, -}; - -static inline void trash_mbo(struct mbo *mbo) -{ - unsigned long flags; - struct most_c_obj *c = mbo->context; - - spin_lock_irqsave(&c->fifo_lock, flags); - list_add(&mbo->list, &c->trash_fifo); - spin_unlock_irqrestore(&c->fifo_lock, flags); -} - -static bool hdm_mbo_ready(struct most_c_obj *c) -{ - bool empty; - - if (c->enqueue_halt) - return false; - - spin_lock_irq(&c->fifo_lock); - empty = list_empty(&c->halt_fifo); - spin_unlock_irq(&c->fifo_lock); - - return !empty; -} - -static void nq_hdm_mbo(struct mbo *mbo) -{ - unsigned long flags; - struct most_c_obj *c = mbo->context; - - spin_lock_irqsave(&c->fifo_lock, flags); - list_add_tail(&mbo->list, &c->halt_fifo); - spin_unlock_irqrestore(&c->fifo_lock, flags); - wake_up_interruptible(&c->hdm_fifo_wq); -} - -static int hdm_enqueue_thread(void *data) -{ - struct most_c_obj *c = data; - struct mbo *mbo; - int ret; - typeof(c->iface->enqueue) enqueue = c->iface->enqueue; - - while (likely(!kthread_should_stop())) { - wait_event_interruptible(c->hdm_fifo_wq, - hdm_mbo_ready(c) || - kthread_should_stop()); - - mutex_lock(&c->nq_mutex); - spin_lock_irq(&c->fifo_lock); - if (unlikely(c->enqueue_halt || list_empty(&c->halt_fifo))) { - spin_unlock_irq(&c->fifo_lock); - mutex_unlock(&c->nq_mutex); - continue; - } - - mbo = list_pop_mbo(&c->halt_fifo); - spin_unlock_irq(&c->fifo_lock); - - if (c->cfg.direction == MOST_CH_RX) - mbo->buffer_length = c->cfg.buffer_size; - - ret = enqueue(mbo->ifp, mbo->hdm_channel_id, mbo); - mutex_unlock(&c->nq_mutex); - - if (unlikely(ret)) { - pr_err("hdm enqueue failed\n"); - nq_hdm_mbo(mbo); - c->hdm_enqueue_task = NULL; - return 0; - } - } - - return 0; -} - -static int run_enqueue_thread(struct most_c_obj *c, int channel_id) -{ - struct task_struct *task = - kthread_run(hdm_enqueue_thread, c, "hdm_fifo_%d", - channel_id); - - if (IS_ERR(task)) - return PTR_ERR(task); - - c->hdm_enqueue_task = task; - return 0; -} - -/** - * arm_mbo - recycle MBO for further usage - * @mbo: buffer object - * - * This puts an MBO back to the list to have it ready for up coming - * tx transactions. - * - * In case the MBO belongs to a channel that recently has been - * poisoned, the MBO is scheduled to be trashed. - * Calls the completion handler of an attached AIM. - */ -static void arm_mbo(struct mbo *mbo) -{ - unsigned long flags; - struct most_c_obj *c; - - BUG_ON((!mbo) || (!mbo->context)); - c = mbo->context; - - if (c->is_poisoned) { - trash_mbo(mbo); - return; - } - - spin_lock_irqsave(&c->fifo_lock, flags); - ++*mbo->num_buffers_ptr; - list_add_tail(&mbo->list, &c->fifo); - spin_unlock_irqrestore(&c->fifo_lock, flags); - - if (c->aim0.refs && c->aim0.ptr->tx_completion) - c->aim0.ptr->tx_completion(c->iface, c->channel_id); - - if (c->aim1.refs && c->aim1.ptr->tx_completion) - c->aim1.ptr->tx_completion(c->iface, c->channel_id); -} - -/** - * arm_mbo_chain - helper function that arms an MBO chain for the HDM - * @c: pointer to interface channel - * @dir: direction of the channel - * @compl: pointer to completion function - * - * This allocates buffer objects including the containing DMA coherent - * buffer and puts them in the fifo. - * Buffers of Rx channels are put in the kthread fifo, hence immediately - * submitted to the HDM. - * - * Returns the number of allocated and enqueued MBOs. - */ -static int arm_mbo_chain(struct most_c_obj *c, int dir, - void (*compl)(struct mbo *)) -{ - unsigned int i; - int retval; - struct mbo *mbo; - u32 coherent_buf_size = c->cfg.buffer_size + c->cfg.extra_len; - - atomic_set(&c->mbo_nq_level, 0); - - for (i = 0; i < c->cfg.num_buffers; i++) { - mbo = kzalloc(sizeof(*mbo), GFP_KERNEL); - if (!mbo) { - retval = i; - goto _exit; - } - mbo->context = c; - mbo->ifp = c->iface; - mbo->hdm_channel_id = c->channel_id; - mbo->virt_address = dma_alloc_coherent(NULL, - coherent_buf_size, - &mbo->bus_address, - GFP_KERNEL); - if (!mbo->virt_address) { - pr_info("WARN: No DMA coherent buffer.\n"); - retval = i; - goto _error1; - } - mbo->complete = compl; - mbo->num_buffers_ptr = &dummy_num_buffers; - if (dir == MOST_CH_RX) { - nq_hdm_mbo(mbo); - atomic_inc(&c->mbo_nq_level); - } else { - arm_mbo(mbo); - } - } - return i; - -_error1: - kfree(mbo); -_exit: - return retval; -} - -/** - * most_submit_mbo - submits an MBO to fifo - * @mbo: pointer to the MBO - */ -void most_submit_mbo(struct mbo *mbo) -{ - if (WARN_ONCE(!mbo || !mbo->context, - "bad mbo or missing channel reference\n")) - return; - - nq_hdm_mbo(mbo); -} -EXPORT_SYMBOL_GPL(most_submit_mbo); - -/** - * most_write_completion - write completion handler - * @mbo: pointer to MBO - * - * This recycles the MBO for further usage. In case the channel has been - * poisoned, the MBO is scheduled to be trashed. - */ -static void most_write_completion(struct mbo *mbo) -{ - struct most_c_obj *c; - - BUG_ON((!mbo) || (!mbo->context)); - - c = mbo->context; - if (mbo->status == MBO_E_INVAL) - pr_info("WARN: Tx MBO status: invalid\n"); - if (unlikely(c->is_poisoned || (mbo->status == MBO_E_CLOSE))) - trash_mbo(mbo); - else - arm_mbo(mbo); -} - -/** - * get_channel_by_iface - get pointer to channel object - * @iface: pointer to interface instance - * @id: channel ID - * - * This retrieves a pointer to a channel of the given interface and channel ID. - */ -static struct -most_c_obj *get_channel_by_iface(struct most_interface *iface, int id) -{ - struct most_inst_obj *i; - - if (unlikely(!iface)) { - pr_err("Bad interface\n"); - return NULL; - } - if (unlikely((id < 0) || (id >= iface->num_channels))) { - pr_err("Channel index (%d) out of range\n", id); - return NULL; - } - i = iface->priv; - if (unlikely(!i)) { - pr_err("interface is not registered\n"); - return NULL; - } - return i->channel[id]; -} - -int channel_has_mbo(struct most_interface *iface, int id, struct most_aim *aim) -{ - struct most_c_obj *c = get_channel_by_iface(iface, id); - unsigned long flags; - int empty; - - if (unlikely(!c)) - return -EINVAL; - - if (c->aim0.refs && c->aim1.refs && - ((aim == c->aim0.ptr && c->aim0.num_buffers <= 0) || - (aim == c->aim1.ptr && c->aim1.num_buffers <= 0))) - return 0; - - spin_lock_irqsave(&c->fifo_lock, flags); - empty = list_empty(&c->fifo); - spin_unlock_irqrestore(&c->fifo_lock, flags); - return !empty; -} -EXPORT_SYMBOL_GPL(channel_has_mbo); - -/** - * most_get_mbo - get pointer to an MBO of pool - * @iface: pointer to interface instance - * @id: channel ID - * - * This attempts to get a free buffer out of the channel fifo. - * Returns a pointer to MBO on success or NULL otherwise. - */ -struct mbo *most_get_mbo(struct most_interface *iface, int id, - struct most_aim *aim) -{ - struct mbo *mbo; - struct most_c_obj *c; - unsigned long flags; - int *num_buffers_ptr; - - c = get_channel_by_iface(iface, id); - if (unlikely(!c)) - return NULL; - - if (c->aim0.refs && c->aim1.refs && - ((aim == c->aim0.ptr && c->aim0.num_buffers <= 0) || - (aim == c->aim1.ptr && c->aim1.num_buffers <= 0))) - return NULL; - - if (aim == c->aim0.ptr) - num_buffers_ptr = &c->aim0.num_buffers; - else if (aim == c->aim1.ptr) - num_buffers_ptr = &c->aim1.num_buffers; - else - num_buffers_ptr = &dummy_num_buffers; - - spin_lock_irqsave(&c->fifo_lock, flags); - if (list_empty(&c->fifo)) { - spin_unlock_irqrestore(&c->fifo_lock, flags); - return NULL; - } - mbo = list_pop_mbo(&c->fifo); - --*num_buffers_ptr; - spin_unlock_irqrestore(&c->fifo_lock, flags); - - mbo->num_buffers_ptr = num_buffers_ptr; - mbo->buffer_length = c->cfg.buffer_size; - return mbo; -} -EXPORT_SYMBOL_GPL(most_get_mbo); - -/** - * most_put_mbo - return buffer to pool - * @mbo: buffer object - */ -void most_put_mbo(struct mbo *mbo) -{ - struct most_c_obj *c = mbo->context; - - if (c->cfg.direction == MOST_CH_TX) { - arm_mbo(mbo); - return; - } - nq_hdm_mbo(mbo); - atomic_inc(&c->mbo_nq_level); -} -EXPORT_SYMBOL_GPL(most_put_mbo); - -/** - * most_read_completion - read completion handler - * @mbo: pointer to MBO - * - * This function is called by the HDM when data has been received from the - * hardware and copied to the buffer of the MBO. - * - * In case the channel has been poisoned it puts the buffer in the trash queue. - * Otherwise, it passes the buffer to an AIM for further processing. - */ -static void most_read_completion(struct mbo *mbo) -{ - struct most_c_obj *c = mbo->context; - - if (unlikely(c->is_poisoned || (mbo->status == MBO_E_CLOSE))) { - trash_mbo(mbo); - return; - } - - if (mbo->status == MBO_E_INVAL) { - nq_hdm_mbo(mbo); - atomic_inc(&c->mbo_nq_level); - return; - } - - if (atomic_sub_and_test(1, &c->mbo_nq_level)) - c->is_starving = 1; - - if (c->aim0.refs && c->aim0.ptr->rx_completion && - c->aim0.ptr->rx_completion(mbo) == 0) - return; - - if (c->aim1.refs && c->aim1.ptr->rx_completion && - c->aim1.ptr->rx_completion(mbo) == 0) - return; - - most_put_mbo(mbo); -} - -/** - * most_start_channel - prepares a channel for communication - * @iface: pointer to interface instance - * @id: channel ID - * - * This prepares the channel for usage. Cross-checks whether the - * channel's been properly configured. - * - * Returns 0 on success or error code otherwise. - */ -int most_start_channel(struct most_interface *iface, int id, - struct most_aim *aim) -{ - int num_buffer; - int ret; - struct most_c_obj *c = get_channel_by_iface(iface, id); - - if (unlikely(!c)) - return -EINVAL; - - mutex_lock(&c->start_mutex); - if (c->aim0.refs + c->aim1.refs > 0) - goto out; /* already started by other aim */ - - if (!try_module_get(iface->mod)) { - pr_info("failed to acquire HDM lock\n"); - mutex_unlock(&c->start_mutex); - return -ENOLCK; - } - - c->cfg.extra_len = 0; - if (c->iface->configure(c->iface, c->channel_id, &c->cfg)) { - pr_info("channel configuration failed. Go check settings...\n"); - ret = -EINVAL; - goto error; - } - - init_waitqueue_head(&c->hdm_fifo_wq); - - if (c->cfg.direction == MOST_CH_RX) - num_buffer = arm_mbo_chain(c, c->cfg.direction, - most_read_completion); - else - num_buffer = arm_mbo_chain(c, c->cfg.direction, - most_write_completion); - if (unlikely(!num_buffer)) { - pr_info("failed to allocate memory\n"); - ret = -ENOMEM; - goto error; - } - - ret = run_enqueue_thread(c, id); - if (ret) - goto error; - - c->is_starving = 0; - c->aim0.num_buffers = c->cfg.num_buffers / 2; - c->aim1.num_buffers = c->cfg.num_buffers - c->aim0.num_buffers; - atomic_set(&c->mbo_ref, num_buffer); - -out: - if (aim == c->aim0.ptr) - c->aim0.refs++; - if (aim == c->aim1.ptr) - c->aim1.refs++; - mutex_unlock(&c->start_mutex); - return 0; - -error: - module_put(iface->mod); - mutex_unlock(&c->start_mutex); - return ret; -} -EXPORT_SYMBOL_GPL(most_start_channel); - -/** - * most_stop_channel - stops a running channel - * @iface: pointer to interface instance - * @id: channel ID - */ -int most_stop_channel(struct most_interface *iface, int id, - struct most_aim *aim) -{ - struct most_c_obj *c; - - if (unlikely((!iface) || (id >= iface->num_channels) || (id < 0))) { - pr_err("Bad interface or index out of range\n"); - return -EINVAL; - } - c = get_channel_by_iface(iface, id); - if (unlikely(!c)) - return -EINVAL; - - mutex_lock(&c->start_mutex); - if (c->aim0.refs + c->aim1.refs >= 2) - goto out; - - if (c->hdm_enqueue_task) - kthread_stop(c->hdm_enqueue_task); - c->hdm_enqueue_task = NULL; - - if (iface->mod) - module_put(iface->mod); - - c->is_poisoned = true; - if (c->iface->poison_channel(c->iface, c->channel_id)) { - pr_err("Cannot stop channel %d of mdev %s\n", c->channel_id, - c->iface->description); - mutex_unlock(&c->start_mutex); - return -EAGAIN; - } - flush_trash_fifo(c); - flush_channel_fifos(c); - -#ifdef CMPL_INTERRUPTIBLE - if (wait_for_completion_interruptible(&c->cleanup)) { - pr_info("Interrupted while clean up ch %d\n", c->channel_id); - mutex_unlock(&c->start_mutex); - return -EINTR; - } -#else - wait_for_completion(&c->cleanup); -#endif - c->is_poisoned = false; - -out: - if (aim == c->aim0.ptr) - c->aim0.refs--; - if (aim == c->aim1.ptr) - c->aim1.refs--; - mutex_unlock(&c->start_mutex); - return 0; -} -EXPORT_SYMBOL_GPL(most_stop_channel); - -/** - * most_register_aim - registers an AIM (driver) with the core - * @aim: instance of AIM to be registered - */ -int most_register_aim(struct most_aim *aim) -{ - struct most_aim_obj *aim_obj; - - if (!aim) { - pr_err("Bad driver\n"); - return -EINVAL; - } - aim_obj = create_most_aim_obj(aim->name); - if (!aim_obj) { - pr_info("failed to alloc driver object\n"); - return -ENOMEM; - } - aim_obj->driver = aim; - aim->context = aim_obj; - pr_info("registered new application interfacing module %s\n", - aim->name); - list_add_tail(&aim_obj->list, &aim_list); - return 0; -} -EXPORT_SYMBOL_GPL(most_register_aim); - -/** - * most_deregister_aim - deregisters an AIM (driver) with the core - * @aim: AIM to be removed - */ -int most_deregister_aim(struct most_aim *aim) -{ - struct most_aim_obj *aim_obj; - struct most_c_obj *c, *tmp; - struct most_inst_obj *i, *i_tmp; - - if (!aim) { - pr_err("Bad driver\n"); - return -EINVAL; - } - - aim_obj = aim->context; - if (!aim_obj) { - pr_info("driver not registered.\n"); - return -EINVAL; - } - list_for_each_entry_safe(i, i_tmp, &instance_list, list) { - list_for_each_entry_safe(c, tmp, &i->channel_list, list) { - if (c->aim0.ptr == aim || c->aim1.ptr == aim) - aim->disconnect_channel( - c->iface, c->channel_id); - if (c->aim0.ptr == aim) - c->aim0.ptr = NULL; - if (c->aim1.ptr == aim) - c->aim1.ptr = NULL; - } - } - list_del(&aim_obj->list); - destroy_most_aim_obj(aim_obj); - pr_info("deregistering application interfacing module %s\n", aim->name); - return 0; -} -EXPORT_SYMBOL_GPL(most_deregister_aim); - -/** - * most_register_interface - registers an interface with core - * @iface: pointer to the instance of the interface description. - * - * Allocates and initializes a new interface instance and all of its channels. - * Returns a pointer to kobject or an error pointer. - */ -struct kobject *most_register_interface(struct most_interface *iface) -{ - unsigned int i; - int id; - char name[STRING_SIZE]; - char channel_name[STRING_SIZE]; - struct most_c_obj *c; - struct most_inst_obj *inst; - - if (!iface || !iface->enqueue || !iface->configure || - !iface->poison_channel || (iface->num_channels > MAX_CHANNELS)) { - pr_err("Bad interface or channel overflow\n"); - return ERR_PTR(-EINVAL); - } - - id = ida_simple_get(&mdev_id, 0, 0, GFP_KERNEL); - if (id < 0) { - pr_info("Failed to alloc mdev ID\n"); - return ERR_PTR(id); - } - snprintf(name, STRING_SIZE, "mdev%d", id); - - inst = create_most_inst_obj(name); - if (!inst) { - pr_info("Failed to allocate interface instance\n"); - ida_simple_remove(&mdev_id, id); - return ERR_PTR(-ENOMEM); - } - - iface->priv = inst; - INIT_LIST_HEAD(&inst->channel_list); - inst->iface = iface; - inst->dev_id = id; - list_add_tail(&inst->list, &instance_list); - - for (i = 0; i < iface->num_channels; i++) { - const char *name_suffix = iface->channel_vector[i].name_suffix; - - if (!name_suffix) - snprintf(channel_name, STRING_SIZE, "ch%d", i); - else - snprintf(channel_name, STRING_SIZE, "%s", name_suffix); - - /* this increments the reference count of this instance */ - c = create_most_c_obj(channel_name, &inst->kobj); - if (!c) - goto free_instance; - inst->channel[i] = c; - c->is_starving = 0; - c->iface = iface; - c->inst = inst; - c->channel_id = i; - c->keep_mbo = false; - c->enqueue_halt = false; - c->is_poisoned = false; - c->cfg.direction = 0; - c->cfg.data_type = 0; - c->cfg.num_buffers = 0; - c->cfg.buffer_size = 0; - c->cfg.subbuffer_size = 0; - c->cfg.packets_per_xact = 0; - spin_lock_init(&c->fifo_lock); - INIT_LIST_HEAD(&c->fifo); - INIT_LIST_HEAD(&c->trash_fifo); - INIT_LIST_HEAD(&c->halt_fifo); - init_completion(&c->cleanup); - atomic_set(&c->mbo_ref, 0); - mutex_init(&c->start_mutex); - mutex_init(&c->nq_mutex); - list_add_tail(&c->list, &inst->channel_list); - } - pr_info("registered new MOST device mdev%d (%s)\n", - inst->dev_id, iface->description); - return &inst->kobj; - -free_instance: - pr_info("Failed allocate channel(s)\n"); - list_del(&inst->list); - ida_simple_remove(&mdev_id, id); - destroy_most_inst_obj(inst); - return ERR_PTR(-ENOMEM); -} -EXPORT_SYMBOL_GPL(most_register_interface); - -/** - * most_deregister_interface - deregisters an interface with core - * @iface: pointer to the interface instance description. - * - * Before removing an interface instance from the list, all running - * channels are stopped and poisoned. - */ -void most_deregister_interface(struct most_interface *iface) -{ - struct most_inst_obj *i = iface->priv; - struct most_c_obj *c; - - if (unlikely(!i)) { - pr_info("Bad Interface\n"); - return; - } - pr_info("deregistering MOST device %s (%s)\n", i->kobj.name, - iface->description); - - list_for_each_entry(c, &i->channel_list, list) { - if (c->aim0.ptr) - c->aim0.ptr->disconnect_channel(c->iface, - c->channel_id); - if (c->aim1.ptr) - c->aim1.ptr->disconnect_channel(c->iface, - c->channel_id); - c->aim0.ptr = NULL; - c->aim1.ptr = NULL; - } - - ida_simple_remove(&mdev_id, i->dev_id); - list_del(&i->list); - destroy_most_inst_obj(i); -} -EXPORT_SYMBOL_GPL(most_deregister_interface); - -/** - * most_stop_enqueue - prevents core from enqueueing MBOs - * @iface: pointer to interface - * @id: channel id - * - * This is called by an HDM that _cannot_ attend to its duties and - * is imminent to get run over by the core. The core is not going to - * enqueue any further packets unless the flagging HDM calls - * most_resume enqueue(). - */ -void most_stop_enqueue(struct most_interface *iface, int id) -{ - struct most_c_obj *c = get_channel_by_iface(iface, id); - - if (!c) - return; - - mutex_lock(&c->nq_mutex); - c->enqueue_halt = true; - mutex_unlock(&c->nq_mutex); -} -EXPORT_SYMBOL_GPL(most_stop_enqueue); - -/** - * most_resume_enqueue - allow core to enqueue MBOs again - * @iface: pointer to interface - * @id: channel id - * - * This clears the enqueue halt flag and enqueues all MBOs currently - * sitting in the wait fifo. - */ -void most_resume_enqueue(struct most_interface *iface, int id) -{ - struct most_c_obj *c = get_channel_by_iface(iface, id); - - if (!c) - return; - - mutex_lock(&c->nq_mutex); - c->enqueue_halt = false; - mutex_unlock(&c->nq_mutex); - - wake_up_interruptible(&c->hdm_fifo_wq); -} -EXPORT_SYMBOL_GPL(most_resume_enqueue); - -static int __init most_init(void) -{ - int err; - - pr_info("init()\n"); - INIT_LIST_HEAD(&instance_list); - INIT_LIST_HEAD(&aim_list); - ida_init(&mdev_id); - - err = bus_register(&most_bus); - if (err) { - pr_info("Cannot register most bus\n"); - return err; - } - - most_class = class_create(THIS_MODULE, "most"); - if (IS_ERR(most_class)) { - pr_info("No udev support.\n"); - err = PTR_ERR(most_class); - goto exit_bus; - } - - err = driver_register(&mostcore); - if (err) { - pr_info("Cannot register core driver\n"); - goto exit_class; - } - - core_dev = device_create(most_class, NULL, 0, NULL, "mostcore"); - if (IS_ERR(core_dev)) { - err = PTR_ERR(core_dev); - goto exit_driver; - } - - most_aim_kset = kset_create_and_add("aims", NULL, &core_dev->kobj); - if (!most_aim_kset) { - err = -ENOMEM; - goto exit_class_container; - } - - most_inst_kset = kset_create_and_add("devices", NULL, &core_dev->kobj); - if (!most_inst_kset) { - err = -ENOMEM; - goto exit_driver_kset; - } - - return 0; - -exit_driver_kset: - kset_unregister(most_aim_kset); -exit_class_container: - device_destroy(most_class, 0); -exit_driver: - driver_unregister(&mostcore); -exit_class: - class_destroy(most_class); -exit_bus: - bus_unregister(&most_bus); - return err; -} - -static void __exit most_exit(void) -{ - struct most_inst_obj *i, *i_tmp; - struct most_aim_obj *d, *d_tmp; - - pr_info("exit core module\n"); - list_for_each_entry_safe(d, d_tmp, &aim_list, list) { - destroy_most_aim_obj(d); - } - - list_for_each_entry_safe(i, i_tmp, &instance_list, list) { - list_del(&i->list); - destroy_most_inst_obj(i); - } - kset_unregister(most_inst_kset); - kset_unregister(most_aim_kset); - device_destroy(most_class, 0); - driver_unregister(&mostcore); - class_destroy(most_class); - bus_unregister(&most_bus); - ida_destroy(&mdev_id); -} - -module_init(most_init); -module_exit(most_exit); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Christian Gromm <christian.gromm@microchip.com>"); -MODULE_DESCRIPTION("Core module of stacked MOST Linux driver"); diff --git a/drivers/staging/most/aim-network/Kconfig b/drivers/staging/most/net/Kconfig index 4c66b24cf73c..795330ba94ef 100644 --- a/drivers/staging/most/aim-network/Kconfig +++ b/drivers/staging/most/net/Kconfig @@ -2,12 +2,12 @@ # MOST Networking configuration # -config AIM_NETWORK - tristate "Networking AIM" +config MOST_NET + tristate "Net" depends on NET ---help--- Say Y here if you want to commumicate via a networking device. To compile this driver as a module, choose M here: the - module will be called aim_network. + module will be called most_net. diff --git a/drivers/staging/most/net/Makefile b/drivers/staging/most/net/Makefile new file mode 100644 index 000000000000..54500aa77be8 --- /dev/null +++ b/drivers/staging/most/net/Makefile @@ -0,0 +1,4 @@ +obj-$(CONFIG_MOST_NET) += most_net.o + +most_net-objs := net.o +ccflags-y += -Idrivers/staging/ diff --git a/drivers/staging/most/aim-network/networking.c b/drivers/staging/most/net/net.c index 936f013c350e..30d816b7e165 100644 --- a/drivers/staging/most/aim-network/networking.c +++ b/drivers/staging/most/net/net.c @@ -1,14 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * Networking AIM - Networking Application Interface Module for MostCore + * net.c - Networking component for Mostcore * * Copyright (C) 2015, Microchip Technology Germany II GmbH & Co. KG - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This file is licensed under GPLv2. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -21,7 +15,7 @@ #include <linux/list.h> #include <linux/wait.h> #include <linux/kobject.h> -#include "mostcore.h" +#include "most/core.h" #define MEP_HDR_LEN 8 #define MDP_HDR_LEN 16 @@ -52,10 +46,12 @@ ((len) > MEP_HDR_LEN && \ EXTRACT_BIT_SET(PMS_FIFONO, (buf)[3]) == PMS_FIFONO_MEP) -#define PMS_IS_MAMAC(buf, len) \ - ((len) > MDP_HDR_LEN && \ - EXTRACT_BIT_SET(PMS_FIFONO, (buf)[3]) == PMS_FIFONO_MDP && \ - EXTRACT_BIT_SET(PMS_TELID, (buf)[14]) == PMS_TELID_UNSEGM_MAMAC) +static inline bool pms_is_mamac(char *buf, u32 len) +{ + return (len > MDP_HDR_LEN && + EXTRACT_BIT_SET(PMS_FIFONO, buf[3]) == PMS_FIFONO_MDP && + EXTRACT_BIT_SET(PMS_TELID, buf[14]) == PMS_TELID_UNSEGM_MAMAC); +} struct net_dev_channel { bool linked; @@ -74,7 +70,7 @@ struct net_dev_context { static struct list_head net_devices = LIST_HEAD_INIT(net_devices); static struct mutex probe_disc_mt; /* ch->linked = true, most_nd_open */ static struct spinlock list_lock; /* list_head, ch->linked = false, dev_hold */ -static struct most_aim aim; +static struct core_component comp; static int skb_to_mamac(const struct sk_buff *skb, struct mbo *mbo) { @@ -184,15 +180,15 @@ static int most_nd_open(struct net_device *dev) mutex_lock(&probe_disc_mt); - if (most_start_channel(nd->iface, nd->rx.ch_id, &aim)) { + if (most_start_channel(nd->iface, nd->rx.ch_id, &comp)) { netdev_err(dev, "most_start_channel() failed\n"); ret = -EBUSY; goto unlock; } - if (most_start_channel(nd->iface, nd->tx.ch_id, &aim)) { + if (most_start_channel(nd->iface, nd->tx.ch_id, &comp)) { netdev_err(dev, "most_start_channel() failed\n"); - most_stop_channel(nd->iface, nd->rx.ch_id, &aim); + most_stop_channel(nd->iface, nd->rx.ch_id, &comp); ret = -EBUSY; goto unlock; } @@ -218,8 +214,8 @@ static int most_nd_stop(struct net_device *dev) netif_stop_queue(dev); if (nd->iface->request_netinfo) nd->iface->request_netinfo(nd->iface, nd->tx.ch_id, NULL); - most_stop_channel(nd->iface, nd->rx.ch_id, &aim); - most_stop_channel(nd->iface, nd->tx.ch_id, &aim); + most_stop_channel(nd->iface, nd->rx.ch_id, &comp); + most_stop_channel(nd->iface, nd->tx.ch_id, &comp); return 0; } @@ -231,7 +227,7 @@ static netdev_tx_t most_nd_start_xmit(struct sk_buff *skb, struct mbo *mbo; int ret; - mbo = most_get_mbo(nd->iface, nd->tx.ch_id, &aim); + mbo = most_get_mbo(nd->iface, nd->tx.ch_id, &comp); if (!mbo) { netif_stop_queue(dev); @@ -296,9 +292,8 @@ static struct net_dev_context *get_net_dev_hold(struct most_interface *iface) return nd; } -static int aim_probe_channel(struct most_interface *iface, int channel_idx, - struct most_channel_config *ccfg, - struct kobject *parent, char *name) +static int comp_probe_channel(struct most_interface *iface, int channel_idx, + struct most_channel_config *ccfg, char *name) { struct net_dev_context *nd; struct net_dev_channel *ch; @@ -353,8 +348,8 @@ unlock: return ret; } -static int aim_disconnect_channel(struct most_interface *iface, - int channel_idx) +static int comp_disconnect_channel(struct most_interface *iface, + int channel_idx) { struct net_dev_context *nd; struct net_dev_channel *ch; @@ -400,8 +395,8 @@ unlock: return ret; } -static int aim_resume_tx_channel(struct most_interface *iface, - int channel_idx) +static int comp_resume_tx_channel(struct most_interface *iface, + int channel_idx) { struct net_dev_context *nd; @@ -419,7 +414,7 @@ put_nd: return 0; } -static int aim_rx_data(struct mbo *mbo) +static int comp_rx_data(struct mbo *mbo) { const u32 zero = 0; struct net_dev_context *nd; @@ -442,7 +437,7 @@ static int aim_rx_data(struct mbo *mbo) dev = nd->dev; if (nd->is_mamac) { - if (!PMS_IS_MAMAC(buf, len)) { + if (!pms_is_mamac(buf, len)) { ret = -EIO; goto put_nd; } @@ -501,24 +496,24 @@ put_nd: return ret; } -static struct most_aim aim = { - .name = "networking", - .probe_channel = aim_probe_channel, - .disconnect_channel = aim_disconnect_channel, - .tx_completion = aim_resume_tx_channel, - .rx_completion = aim_rx_data, +static struct core_component comp = { + .name = "net", + .probe_channel = comp_probe_channel, + .disconnect_channel = comp_disconnect_channel, + .tx_completion = comp_resume_tx_channel, + .rx_completion = comp_rx_data, }; static int __init most_net_init(void) { spin_lock_init(&list_lock); mutex_init(&probe_disc_mt); - return most_register_aim(&aim); + return most_register_component(&comp); } static void __exit most_net_exit(void) { - most_deregister_aim(&aim); + most_deregister_component(&comp); } /** @@ -564,4 +559,4 @@ module_init(most_net_init); module_exit(most_net_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Andrey Shvetsov <andrey.shvetsov@k2l.de>"); -MODULE_DESCRIPTION("Networking Application Interface Module for MostCore"); +MODULE_DESCRIPTION("Networking Component Module for Mostcore"); diff --git a/drivers/staging/most/aim-sound/Kconfig b/drivers/staging/most/sound/Kconfig index 3194c219ff14..115262a58a42 100644 --- a/drivers/staging/most/aim-sound/Kconfig +++ b/drivers/staging/most/sound/Kconfig @@ -2,12 +2,12 @@ # MOST ALSA configuration # -config AIM_SOUND - tristate "ALSA AIM" +config MOST_SOUND + tristate "Sound" depends on SND select SND_PCM ---help--- Say Y here if you want to commumicate via ALSA/sound devices. To compile this driver as a module, choose M here: the - module will be called aim_sound. + module will be called most_sound. diff --git a/drivers/staging/most/sound/Makefile b/drivers/staging/most/sound/Makefile new file mode 100644 index 000000000000..eee8774e38cb --- /dev/null +++ b/drivers/staging/most/sound/Makefile @@ -0,0 +1,4 @@ +obj-$(CONFIG_MOST_SOUND) += most_sound.o + +most_sound-objs := sound.o +ccflags-y += -Idrivers/staging/ diff --git a/drivers/staging/most/aim-sound/sound.c b/drivers/staging/most/sound/sound.c index ea1366a44008..83cec21c85b8 100644 --- a/drivers/staging/most/aim-sound/sound.c +++ b/drivers/staging/most/sound/sound.c @@ -1,14 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * sound.c - Audio Application Interface Module for Mostcore + * sound.c - Sound component for Mostcore * * Copyright (C) 2015 Microchip Technology Germany II GmbH & Co. KG - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This file is licensed under GPLv2. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -22,12 +16,12 @@ #include <sound/pcm_params.h> #include <linux/sched.h> #include <linux/kthread.h> -#include <mostcore.h> +#include <most/core.h> #define DRIVER_NAME "sound" static struct list_head dev_list; -static struct most_aim audio_aim; +static struct core_component comp; /** * struct channel - private structure to keep channel specific data @@ -240,7 +234,7 @@ static int playback_thread(void *data) kthread_should_stop() || (channel->is_stream_running && (mbo = most_get_mbo(channel->iface, channel->id, - &audio_aim)))); + &comp)))); if (!mbo) continue; @@ -283,7 +277,7 @@ static int pcm_open(struct snd_pcm_substream *substream) } } - if (most_start_channel(channel->iface, channel->id, &audio_aim)) { + if (most_start_channel(channel->iface, channel->id, &comp)) { pr_err("most_start_channel() failed!\n"); if (cfg->direction == MOST_CH_TX) kthread_stop(channel->playback_task); @@ -310,7 +304,7 @@ static int pcm_close(struct snd_pcm_substream *substream) if (channel->cfg->direction == MOST_CH_TX) kthread_stop(channel->playback_task); - most_stop_channel(channel->iface, channel->id, &audio_aim); + most_stop_channel(channel->iface, channel->id, &comp); return 0; } @@ -545,7 +539,6 @@ error: * @iface: pointer to interface instance * @channel_id: channel index/ID * @cfg: pointer to actual channel configuration - * @parent: pointer to kobject (needed for sysfs hook-up) * @arg_list: string that provides the name of the device to be created in /dev * plus the desired audio resolution * @@ -555,7 +548,7 @@ error: */ static int audio_probe_channel(struct most_interface *iface, int channel_id, struct most_channel_config *cfg, - struct kobject *parent, char *arg_list) + char *arg_list) { struct channel *channel; struct snd_card *card; @@ -724,9 +717,9 @@ static int audio_tx_completion(struct most_interface *iface, int channel_id) } /** - * Initialization of the struct most_aim + * Initialization of the struct core_component */ -static struct most_aim audio_aim = { +static struct core_component comp = { .name = DRIVER_NAME, .probe_channel = audio_probe_channel, .disconnect_channel = audio_disconnect_channel, @@ -740,7 +733,7 @@ static int __init audio_init(void) INIT_LIST_HEAD(&dev_list); - return most_register_aim(&audio_aim); + return most_register_component(&comp); } static void __exit audio_exit(void) @@ -754,7 +747,7 @@ static void __exit audio_exit(void) snd_card_free(channel->card); } - most_deregister_aim(&audio_aim); + most_deregister_component(&comp); } module_init(audio_init); @@ -762,4 +755,4 @@ module_exit(audio_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Christian Gromm <christian.gromm@microchip.com>"); -MODULE_DESCRIPTION("Audio Application Interface Module for MostCore"); +MODULE_DESCRIPTION("Sound Component Module for Mostcore"); diff --git a/drivers/staging/most/hdm-usb/Kconfig b/drivers/staging/most/usb/Kconfig index 487f1f34776c..ebbdb573a9a6 100644 --- a/drivers/staging/most/hdm-usb/Kconfig +++ b/drivers/staging/most/usb/Kconfig @@ -2,13 +2,12 @@ # MOST USB configuration # -config HDM_USB - tristate "USB HDM" +config MOST_USB + tristate "USB" depends on USB && NET - ---help--- Say Y here if you want to connect via USB to network tranceiver. This device driver depends on the networking AIM. To compile this driver as a module, choose M here: the - module will be called hdm_usb. + module will be called most_usb. diff --git a/drivers/staging/most/usb/Makefile b/drivers/staging/most/usb/Makefile new file mode 100644 index 000000000000..18d28cba4fbf --- /dev/null +++ b/drivers/staging/most/usb/Makefile @@ -0,0 +1,4 @@ +obj-$(CONFIG_MOST_USB) += most_usb.o + +most_usb-objs := usb.o +ccflags-y += -Idrivers/staging/ diff --git a/drivers/staging/most/hdm-usb/hdm_usb.c b/drivers/staging/most/usb/usb.c index 667dacac81f0..31f184cfcd69 100644 --- a/drivers/staging/most/hdm-usb/hdm_usb.c +++ b/drivers/staging/most/usb/usb.c @@ -1,14 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * hdm_usb.c - Hardware dependent module for USB + * usb.c - Hardware dependent module for USB * * Copyright (C) 2013-2015 Microchip Technology Germany II GmbH & Co. KG - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This file is licensed under GPLv2. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -29,7 +23,7 @@ #include <linux/dma-mapping.h> #include <linux/etherdevice.h> #include <linux/uaccess.h> -#include "mostcore.h" +#include "most/core.h" #define USB_MTU 512 #define NO_ISOCHRONOUS_URB 0 @@ -70,12 +64,12 @@ * @reg_addr: register address for arbitrary DCI access */ struct most_dci_obj { - struct kobject kobj; + struct device dev; struct usb_device *usb_device; u16 reg_addr; }; -#define to_dci_obj(p) container_of(p, struct most_dci_obj, kobj) +#define to_dci_obj(p) container_of(p, struct most_dci_obj, dev) struct most_dev; @@ -90,7 +84,6 @@ struct clear_hold_work { /** * struct most_dev - holds all usb interface specific stuff - * @parent: parent object in sysfs * @usb_device: pointer to usb device * @iface: hardware interface * @cap: channel capabilities @@ -108,7 +101,6 @@ struct clear_hold_work { * @poll_work_obj: work for polling link status */ struct most_dev { - struct kobject *parent; struct usb_device *usb_device; struct most_interface iface; struct most_channel_capability *cap; @@ -125,8 +117,8 @@ struct most_dev { struct mutex io_mutex; struct timer_list link_stat_timer; struct work_struct poll_work_obj; - void (*on_netinfo)(struct most_interface *, unsigned char, - unsigned char *); + void (*on_netinfo)(struct most_interface *most_iface, + unsigned char link_state, unsigned char *addrs); }; #define to_mdev(d) container_of(d, struct most_dev, iface) @@ -817,6 +809,21 @@ static void wq_clear_halt(struct work_struct *wq_obj) if (usb_clear_halt(mdev->usb_device, pipe)) dev_warn(&mdev->usb_device->dev, "Failed to reset endpoint.\n"); + /* If the functional Stall condition has been set on an + * asynchronous rx channel, we need to clear the tx channel + * too, since the hardware runs its clean-up sequence on both + * channels, as they are physically one on the network. + * + * The USB interface that exposes the asynchronous channels + * contains always two endpoints, and two only. + */ + if (mdev->conf[channel].data_type == MOST_CH_ASYNC && + mdev->conf[channel].direction == MOST_CH_RX) { + int peer = 1 - channel; + int snd_pipe = usb_sndbulkpipe(mdev->usb_device, + mdev->ep_address[peer]); + usb_clear_halt(mdev->usb_device, snd_pipe); + } mdev->is_channel_healthy[channel] = true; most_resume_enqueue(&mdev->iface, channel); mutex_unlock(&mdev->io_mutex); @@ -840,94 +847,6 @@ static const struct usb_device_id usbid[] = { { } /* Terminating entry */ }; -#define MOST_DCI_RO_ATTR(_name) \ - struct most_dci_attribute most_dci_attr_##_name = \ - __ATTR(_name, 0444, show_value, NULL) - -#define MOST_DCI_ATTR(_name) \ - struct most_dci_attribute most_dci_attr_##_name = \ - __ATTR(_name, 0644, show_value, store_value) - -#define MOST_DCI_WO_ATTR(_name) \ - struct most_dci_attribute most_dci_attr_##_name = \ - __ATTR(_name, 0200, NULL, store_value) - -/** - * struct most_dci_attribute - to access the attributes of a dci object - * @attr: attributes of a dci object - * @show: pointer to the show function - * @store: pointer to the store function - */ -struct most_dci_attribute { - struct attribute attr; - ssize_t (*show)(struct most_dci_obj *d, - struct most_dci_attribute *attr, - char *buf); - ssize_t (*store)(struct most_dci_obj *d, - struct most_dci_attribute *attr, - const char *buf, - size_t count); -}; - -#define to_dci_attr(a) container_of(a, struct most_dci_attribute, attr) - -/** - * dci_attr_show - show function for dci object - * @kobj: pointer to kobject - * @attr: pointer to attribute struct - * @buf: buffer - */ -static ssize_t dci_attr_show(struct kobject *kobj, struct attribute *attr, - char *buf) -{ - struct most_dci_attribute *dci_attr = to_dci_attr(attr); - struct most_dci_obj *dci_obj = to_dci_obj(kobj); - - if (!dci_attr->show) - return -EIO; - - return dci_attr->show(dci_obj, dci_attr, buf); -} - -/** - * dci_attr_store - store function for dci object - * @kobj: pointer to kobject - * @attr: pointer to attribute struct - * @buf: buffer - * @len: length of buffer - */ -static ssize_t dci_attr_store(struct kobject *kobj, - struct attribute *attr, - const char *buf, - size_t len) -{ - struct most_dci_attribute *dci_attr = to_dci_attr(attr); - struct most_dci_obj *dci_obj = to_dci_obj(kobj); - - if (!dci_attr->store) - return -EIO; - - return dci_attr->store(dci_obj, dci_attr, buf, len); -} - -static const struct sysfs_ops most_dci_sysfs_ops = { - .show = dci_attr_show, - .store = dci_attr_store, -}; - -/** - * most_dci_release - release function for dci object - * @kobj: pointer to kobject - * - * This frees the memory allocated for the dci object - */ -static void most_dci_release(struct kobject *kobj) -{ - struct most_dci_obj *dci_obj = to_dci_obj(kobj); - - kfree(dci_obj); -} - struct regs { const char *name; u16 reg; @@ -968,10 +887,11 @@ static int get_stat_reg_addr(const struct regs *regs, int size, #define get_static_reg_addr(regs, name, reg_addr) \ get_stat_reg_addr(regs, ARRAY_SIZE(regs), name, reg_addr) -static ssize_t show_value(struct most_dci_obj *dci_obj, - struct most_dci_attribute *attr, char *buf) +static ssize_t value_show(struct device *dev, struct device_attribute *attr, + char *buf) { const char *name = attr->attr.name; + struct most_dci_obj *dci_obj = to_dci_obj(dev); u16 val; u16 reg_addr; int err; @@ -992,13 +912,13 @@ static ssize_t show_value(struct most_dci_obj *dci_obj, return snprintf(buf, PAGE_SIZE, "%04x\n", val); } -static ssize_t store_value(struct most_dci_obj *dci_obj, - struct most_dci_attribute *attr, +static ssize_t value_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { u16 val; u16 reg_addr; const char *name = attr->attr.name; + struct most_dci_obj *dci_obj = to_dci_obj(dev); struct usb_device *usb_dev = dci_obj->usb_device; int err = kstrtou16(buf, 16, &val); @@ -1025,86 +945,49 @@ static ssize_t store_value(struct most_dci_obj *dci_obj, return count; } -static MOST_DCI_RO_ATTR(ni_state); -static MOST_DCI_RO_ATTR(packet_bandwidth); -static MOST_DCI_RO_ATTR(node_address); -static MOST_DCI_RO_ATTR(node_position); -static MOST_DCI_WO_ATTR(sync_ep); -static MOST_DCI_ATTR(mep_filter); -static MOST_DCI_ATTR(mep_hash0); -static MOST_DCI_ATTR(mep_hash1); -static MOST_DCI_ATTR(mep_hash2); -static MOST_DCI_ATTR(mep_hash3); -static MOST_DCI_ATTR(mep_eui48_hi); -static MOST_DCI_ATTR(mep_eui48_mi); -static MOST_DCI_ATTR(mep_eui48_lo); -static MOST_DCI_ATTR(arb_address); -static MOST_DCI_ATTR(arb_value); - -/** - * most_dci_def_attrs - array of default attribute files of the dci object - */ -static struct attribute *most_dci_def_attrs[] = { - &most_dci_attr_ni_state.attr, - &most_dci_attr_packet_bandwidth.attr, - &most_dci_attr_node_address.attr, - &most_dci_attr_node_position.attr, - &most_dci_attr_sync_ep.attr, - &most_dci_attr_mep_filter.attr, - &most_dci_attr_mep_hash0.attr, - &most_dci_attr_mep_hash1.attr, - &most_dci_attr_mep_hash2.attr, - &most_dci_attr_mep_hash3.attr, - &most_dci_attr_mep_eui48_hi.attr, - &most_dci_attr_mep_eui48_mi.attr, - &most_dci_attr_mep_eui48_lo.attr, - &most_dci_attr_arb_address.attr, - &most_dci_attr_arb_value.attr, +static DEVICE_ATTR(ni_state, 0444, value_show, NULL); +static DEVICE_ATTR(packet_bandwidth, 0444, value_show, NULL); +static DEVICE_ATTR(node_address, 0444, value_show, NULL); +static DEVICE_ATTR(node_position, 0444, value_show, NULL); +static DEVICE_ATTR(sync_ep, 0200, NULL, value_store); +static DEVICE_ATTR(mep_filter, 0644, value_show, value_store); +static DEVICE_ATTR(mep_hash0, 0644, value_show, value_store); +static DEVICE_ATTR(mep_hash1, 0644, value_show, value_store); +static DEVICE_ATTR(mep_hash2, 0644, value_show, value_store); +static DEVICE_ATTR(mep_hash3, 0644, value_show, value_store); +static DEVICE_ATTR(mep_eui48_hi, 0644, value_show, value_store); +static DEVICE_ATTR(mep_eui48_mi, 0644, value_show, value_store); +static DEVICE_ATTR(mep_eui48_lo, 0644, value_show, value_store); +static DEVICE_ATTR(arb_address, 0644, value_show, value_store); +static DEVICE_ATTR(arb_value, 0644, value_show, value_store); + +static struct attribute *dci_attrs[] = { + &dev_attr_ni_state.attr, + &dev_attr_packet_bandwidth.attr, + &dev_attr_node_address.attr, + &dev_attr_node_position.attr, + &dev_attr_sync_ep.attr, + &dev_attr_mep_filter.attr, + &dev_attr_mep_hash0.attr, + &dev_attr_mep_hash1.attr, + &dev_attr_mep_hash2.attr, + &dev_attr_mep_hash3.attr, + &dev_attr_mep_eui48_hi.attr, + &dev_attr_mep_eui48_mi.attr, + &dev_attr_mep_eui48_lo.attr, + &dev_attr_arb_address.attr, + &dev_attr_arb_value.attr, NULL, }; -/** - * DCI ktype - */ -static struct kobj_type most_dci_ktype = { - .sysfs_ops = &most_dci_sysfs_ops, - .release = most_dci_release, - .default_attrs = most_dci_def_attrs, +static struct attribute_group dci_attr_group = { + .attrs = dci_attrs, }; -/** - * create_most_dci_obj - allocates a dci object - * @parent: parent kobject - * - * This creates a dci object and registers it with sysfs. - * Returns a pointer to the object or NULL when something went wrong. - */ -static struct -most_dci_obj *create_most_dci_obj(struct kobject *parent) -{ - struct most_dci_obj *most_dci = kzalloc(sizeof(*most_dci), GFP_KERNEL); - int retval; - - if (!most_dci) - return NULL; - - retval = kobject_init_and_add(&most_dci->kobj, &most_dci_ktype, parent, - "dci"); - if (retval) { - kobject_put(&most_dci->kobj); - return NULL; - } - return most_dci; -} - -/** - * destroy_most_dci_obj - DCI object release function - * @p: pointer to dci object - */ -static void destroy_most_dci_obj(struct most_dci_obj *p) -{ - kobject_put(&p->kobj); -} +static const struct attribute_group *dci_attr_groups[] = { + &dci_attr_group, + NULL, +}; /** * hdm_probe - probe function of USB device driver @@ -1168,8 +1051,6 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id) goto exit_free1; mdev->iface.channel_vector = mdev->cap; - mdev->iface.priv = NULL; - mdev->ep_address = kcalloc(num_endpoints, sizeof(*mdev->ep_address), GFP_KERNEL); if (!mdev->ep_address) @@ -1217,20 +1098,15 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id) usb_dev->config->desc.bConfigurationValue, usb_iface_desc->desc.bInterfaceNumber); - mdev->parent = most_register_interface(&mdev->iface); - if (IS_ERR(mdev->parent)) { - ret = PTR_ERR(mdev->parent); + ret = most_register_interface(&mdev->iface); + if (ret) goto exit_free4; - } mutex_lock(&mdev->io_mutex); if (le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81118 || le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81119 || le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81210) { - /* this increments the reference count of the instance - * object of the core - */ - mdev->dci = create_most_dci_obj(mdev->parent); + mdev->dci = kzalloc(sizeof(*mdev->dci), GFP_KERNEL); if (!mdev->dci) { mutex_unlock(&mdev->io_mutex); most_deregister_interface(&mdev->iface); @@ -1238,12 +1114,21 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id) goto exit_free4; } - kobject_uevent(&mdev->dci->kobj, KOBJ_ADD); + mdev->dci->dev.init_name = "dci"; + mdev->dci->dev.parent = &mdev->iface.dev; + mdev->dci->dev.groups = dci_attr_groups; + if (device_register(&mdev->dci->dev)) { + mutex_unlock(&mdev->io_mutex); + most_deregister_interface(&mdev->iface); + ret = -ENOMEM; + goto exit_free5; + } mdev->dci->usb_device = mdev->usb_device; } mutex_unlock(&mdev->io_mutex); return 0; - +exit_free5: + kfree(mdev->dci); exit_free4: kfree(mdev->busy_urbs); exit_free3: @@ -1283,7 +1168,8 @@ static void hdm_disconnect(struct usb_interface *interface) del_timer_sync(&mdev->link_stat_timer); cancel_work_sync(&mdev->poll_work_obj); - destroy_most_dci_obj(mdev->dci); + device_unregister(&mdev->dci->dev); + kfree(mdev->dci); most_deregister_interface(&mdev->iface); kfree(mdev->busy_urbs); diff --git a/drivers/staging/most/aim-v4l2/Kconfig b/drivers/staging/most/video/Kconfig index d70eaaf0936c..ce6af4f951a6 100644 --- a/drivers/staging/most/aim-v4l2/Kconfig +++ b/drivers/staging/most/video/Kconfig @@ -2,11 +2,11 @@ # MOST V4L2 configuration # -config AIM_V4L2 - tristate "V4L2 AIM" +config MOST_VIDEO + tristate "Video" depends on VIDEO_V4L2 ---help--- Say Y here if you want to commumicate via Video 4 Linux. To compile this driver as a module, choose M here: the - module will be called aim_v4l2.
\ No newline at end of file + module will be called most_video. diff --git a/drivers/staging/most/video/Makefile b/drivers/staging/most/video/Makefile new file mode 100644 index 000000000000..1c8e520e02a2 --- /dev/null +++ b/drivers/staging/most/video/Makefile @@ -0,0 +1,4 @@ +obj-$(CONFIG_MOST_VIDEO) += most_video.o + +most_video-objs := video.o +ccflags-y += -Idrivers/staging/ diff --git a/drivers/staging/most/aim-v4l2/video.c b/drivers/staging/most/video/video.c index 7783bc2dd9f5..ef23e8524b1e 100644 --- a/drivers/staging/most/aim-v4l2/video.c +++ b/drivers/staging/most/video/video.c @@ -1,14 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * V4L2 AIM - V4L2 Application Interface Module for MostCore + * video.c - V4L2 component for Mostcore * * Copyright (C) 2015, Microchip Technology Germany II GmbH & Co. KG - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * This file is licensed under GPLv2. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -27,11 +21,11 @@ #include <media/v4l2-ctrls.h> #include <media/v4l2-fh.h> -#include "mostcore.h" +#include "most/core.h" -#define V4L2_AIM_MAX_INPUT 1 +#define V4L2_CMP_MAX_INPUT 1 -static struct most_aim aim_info; +static struct core_component comp; struct most_video_dev { struct most_interface *iface; @@ -52,7 +46,7 @@ struct most_video_dev { wait_queue_head_t wait_data; }; -struct aim_fh { +struct comp_fh { /* must be the first field of this struct! */ struct v4l2_fh fh; struct most_video_dev *mdev; @@ -72,14 +66,14 @@ static inline struct mbo *get_top_mbo(struct most_video_dev *mdev) return list_first_entry(&mdev->pending_mbos, struct mbo, list); } -static int aim_vdev_open(struct file *filp) +static int comp_vdev_open(struct file *filp) { int ret; struct video_device *vdev = video_devdata(filp); struct most_video_dev *mdev = video_drvdata(filp); - struct aim_fh *fh; + struct comp_fh *fh; - v4l2_info(&mdev->v4l2_dev, "aim_vdev_open()\n"); + v4l2_info(&mdev->v4l2_dev, "comp_vdev_open()\n"); switch (vdev->vfl_type) { case VFL_TYPE_GRABBER: @@ -104,7 +98,7 @@ static int aim_vdev_open(struct file *filp) v4l2_fh_add(&fh->fh); - ret = most_start_channel(mdev->iface, mdev->ch_idx, &aim_info); + ret = most_start_channel(mdev->iface, mdev->ch_idx, &comp); if (ret) { v4l2_err(&mdev->v4l2_dev, "most_start_channel() failed\n"); goto err_rm; @@ -122,13 +116,13 @@ err_dec: return ret; } -static int aim_vdev_close(struct file *filp) +static int comp_vdev_close(struct file *filp) { - struct aim_fh *fh = filp->private_data; + struct comp_fh *fh = filp->private_data; struct most_video_dev *mdev = fh->mdev; struct mbo *mbo, *tmp; - v4l2_info(&mdev->v4l2_dev, "aim_vdev_close()\n"); + v4l2_info(&mdev->v4l2_dev, "comp_vdev_close()\n"); /* * We need to put MBOs back before we call most_stop_channel() @@ -148,7 +142,7 @@ static int aim_vdev_close(struct file *filp) spin_lock_irq(&mdev->list_lock); } spin_unlock_irq(&mdev->list_lock); - most_stop_channel(mdev->iface, mdev->ch_idx, &aim_info); + most_stop_channel(mdev->iface, mdev->ch_idx, &comp); mdev->mute = false; v4l2_fh_del(&fh->fh); @@ -159,10 +153,10 @@ static int aim_vdev_close(struct file *filp) return 0; } -static ssize_t aim_vdev_read(struct file *filp, char __user *buf, - size_t count, loff_t *pos) +static ssize_t comp_vdev_read(struct file *filp, char __user *buf, + size_t count, loff_t *pos) { - struct aim_fh *fh = filp->private_data; + struct comp_fh *fh = filp->private_data; struct most_video_dev *mdev = fh->mdev; int ret = 0; @@ -209,9 +203,9 @@ static ssize_t aim_vdev_read(struct file *filp, char __user *buf, return ret; } -static __poll_t aim_vdev_poll(struct file *filp, poll_table *wait) +static __poll_t comp_vdev_poll(struct file *filp, poll_table *wait) { - struct aim_fh *fh = filp->private_data; + struct comp_fh *fh = filp->private_data; struct most_video_dev *mdev = fh->mdev; __poll_t mask = 0; @@ -224,7 +218,7 @@ static __poll_t aim_vdev_poll(struct file *filp, poll_table *wait) return mask; } -static void aim_set_format_struct(struct v4l2_format *f) +static void comp_set_format_struct(struct v4l2_format *f) { f->fmt.pix.width = 8; f->fmt.pix.height = 8; @@ -236,8 +230,8 @@ static void aim_set_format_struct(struct v4l2_format *f) f->fmt.pix.priv = 0; } -static int aim_set_format(struct most_video_dev *mdev, unsigned int cmd, - struct v4l2_format *format) +static int comp_set_format(struct most_video_dev *mdev, unsigned int cmd, + struct v4l2_format *format) { if (format->fmt.pix.pixelformat != V4L2_PIX_FMT_MPEG) return -EINVAL; @@ -245,7 +239,7 @@ static int aim_set_format(struct most_video_dev *mdev, unsigned int cmd, if (cmd == VIDIOC_TRY_FMT) return 0; - aim_set_format_struct(format); + comp_set_format_struct(format); return 0; } @@ -253,12 +247,12 @@ static int aim_set_format(struct most_video_dev *mdev, unsigned int cmd, static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { - struct aim_fh *fh = priv; + struct comp_fh *fh = priv; struct most_video_dev *mdev = fh->mdev; v4l2_info(&mdev->v4l2_dev, "vidioc_querycap()\n"); - strlcpy(cap->driver, "v4l2_most_aim", sizeof(cap->driver)); + strlcpy(cap->driver, "v4l2_component", sizeof(cap->driver)); strlcpy(cap->card, "MOST", sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "%s", mdev->iface->description); @@ -273,7 +267,7 @@ static int vidioc_querycap(struct file *file, void *priv, static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { - struct aim_fh *fh = priv; + struct comp_fh *fh = priv; struct most_video_dev *mdev = fh->mdev; v4l2_info(&mdev->v4l2_dev, "vidioc_enum_fmt_vid_cap() %d\n", f->index); @@ -292,36 +286,36 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct aim_fh *fh = priv; + struct comp_fh *fh = priv; struct most_video_dev *mdev = fh->mdev; v4l2_info(&mdev->v4l2_dev, "vidioc_g_fmt_vid_cap()\n"); - aim_set_format_struct(f); + comp_set_format_struct(f); return 0; } static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct aim_fh *fh = priv; + struct comp_fh *fh = priv; struct most_video_dev *mdev = fh->mdev; - return aim_set_format(mdev, VIDIOC_TRY_FMT, f); + return comp_set_format(mdev, VIDIOC_TRY_FMT, f); } static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct aim_fh *fh = priv; + struct comp_fh *fh = priv; struct most_video_dev *mdev = fh->mdev; - return aim_set_format(mdev, VIDIOC_S_FMT, f); + return comp_set_format(mdev, VIDIOC_S_FMT, f); } static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm) { - struct aim_fh *fh = priv; + struct comp_fh *fh = priv; struct most_video_dev *mdev = fh->mdev; v4l2_info(&mdev->v4l2_dev, "vidioc_g_std()\n"); @@ -333,10 +327,10 @@ static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm) static int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *input) { - struct aim_fh *fh = priv; + struct comp_fh *fh = priv; struct most_video_dev *mdev = fh->mdev; - if (input->index >= V4L2_AIM_MAX_INPUT) + if (input->index >= V4L2_CMP_MAX_INPUT) return -EINVAL; strcpy(input->name, "MOST Video"); @@ -350,7 +344,7 @@ static int vidioc_enum_input(struct file *file, void *priv, static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) { - struct aim_fh *fh = priv; + struct comp_fh *fh = priv; struct most_video_dev *mdev = fh->mdev; *i = mdev->ctrl_input; return 0; @@ -358,23 +352,23 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) static int vidioc_s_input(struct file *file, void *priv, unsigned int index) { - struct aim_fh *fh = priv; + struct comp_fh *fh = priv; struct most_video_dev *mdev = fh->mdev; v4l2_info(&mdev->v4l2_dev, "vidioc_s_input(%d)\n", index); - if (index >= V4L2_AIM_MAX_INPUT) + if (index >= V4L2_CMP_MAX_INPUT) return -EINVAL; mdev->ctrl_input = index; return 0; } -static const struct v4l2_file_operations aim_fops = { +static const struct v4l2_file_operations comp_fops = { .owner = THIS_MODULE, - .open = aim_vdev_open, - .release = aim_vdev_close, - .read = aim_vdev_read, - .poll = aim_vdev_poll, + .open = comp_vdev_open, + .release = comp_vdev_close, + .read = comp_vdev_read, + .poll = comp_vdev_poll, .unlocked_ioctl = video_ioctl2, }; @@ -390,8 +384,8 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_s_input = vidioc_s_input, }; -static const struct video_device aim_videodev_template = { - .fops = &aim_fops, +static const struct video_device comp_videodev_template = { + .fops = &comp_fops, .release = video_device_release, .ioctl_ops = &video_ioctl_ops, .tvnorms = V4L2_STD_UNKNOWN, @@ -399,7 +393,7 @@ static const struct video_device aim_videodev_template = { /**************************************************************************/ -static struct most_video_dev *get_aim_dev( +static struct most_video_dev *get_comp_dev( struct most_interface *iface, int channel_idx) { struct most_video_dev *mdev; @@ -416,11 +410,11 @@ static struct most_video_dev *get_aim_dev( return NULL; } -static int aim_rx_data(struct mbo *mbo) +static int comp_rx_data(struct mbo *mbo) { unsigned long flags; struct most_video_dev *mdev = - get_aim_dev(mbo->ifp, mbo->hdm_channel_id); + get_comp_dev(mbo->ifp, mbo->hdm_channel_id); if (!mdev) return -EIO; @@ -437,11 +431,11 @@ static int aim_rx_data(struct mbo *mbo) return 0; } -static int aim_register_videodev(struct most_video_dev *mdev) +static int comp_register_videodev(struct most_video_dev *mdev) { int ret; - v4l2_info(&mdev->v4l2_dev, "aim_register_videodev()\n"); + v4l2_info(&mdev->v4l2_dev, "comp_register_videodev()\n"); init_waitqueue_head(&mdev->wait_data); @@ -451,7 +445,7 @@ static int aim_register_videodev(struct most_video_dev *mdev) return -ENOMEM; /* Fill the video capture device struct */ - *mdev->vdev = aim_videodev_template; + *mdev->vdev = comp_videodev_template; mdev->vdev->v4l2_dev = &mdev->v4l2_dev; mdev->vdev->lock = &mdev->lock; snprintf(mdev->vdev->name, sizeof(mdev->vdev->name), "MOST: %s", @@ -469,14 +463,14 @@ static int aim_register_videodev(struct most_video_dev *mdev) return ret; } -static void aim_unregister_videodev(struct most_video_dev *mdev) +static void comp_unregister_videodev(struct most_video_dev *mdev) { - v4l2_info(&mdev->v4l2_dev, "aim_unregister_videodev()\n"); + v4l2_info(&mdev->v4l2_dev, "comp_unregister_videodev()\n"); video_unregister_device(mdev->vdev); } -static void aim_v4l2_dev_release(struct v4l2_device *v4l2_dev) +static void comp_v4l2_dev_release(struct v4l2_device *v4l2_dev) { struct most_video_dev *mdev = container_of(v4l2_dev, struct most_video_dev, v4l2_dev); @@ -485,14 +479,13 @@ static void aim_v4l2_dev_release(struct v4l2_device *v4l2_dev) kfree(mdev); } -static int aim_probe_channel(struct most_interface *iface, int channel_idx, - struct most_channel_config *ccfg, - struct kobject *parent, char *name) +static int comp_probe_channel(struct most_interface *iface, int channel_idx, + struct most_channel_config *ccfg, char *name) { int ret; - struct most_video_dev *mdev = get_aim_dev(iface, channel_idx); + struct most_video_dev *mdev = get_comp_dev(iface, channel_idx); - pr_info("aim_probe_channel(%s)\n", name); + pr_info("comp_probe_channel(%s)\n", name); if (mdev) { pr_err("channel already linked\n"); @@ -520,7 +513,7 @@ static int aim_probe_channel(struct most_interface *iface, int channel_idx, INIT_LIST_HEAD(&mdev->pending_mbos); mdev->iface = iface; mdev->ch_idx = channel_idx; - mdev->v4l2_dev.release = aim_v4l2_dev_release; + mdev->v4l2_dev.release = comp_v4l2_dev_release; /* Create the v4l2_device */ strlcpy(mdev->v4l2_dev.name, name, sizeof(mdev->v4l2_dev.name)); @@ -531,14 +524,14 @@ static int aim_probe_channel(struct most_interface *iface, int channel_idx, return ret; } - ret = aim_register_videodev(mdev); + ret = comp_register_videodev(mdev); if (ret) goto err_unreg; spin_lock_irq(&list_lock); list_add(&mdev->list, &video_devices); spin_unlock_irq(&list_lock); - v4l2_info(&mdev->v4l2_dev, "aim_probe_channel() done\n"); + v4l2_info(&mdev->v4l2_dev, "comp_probe_channel() done\n"); return 0; err_unreg: @@ -547,48 +540,48 @@ err_unreg: return ret; } -static int aim_disconnect_channel(struct most_interface *iface, - int channel_idx) +static int comp_disconnect_channel(struct most_interface *iface, + int channel_idx) { - struct most_video_dev *mdev = get_aim_dev(iface, channel_idx); + struct most_video_dev *mdev = get_comp_dev(iface, channel_idx); if (!mdev) { pr_err("no such channel is linked\n"); return -ENOENT; } - v4l2_info(&mdev->v4l2_dev, "aim_disconnect_channel()\n"); + v4l2_info(&mdev->v4l2_dev, "comp_disconnect_channel()\n"); spin_lock_irq(&list_lock); list_del(&mdev->list); spin_unlock_irq(&list_lock); - aim_unregister_videodev(mdev); + comp_unregister_videodev(mdev); v4l2_device_disconnect(&mdev->v4l2_dev); v4l2_device_put(&mdev->v4l2_dev); return 0; } -static struct most_aim aim_info = { - .name = "v4l", - .probe_channel = aim_probe_channel, - .disconnect_channel = aim_disconnect_channel, - .rx_completion = aim_rx_data, +static struct core_component comp_info = { + .name = "video", + .probe_channel = comp_probe_channel, + .disconnect_channel = comp_disconnect_channel, + .rx_completion = comp_rx_data, }; -static int __init aim_init(void) +static int __init comp_init(void) { spin_lock_init(&list_lock); - return most_register_aim(&aim_info); + return most_register_component(&comp); } -static void __exit aim_exit(void) +static void __exit comp_exit(void) { struct most_video_dev *mdev, *tmp; /* * As the mostcore currently doesn't call disconnect_channel() - * for linked channels while we call most_deregister_aim() + * for linked channels while we call most_deregister_component() * we simulate this call here. * This must be fixed in core. */ @@ -597,20 +590,20 @@ static void __exit aim_exit(void) list_del(&mdev->list); spin_unlock_irq(&list_lock); - aim_unregister_videodev(mdev); + comp_unregister_videodev(mdev); v4l2_device_disconnect(&mdev->v4l2_dev); v4l2_device_put(&mdev->v4l2_dev); spin_lock_irq(&list_lock); } spin_unlock_irq(&list_lock); - most_deregister_aim(&aim_info); + most_deregister_component(&comp_info); BUG_ON(!list_empty(&video_devices)); } -module_init(aim_init); -module_exit(aim_exit); +module_init(comp_init); +module_exit(comp_exit); -MODULE_DESCRIPTION("V4L2 Application Interface Module for MostCore"); +MODULE_DESCRIPTION("V4L2 Component Module for Mostcore"); MODULE_AUTHOR("Andrey Shvetsov <andrey.shvetsov@k2l.de>"); MODULE_LICENSE("GPL"); diff --git a/drivers/staging/ncpfs/Kconfig b/drivers/staging/ncpfs/Kconfig new file mode 100644 index 000000000000..c931cf22a1f6 --- /dev/null +++ b/drivers/staging/ncpfs/Kconfig @@ -0,0 +1,108 @@ +# +# NCP Filesystem configuration +# +config NCP_FS + tristate "NCP file system support (to mount NetWare volumes)" + depends on IPX!=n || INET + help + NCP (NetWare Core Protocol) is a protocol that runs over IPX and is + used by Novell NetWare clients to talk to file servers. It is to + IPX what NFS is to TCP/IP, if that helps. Saying Y here allows you + to mount NetWare file server volumes and to access them just like + any other Unix directory. For details, please read the file + <file:Documentation/filesystems/ncpfs.txt> in the kernel source and + the IPX-HOWTO from <http://www.tldp.org/docs.html#howto>. + + You do not have to say Y here if you want your Linux box to act as a + file *server* for Novell NetWare clients. + + General information about how to connect Linux, Windows machines and + Macs is on the WWW at <http://www.eats.com/linux_mac_win.html>. + + To compile this as a module, choose M here: the module will be called + ncpfs. Say N unless you are connected to a Novell network. + +config NCPFS_PACKET_SIGNING + bool "Packet signatures" + depends on NCP_FS + help + NCP allows packets to be signed for stronger security. If you want + security, say Y. Normal users can leave it off. To be able to use + packet signing you must use ncpfs > 2.0.12. + +config NCPFS_IOCTL_LOCKING + bool "Proprietary file locking" + depends on NCP_FS + help + Allows locking of records on remote volumes. Say N unless you have + special applications which are able to utilize this locking scheme. + +config NCPFS_STRONG + bool "Clear remove/delete inhibit when needed" + depends on NCP_FS + help + Allows manipulation of files flagged as Delete or Rename Inhibit. + To use this feature you must mount volumes with the ncpmount + parameter "-s" (ncpfs-2.0.12 and newer). Say Y unless you are not + mounting volumes with -f 444. + +config NCPFS_NFS_NS + bool "Use NFS namespace if available" + depends on NCP_FS + help + Allows you to utilize NFS namespace on NetWare servers. It brings + you case sensitive filenames. Say Y. You can disable it at + mount-time with the `-N nfs' parameter of ncpmount. + +config NCPFS_OS2_NS + bool "Use LONG (OS/2) namespace if available" + depends on NCP_FS + help + Allows you to utilize OS2/LONG namespace on NetWare servers. + Filenames in this namespace are limited to 255 characters, they are + case insensitive, and case in names is preserved. Say Y. You can + disable it at mount time with the -N os2 parameter of ncpmount. + +config NCPFS_SMALLDOS + bool "Lowercase DOS filenames" + depends on NCP_FS + ---help--- + If you say Y here, every filename on a NetWare server volume using + the OS2/LONG namespace and created under DOS or on a volume using + DOS namespace will be converted to lowercase characters. + Saying N here will give you these filenames in uppercase. + + This is only a cosmetic option since the OS2/LONG namespace is case + insensitive. The only major reason for this option is backward + compatibility when moving from DOS to OS2/LONG namespace support. + Long filenames (created by Win95) will not be affected. + + This option does not solve the problem that filenames appear + differently under Linux and under Windows, since Windows does an + additional conversions on the client side. You can achieve similar + effects by saying Y to "Allow using of Native Language Support" + below. + +config NCPFS_NLS + bool "Use Native Language Support" + depends on NCP_FS + select NLS + help + Allows you to use codepages and I/O charsets for file name + translation between the server file system and input/output. This + may be useful, if you want to access the server with other operating + systems, e.g. Windows 95. See also NLS for more Information. + + To select codepages and I/O charsets use ncpfs-2.2.0.13 or newer. + +config NCPFS_EXTRAS + bool "Enable symbolic links and execute flags" + depends on NCP_FS + help + This enables the use of symbolic links and an execute permission + bit on NCPFS. The file server need not have long name space or NFS + name space loaded for these to work. + + To use the new attributes, it is recommended to use the flags + '-f 600 -d 755' on the ncpmount command line. + diff --git a/drivers/staging/ncpfs/Makefile b/drivers/staging/ncpfs/Makefile new file mode 100644 index 000000000000..66fe5f878817 --- /dev/null +++ b/drivers/staging/ncpfs/Makefile @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Makefile for the linux ncp filesystem routines. +# + +obj-$(CONFIG_NCP_FS) += ncpfs.o + +ncpfs-y := dir.o file.o inode.o ioctl.o mmap.o ncplib_kernel.o sock.o \ + ncpsign_kernel.o getopt.o + +ncpfs-$(CONFIG_NCPFS_EXTRAS) += symlink.o +ncpfs-$(CONFIG_NCPFS_NFS_NS) += symlink.o + +# If you want debugging output, please uncomment the following line +# ccflags-y := -DDEBUG_NCP=1 + +CFLAGS_ncplib_kernel.o := -finline-functions diff --git a/drivers/staging/ncpfs/TODO b/drivers/staging/ncpfs/TODO new file mode 100644 index 000000000000..9b6d38b7e248 --- /dev/null +++ b/drivers/staging/ncpfs/TODO @@ -0,0 +1,4 @@ +The ncpfs code will be removed soon from the kernel tree as it is old and +obsolete and broken. + +Don't worry about fixing up anything here, it's not needed. diff --git a/drivers/staging/ncpfs/dir.c b/drivers/staging/ncpfs/dir.c new file mode 100644 index 000000000000..0c57c5c5d40a --- /dev/null +++ b/drivers/staging/ncpfs/dir.c @@ -0,0 +1,1232 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dir.c + * + * Copyright (C) 1995, 1996 by Volker Lendecke + * Modified for big endian by J.F. Chadima and David S. Miller + * Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache + * Modified 1998, 1999 Wolfram Pienkoss for NLS + * Modified 1999 Wolfram Pienkoss for directory caching + * Modified 2000 Ben Harris, University of Cambridge for NFS NS meta-info + * + */ + + +#include <linux/time.h> +#include <linux/errno.h> +#include <linux/stat.h> +#include <linux/kernel.h> +#include <linux/vmalloc.h> +#include <linux/mm.h> +#include <linux/namei.h> +#include <linux/uaccess.h> +#include <asm/byteorder.h> + +#include "ncp_fs.h" + +static void ncp_read_volume_list(struct file *, struct dir_context *, + struct ncp_cache_control *); +static void ncp_do_readdir(struct file *, struct dir_context *, + struct ncp_cache_control *); + +static int ncp_readdir(struct file *, struct dir_context *); + +static int ncp_create(struct inode *, struct dentry *, umode_t, bool); +static struct dentry *ncp_lookup(struct inode *, struct dentry *, unsigned int); +static int ncp_unlink(struct inode *, struct dentry *); +static int ncp_mkdir(struct inode *, struct dentry *, umode_t); +static int ncp_rmdir(struct inode *, struct dentry *); +static int ncp_rename(struct inode *, struct dentry *, + struct inode *, struct dentry *, unsigned int); +static int ncp_mknod(struct inode * dir, struct dentry *dentry, + umode_t mode, dev_t rdev); +#if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS) +extern int ncp_symlink(struct inode *, struct dentry *, const char *); +#else +#define ncp_symlink NULL +#endif + +const struct file_operations ncp_dir_operations = +{ + .llseek = generic_file_llseek, + .read = generic_read_dir, + .iterate = ncp_readdir, + .unlocked_ioctl = ncp_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ncp_compat_ioctl, +#endif +}; + +const struct inode_operations ncp_dir_inode_operations = +{ + .create = ncp_create, + .lookup = ncp_lookup, + .unlink = ncp_unlink, + .symlink = ncp_symlink, + .mkdir = ncp_mkdir, + .rmdir = ncp_rmdir, + .mknod = ncp_mknod, + .rename = ncp_rename, + .setattr = ncp_notify_change, +}; + +/* + * Dentry operations routines + */ +static int ncp_lookup_validate(struct dentry *, unsigned int); +static int ncp_hash_dentry(const struct dentry *, struct qstr *); +static int ncp_compare_dentry(const struct dentry *, + unsigned int, const char *, const struct qstr *); +static int ncp_delete_dentry(const struct dentry *); +static void ncp_d_prune(struct dentry *dentry); + +const struct dentry_operations ncp_dentry_operations = +{ + .d_revalidate = ncp_lookup_validate, + .d_hash = ncp_hash_dentry, + .d_compare = ncp_compare_dentry, + .d_delete = ncp_delete_dentry, + .d_prune = ncp_d_prune, +}; + +#define ncp_namespace(i) (NCP_SERVER(i)->name_space[NCP_FINFO(i)->volNumber]) + +static inline int ncp_preserve_entry_case(struct inode *i, __u32 nscreator) +{ +#ifdef CONFIG_NCPFS_SMALLDOS + int ns = ncp_namespace(i); + + if ((ns == NW_NS_DOS) +#ifdef CONFIG_NCPFS_OS2_NS + || ((ns == NW_NS_OS2) && (nscreator == NW_NS_DOS)) +#endif /* CONFIG_NCPFS_OS2_NS */ + ) + return 0; +#endif /* CONFIG_NCPFS_SMALLDOS */ + return 1; +} + +#define ncp_preserve_case(i) (ncp_namespace(i) != NW_NS_DOS) + +static inline int ncp_case_sensitive(const struct inode *i) +{ +#ifdef CONFIG_NCPFS_NFS_NS + return ncp_namespace(i) == NW_NS_NFS; +#else + return 0; +#endif /* CONFIG_NCPFS_NFS_NS */ +} + +/* + * Note: leave the hash unchanged if the directory + * is case-sensitive. + */ +static int +ncp_hash_dentry(const struct dentry *dentry, struct qstr *this) +{ + struct inode *inode = d_inode_rcu(dentry); + + if (!inode) + return 0; + + if (!ncp_case_sensitive(inode)) { + struct nls_table *t; + unsigned long hash; + int i; + + t = NCP_IO_TABLE(dentry->d_sb); + hash = init_name_hash(dentry); + for (i=0; i<this->len ; i++) + hash = partial_name_hash(ncp_tolower(t, this->name[i]), + hash); + this->hash = end_name_hash(hash); + } + return 0; +} + +static int +ncp_compare_dentry(const struct dentry *dentry, + unsigned int len, const char *str, const struct qstr *name) +{ + struct inode *pinode; + + if (len != name->len) + return 1; + + pinode = d_inode_rcu(dentry->d_parent); + if (!pinode) + return 1; + + if (ncp_case_sensitive(pinode)) + return strncmp(str, name->name, len); + + return ncp_strnicmp(NCP_IO_TABLE(pinode->i_sb), str, name->name, len); +} + +/* + * This is the callback from dput() when d_count is going to 0. + * We use this to unhash dentries with bad inodes. + * Closing files can be safely postponed until iput() - it's done there anyway. + */ +static int +ncp_delete_dentry(const struct dentry * dentry) +{ + struct inode *inode = d_inode(dentry); + + if (inode) { + if (is_bad_inode(inode)) + return 1; + } else + { + /* N.B. Unhash negative dentries? */ + } + return 0; +} + +static inline int +ncp_single_volume(struct ncp_server *server) +{ + return (server->m.mounted_vol[0] != '\0'); +} + +static inline int ncp_is_server_root(struct inode *inode) +{ + return !ncp_single_volume(NCP_SERVER(inode)) && + is_root_inode(inode); +} + + +/* + * This is the callback when the dcache has a lookup hit. + */ + + +#ifdef CONFIG_NCPFS_STRONG +/* try to delete a readonly file (NW R bit set) */ + +static int +ncp_force_unlink(struct inode *dir, struct dentry* dentry) +{ + int res=0x9c,res2; + struct nw_modify_dos_info info; + __le32 old_nwattr; + struct inode *inode; + + memset(&info, 0, sizeof(info)); + + /* remove the Read-Only flag on the NW server */ + inode = d_inode(dentry); + + old_nwattr = NCP_FINFO(inode)->nwattr; + info.attributes = old_nwattr & ~(aRONLY|aDELETEINHIBIT|aRENAMEINHIBIT); + res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(inode), inode, NULL, DM_ATTRIBUTES, &info); + if (res2) + goto leave_me; + + /* now try again the delete operation */ + res = ncp_del_file_or_subdir2(NCP_SERVER(dir), dentry); + + if (res) /* delete failed, set R bit again */ + { + info.attributes = old_nwattr; + res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(inode), inode, NULL, DM_ATTRIBUTES, &info); + if (res2) + goto leave_me; + } +leave_me: + return(res); +} +#endif /* CONFIG_NCPFS_STRONG */ + +#ifdef CONFIG_NCPFS_STRONG +static int +ncp_force_rename(struct inode *old_dir, struct dentry* old_dentry, char *_old_name, + struct inode *new_dir, struct dentry* new_dentry, char *_new_name) +{ + struct nw_modify_dos_info info; + int res=0x90,res2; + struct inode *old_inode = d_inode(old_dentry); + __le32 old_nwattr = NCP_FINFO(old_inode)->nwattr; + __le32 new_nwattr = 0; /* shut compiler warning */ + int old_nwattr_changed = 0; + int new_nwattr_changed = 0; + + memset(&info, 0, sizeof(info)); + + /* remove the Read-Only flag on the NW server */ + + info.attributes = old_nwattr & ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT); + res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(old_inode), old_inode, NULL, DM_ATTRIBUTES, &info); + if (!res2) + old_nwattr_changed = 1; + if (new_dentry && d_really_is_positive(new_dentry)) { + new_nwattr = NCP_FINFO(d_inode(new_dentry))->nwattr; + info.attributes = new_nwattr & ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT); + res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(new_dir), new_dir, _new_name, DM_ATTRIBUTES, &info); + if (!res2) + new_nwattr_changed = 1; + } + /* now try again the rename operation */ + /* but only if something really happened */ + if (new_nwattr_changed || old_nwattr_changed) { + res = ncp_ren_or_mov_file_or_subdir(NCP_SERVER(old_dir), + old_dir, _old_name, + new_dir, _new_name); + } + if (res) + goto leave_me; + /* file was successfully renamed, so: + do not set attributes on old file - it no longer exists + copy attributes from old file to new */ + new_nwattr_changed = old_nwattr_changed; + new_nwattr = old_nwattr; + old_nwattr_changed = 0; + +leave_me:; + if (old_nwattr_changed) { + info.attributes = old_nwattr; + res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(old_inode), old_inode, NULL, DM_ATTRIBUTES, &info); + /* ignore errors */ + } + if (new_nwattr_changed) { + info.attributes = new_nwattr; + res2 = ncp_modify_file_or_subdir_dos_info_path(NCP_SERVER(new_dir), new_dir, _new_name, DM_ATTRIBUTES, &info); + /* ignore errors */ + } + return(res); +} +#endif /* CONFIG_NCPFS_STRONG */ + + +static int +ncp_lookup_validate(struct dentry *dentry, unsigned int flags) +{ + struct ncp_server *server; + struct dentry *parent; + struct inode *dir; + struct ncp_entry_info finfo; + int res, val = 0, len; + __u8 __name[NCP_MAXPATHLEN + 1]; + + if (dentry == dentry->d_sb->s_root) + return 1; + + if (flags & LOOKUP_RCU) + return -ECHILD; + + parent = dget_parent(dentry); + dir = d_inode(parent); + + if (d_really_is_negative(dentry)) + goto finished; + + server = NCP_SERVER(dir); + + /* + * Inspired by smbfs: + * The default validation is based on dentry age: + * We set the max age at mount time. (But each + * successful server lookup renews the timestamp.) + */ + val = NCP_TEST_AGE(server, dentry); + if (val) + goto finished; + + ncp_dbg(2, "%pd2 not valid, age=%ld, server lookup\n", + dentry, NCP_GET_AGE(dentry)); + + len = sizeof(__name); + if (ncp_is_server_root(dir)) { + res = ncp_io2vol(server, __name, &len, dentry->d_name.name, + dentry->d_name.len, 1); + if (!res) { + res = ncp_lookup_volume(server, __name, &(finfo.i)); + if (!res) + ncp_update_known_namespace(server, finfo.i.volNumber, NULL); + } + } else { + res = ncp_io2vol(server, __name, &len, dentry->d_name.name, + dentry->d_name.len, !ncp_preserve_case(dir)); + if (!res) + res = ncp_obtain_info(server, dir, __name, &(finfo.i)); + } + finfo.volume = finfo.i.volNumber; + ncp_dbg(2, "looked for %pd/%s, res=%d\n", + dentry->d_parent, __name, res); + /* + * If we didn't find it, or if it has a different dirEntNum to + * what we remember, it's not valid any more. + */ + if (!res) { + struct inode *inode = d_inode(dentry); + + inode_lock(inode); + if (finfo.i.dirEntNum == NCP_FINFO(inode)->dirEntNum) { + ncp_new_dentry(dentry); + val=1; + } else + ncp_dbg(2, "found, but dirEntNum changed\n"); + + ncp_update_inode2(inode, &finfo); + inode_unlock(inode); + } + +finished: + ncp_dbg(2, "result=%d\n", val); + dput(parent); + return val; +} + +static time_t ncp_obtain_mtime(struct dentry *dentry) +{ + struct inode *inode = d_inode(dentry); + struct ncp_server *server = NCP_SERVER(inode); + struct nw_info_struct i; + + if (!ncp_conn_valid(server) || ncp_is_server_root(inode)) + return 0; + + if (ncp_obtain_info(server, inode, NULL, &i)) + return 0; + + return ncp_date_dos2unix(i.modifyTime, i.modifyDate); +} + +static inline void +ncp_invalidate_dircache_entries(struct dentry *parent) +{ + struct ncp_server *server = NCP_SERVER(d_inode(parent)); + struct dentry *dentry; + + spin_lock(&parent->d_lock); + list_for_each_entry(dentry, &parent->d_subdirs, d_child) { + dentry->d_fsdata = NULL; + ncp_age_dentry(server, dentry); + } + spin_unlock(&parent->d_lock); +} + +static int ncp_readdir(struct file *file, struct dir_context *ctx) +{ + struct dentry *dentry = file->f_path.dentry; + struct inode *inode = d_inode(dentry); + struct page *page = NULL; + struct ncp_server *server = NCP_SERVER(inode); + union ncp_dir_cache *cache = NULL; + struct ncp_cache_control ctl; + int result, mtime_valid = 0; + time_t mtime = 0; + + ctl.page = NULL; + ctl.cache = NULL; + + ncp_dbg(2, "reading %pD2, pos=%d\n", file, (int)ctx->pos); + + result = -EIO; + /* Do not generate '.' and '..' when server is dead. */ + if (!ncp_conn_valid(server)) + goto out; + + result = 0; + if (!dir_emit_dots(file, ctx)) + goto out; + + page = grab_cache_page(&inode->i_data, 0); + if (!page) + goto read_really; + + ctl.cache = cache = kmap(page); + ctl.head = cache->head; + + if (!PageUptodate(page) || !ctl.head.eof) + goto init_cache; + + if (ctx->pos == 2) { + if (jiffies - ctl.head.time >= NCP_MAX_AGE(server)) + goto init_cache; + + mtime = ncp_obtain_mtime(dentry); + mtime_valid = 1; + if ((!mtime) || (mtime != ctl.head.mtime)) + goto init_cache; + } + + if (ctx->pos > ctl.head.end) + goto finished; + + ctl.fpos = ctx->pos + (NCP_DIRCACHE_START - 2); + ctl.ofs = ctl.fpos / NCP_DIRCACHE_SIZE; + ctl.idx = ctl.fpos % NCP_DIRCACHE_SIZE; + + for (;;) { + if (ctl.ofs != 0) { + ctl.page = find_lock_page(&inode->i_data, ctl.ofs); + if (!ctl.page) + goto invalid_cache; + ctl.cache = kmap(ctl.page); + if (!PageUptodate(ctl.page)) + goto invalid_cache; + } + while (ctl.idx < NCP_DIRCACHE_SIZE) { + struct dentry *dent; + bool over; + + spin_lock(&dentry->d_lock); + if (!(NCP_FINFO(inode)->flags & NCPI_DIR_CACHE)) { + spin_unlock(&dentry->d_lock); + goto invalid_cache; + } + dent = ctl.cache->dentry[ctl.idx]; + if (unlikely(!lockref_get_not_dead(&dent->d_lockref))) { + spin_unlock(&dentry->d_lock); + goto invalid_cache; + } + spin_unlock(&dentry->d_lock); + if (d_really_is_negative(dent)) { + dput(dent); + goto invalid_cache; + } + over = !dir_emit(ctx, dent->d_name.name, + dent->d_name.len, + d_inode(dent)->i_ino, DT_UNKNOWN); + dput(dent); + if (over) + goto finished; + ctx->pos += 1; + ctl.idx += 1; + if (ctx->pos > ctl.head.end) + goto finished; + } + if (ctl.page) { + kunmap(ctl.page); + SetPageUptodate(ctl.page); + unlock_page(ctl.page); + put_page(ctl.page); + ctl.page = NULL; + } + ctl.idx = 0; + ctl.ofs += 1; + } +invalid_cache: + if (ctl.page) { + kunmap(ctl.page); + unlock_page(ctl.page); + put_page(ctl.page); + ctl.page = NULL; + } + ctl.cache = cache; +init_cache: + ncp_invalidate_dircache_entries(dentry); + if (!mtime_valid) { + mtime = ncp_obtain_mtime(dentry); + mtime_valid = 1; + } + ctl.head.mtime = mtime; + ctl.head.time = jiffies; + ctl.head.eof = 0; + ctl.fpos = 2; + ctl.ofs = 0; + ctl.idx = NCP_DIRCACHE_START; + ctl.filled = 0; + ctl.valid = 1; +read_really: + spin_lock(&dentry->d_lock); + NCP_FINFO(inode)->flags |= NCPI_DIR_CACHE; + spin_unlock(&dentry->d_lock); + if (ncp_is_server_root(inode)) { + ncp_read_volume_list(file, ctx, &ctl); + } else { + ncp_do_readdir(file, ctx, &ctl); + } + ctl.head.end = ctl.fpos - 1; + ctl.head.eof = ctl.valid; +finished: + if (ctl.page) { + kunmap(ctl.page); + SetPageUptodate(ctl.page); + unlock_page(ctl.page); + put_page(ctl.page); + } + if (page) { + cache->head = ctl.head; + kunmap(page); + SetPageUptodate(page); + unlock_page(page); + put_page(page); + } +out: + return result; +} + +static void ncp_d_prune(struct dentry *dentry) +{ + if (!dentry->d_fsdata) /* not referenced from page cache */ + return; + NCP_FINFO(d_inode(dentry->d_parent))->flags &= ~NCPI_DIR_CACHE; +} + +static int +ncp_fill_cache(struct file *file, struct dir_context *ctx, + struct ncp_cache_control *ctrl, struct ncp_entry_info *entry, + int inval_childs) +{ + struct dentry *newdent, *dentry = file->f_path.dentry; + struct inode *dir = d_inode(dentry); + struct ncp_cache_control ctl = *ctrl; + struct qstr qname; + int valid = 0; + int hashed = 0; + ino_t ino = 0; + __u8 __name[NCP_MAXPATHLEN + 1]; + + qname.len = sizeof(__name); + if (ncp_vol2io(NCP_SERVER(dir), __name, &qname.len, + entry->i.entryName, entry->i.nameLen, + !ncp_preserve_entry_case(dir, entry->i.NSCreator))) + return 1; /* I'm not sure */ + + qname.name = __name; + + newdent = d_hash_and_lookup(dentry, &qname); + if (IS_ERR(newdent)) + goto end_advance; + if (!newdent) { + newdent = d_alloc(dentry, &qname); + if (!newdent) + goto end_advance; + } else { + hashed = 1; + + /* If case sensitivity changed for this volume, all entries below this one + should be thrown away. This entry itself is not affected, as its case + sensitivity is controlled by its own parent. */ + if (inval_childs) + shrink_dcache_parent(newdent); + + /* + * NetWare's OS2 namespace is case preserving yet case + * insensitive. So we update dentry's name as received from + * server. Parent dir's i_mutex is locked because we're in + * readdir. + */ + dentry_update_name_case(newdent, &qname); + } + + if (d_really_is_negative(newdent)) { + struct inode *inode; + + entry->opened = 0; + entry->ino = iunique(dir->i_sb, 2); + inode = ncp_iget(dir->i_sb, entry); + if (inode) { + d_instantiate(newdent, inode); + if (!hashed) + d_rehash(newdent); + } else { + spin_lock(&dentry->d_lock); + NCP_FINFO(dir)->flags &= ~NCPI_DIR_CACHE; + spin_unlock(&dentry->d_lock); + } + } else { + struct inode *inode = d_inode(newdent); + + inode_lock_nested(inode, I_MUTEX_CHILD); + ncp_update_inode2(inode, entry); + inode_unlock(inode); + } + + if (ctl.idx >= NCP_DIRCACHE_SIZE) { + if (ctl.page) { + kunmap(ctl.page); + SetPageUptodate(ctl.page); + unlock_page(ctl.page); + put_page(ctl.page); + } + ctl.cache = NULL; + ctl.idx -= NCP_DIRCACHE_SIZE; + ctl.ofs += 1; + ctl.page = grab_cache_page(&dir->i_data, ctl.ofs); + if (ctl.page) + ctl.cache = kmap(ctl.page); + } + if (ctl.cache) { + if (d_really_is_positive(newdent)) { + newdent->d_fsdata = newdent; + ctl.cache->dentry[ctl.idx] = newdent; + ino = d_inode(newdent)->i_ino; + ncp_new_dentry(newdent); + } + valid = 1; + } + dput(newdent); +end_advance: + if (!valid) + ctl.valid = 0; + if (!ctl.filled && (ctl.fpos == ctx->pos)) { + if (!ino) + ino = iunique(dir->i_sb, 2); + ctl.filled = !dir_emit(ctx, qname.name, qname.len, + ino, DT_UNKNOWN); + if (!ctl.filled) + ctx->pos += 1; + } + ctl.fpos += 1; + ctl.idx += 1; + *ctrl = ctl; + return (ctl.valid || !ctl.filled); +} + +static void +ncp_read_volume_list(struct file *file, struct dir_context *ctx, + struct ncp_cache_control *ctl) +{ + struct inode *inode = file_inode(file); + struct ncp_server *server = NCP_SERVER(inode); + struct ncp_volume_info info; + struct ncp_entry_info entry; + int i; + + ncp_dbg(1, "pos=%ld\n", (unsigned long)ctx->pos); + + for (i = 0; i < NCP_NUMBER_OF_VOLUMES; i++) { + int inval_dentry; + + if (ncp_get_volume_info_with_number(server, i, &info) != 0) + return; + if (!strlen(info.volume_name)) + continue; + + ncp_dbg(1, "found vol: %s\n", info.volume_name); + + if (ncp_lookup_volume(server, info.volume_name, + &entry.i)) { + ncp_dbg(1, "could not lookup vol %s\n", + info.volume_name); + continue; + } + inval_dentry = ncp_update_known_namespace(server, entry.i.volNumber, NULL); + entry.volume = entry.i.volNumber; + if (!ncp_fill_cache(file, ctx, ctl, &entry, inval_dentry)) + return; + } +} + +static void +ncp_do_readdir(struct file *file, struct dir_context *ctx, + struct ncp_cache_control *ctl) +{ + struct inode *dir = file_inode(file); + struct ncp_server *server = NCP_SERVER(dir); + struct nw_search_sequence seq; + struct ncp_entry_info entry; + int err; + void* buf; + int more; + size_t bufsize; + + ncp_dbg(1, "%pD2, fpos=%ld\n", file, (unsigned long)ctx->pos); + ncp_vdbg("init %pD, volnum=%d, dirent=%u\n", + file, NCP_FINFO(dir)->volNumber, NCP_FINFO(dir)->dirEntNum); + + err = ncp_initialize_search(server, dir, &seq); + if (err) { + ncp_dbg(1, "init failed, err=%d\n", err); + return; + } + /* We MUST NOT use server->buffer_size handshaked with server if we are + using UDP, as for UDP server uses max. buffer size determined by + MTU, and for TCP server uses hardwired value 65KB (== 66560 bytes). + So we use 128KB, just to be sure, as there is no way how to know + this value in advance. */ + bufsize = 131072; + buf = vmalloc(bufsize); + if (!buf) + return; + do { + int cnt; + char* rpl; + size_t rpls; + + err = ncp_search_for_fileset(server, &seq, &more, &cnt, buf, bufsize, &rpl, &rpls); + if (err) /* Error */ + break; + if (!cnt) /* prevent endless loop */ + break; + while (cnt--) { + size_t onerpl; + + if (rpls < offsetof(struct nw_info_struct, entryName)) + break; /* short packet */ + ncp_extract_file_info(rpl, &entry.i); + onerpl = offsetof(struct nw_info_struct, entryName) + entry.i.nameLen; + if (rpls < onerpl) + break; /* short packet */ + (void)ncp_obtain_nfs_info(server, &entry.i); + rpl += onerpl; + rpls -= onerpl; + entry.volume = entry.i.volNumber; + if (!ncp_fill_cache(file, ctx, ctl, &entry, 0)) + break; + } + } while (more); + vfree(buf); + return; +} + +int ncp_conn_logged_in(struct super_block *sb) +{ + struct ncp_server* server = NCP_SBP(sb); + int result; + + if (ncp_single_volume(server)) { + int len; + struct dentry* dent; + __u32 volNumber; + __le32 dirEntNum; + __le32 DosDirNum; + __u8 __name[NCP_MAXPATHLEN + 1]; + + len = sizeof(__name); + result = ncp_io2vol(server, __name, &len, server->m.mounted_vol, + strlen(server->m.mounted_vol), 1); + if (result) + goto out; + result = -ENOENT; + if (ncp_get_volume_root(server, __name, &volNumber, &dirEntNum, &DosDirNum)) { + ncp_vdbg("%s not found\n", server->m.mounted_vol); + goto out; + } + dent = sb->s_root; + if (dent) { + struct inode* ino = d_inode(dent); + if (ino) { + ncp_update_known_namespace(server, volNumber, NULL); + NCP_FINFO(ino)->volNumber = volNumber; + NCP_FINFO(ino)->dirEntNum = dirEntNum; + NCP_FINFO(ino)->DosDirNum = DosDirNum; + result = 0; + } else { + ncp_dbg(1, "d_inode(sb->s_root) == NULL!\n"); + } + } else { + ncp_dbg(1, "sb->s_root == NULL!\n"); + } + } else + result = 0; + +out: + return result; +} + +static struct dentry *ncp_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) +{ + struct ncp_server *server = NCP_SERVER(dir); + struct inode *inode = NULL; + struct ncp_entry_info finfo; + int error, res, len; + __u8 __name[NCP_MAXPATHLEN + 1]; + + error = -EIO; + if (!ncp_conn_valid(server)) + goto finished; + + ncp_vdbg("server lookup for %pd2\n", dentry); + + len = sizeof(__name); + if (ncp_is_server_root(dir)) { + res = ncp_io2vol(server, __name, &len, dentry->d_name.name, + dentry->d_name.len, 1); + if (!res) + res = ncp_lookup_volume(server, __name, &(finfo.i)); + if (!res) + ncp_update_known_namespace(server, finfo.i.volNumber, NULL); + } else { + res = ncp_io2vol(server, __name, &len, dentry->d_name.name, + dentry->d_name.len, !ncp_preserve_case(dir)); + if (!res) + res = ncp_obtain_info(server, dir, __name, &(finfo.i)); + } + ncp_vdbg("looked for %pd2, res=%d\n", dentry, res); + /* + * If we didn't find an entry, make a negative dentry. + */ + if (res) + goto add_entry; + + /* + * Create an inode for the entry. + */ + finfo.opened = 0; + finfo.ino = iunique(dir->i_sb, 2); + finfo.volume = finfo.i.volNumber; + error = -EACCES; + inode = ncp_iget(dir->i_sb, &finfo); + + if (inode) { + ncp_new_dentry(dentry); +add_entry: + d_add(dentry, inode); + error = 0; + } + +finished: + ncp_vdbg("result=%d\n", error); + return ERR_PTR(error); +} + +/* + * This code is common to create, mkdir, and mknod. + */ +static int ncp_instantiate(struct inode *dir, struct dentry *dentry, + struct ncp_entry_info *finfo) +{ + struct inode *inode; + int error = -EINVAL; + + finfo->ino = iunique(dir->i_sb, 2); + inode = ncp_iget(dir->i_sb, finfo); + if (!inode) + goto out_close; + d_instantiate(dentry,inode); + error = 0; +out: + return error; + +out_close: + ncp_vdbg("%pd2 failed, closing file\n", dentry); + ncp_close_file(NCP_SERVER(dir), finfo->file_handle); + goto out; +} + +int ncp_create_new(struct inode *dir, struct dentry *dentry, umode_t mode, + dev_t rdev, __le32 attributes) +{ + struct ncp_server *server = NCP_SERVER(dir); + struct ncp_entry_info finfo; + int error, result, len; + int opmode; + __u8 __name[NCP_MAXPATHLEN + 1]; + + ncp_vdbg("creating %pd2, mode=%hx\n", dentry, mode); + + ncp_age_dentry(server, dentry); + len = sizeof(__name); + error = ncp_io2vol(server, __name, &len, dentry->d_name.name, + dentry->d_name.len, !ncp_preserve_case(dir)); + if (error) + goto out; + + error = -EACCES; + + if (S_ISREG(mode) && + (server->m.flags & NCP_MOUNT_EXTRAS) && + (mode & S_IXUGO)) + attributes |= aSYSTEM | aSHARED; + + result = ncp_open_create_file_or_subdir(server, dir, __name, + OC_MODE_CREATE | OC_MODE_OPEN | OC_MODE_REPLACE, + attributes, AR_READ | AR_WRITE, &finfo); + opmode = O_RDWR; + if (result) { + result = ncp_open_create_file_or_subdir(server, dir, __name, + OC_MODE_CREATE | OC_MODE_OPEN | OC_MODE_REPLACE, + attributes, AR_WRITE, &finfo); + if (result) { + if (result == 0x87) + error = -ENAMETOOLONG; + else if (result < 0) + error = result; + ncp_dbg(1, "%pd2 failed\n", dentry); + goto out; + } + opmode = O_WRONLY; + } + finfo.access = opmode; + if (ncp_is_nfs_extras(server, finfo.volume)) { + finfo.i.nfs.mode = mode; + finfo.i.nfs.rdev = new_encode_dev(rdev); + if (ncp_modify_nfs_info(server, finfo.volume, + finfo.i.dirEntNum, + mode, new_encode_dev(rdev)) != 0) + goto out; + } + + error = ncp_instantiate(dir, dentry, &finfo); +out: + return error; +} + +static int ncp_create(struct inode *dir, struct dentry *dentry, umode_t mode, + bool excl) +{ + return ncp_create_new(dir, dentry, mode, 0, 0); +} + +static int ncp_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) +{ + struct ncp_entry_info finfo; + struct ncp_server *server = NCP_SERVER(dir); + int error, len; + __u8 __name[NCP_MAXPATHLEN + 1]; + + ncp_dbg(1, "making %pd2\n", dentry); + + ncp_age_dentry(server, dentry); + len = sizeof(__name); + error = ncp_io2vol(server, __name, &len, dentry->d_name.name, + dentry->d_name.len, !ncp_preserve_case(dir)); + if (error) + goto out; + + error = ncp_open_create_file_or_subdir(server, dir, __name, + OC_MODE_CREATE, aDIR, + cpu_to_le16(0xffff), + &finfo); + if (error == 0) { + if (ncp_is_nfs_extras(server, finfo.volume)) { + mode |= S_IFDIR; + finfo.i.nfs.mode = mode; + if (ncp_modify_nfs_info(server, + finfo.volume, + finfo.i.dirEntNum, + mode, 0) != 0) + goto out; + } + error = ncp_instantiate(dir, dentry, &finfo); + } else if (error > 0) { + error = -EACCES; + } +out: + return error; +} + +static int ncp_rmdir(struct inode *dir, struct dentry *dentry) +{ + struct ncp_server *server = NCP_SERVER(dir); + int error, result, len; + __u8 __name[NCP_MAXPATHLEN + 1]; + + ncp_dbg(1, "removing %pd2\n", dentry); + + len = sizeof(__name); + error = ncp_io2vol(server, __name, &len, dentry->d_name.name, + dentry->d_name.len, !ncp_preserve_case(dir)); + if (error) + goto out; + + result = ncp_del_file_or_subdir(server, dir, __name); + switch (result) { + case 0x00: + error = 0; + break; + case 0x85: /* unauthorized to delete file */ + case 0x8A: /* unauthorized to delete file */ + error = -EACCES; + break; + case 0x8F: + case 0x90: /* read only */ + error = -EPERM; + break; + case 0x9F: /* in use by another client */ + error = -EBUSY; + break; + case 0xA0: /* directory not empty */ + error = -ENOTEMPTY; + break; + case 0xFF: /* someone deleted file */ + error = -ENOENT; + break; + default: + error = result < 0 ? result : -EACCES; + break; + } +out: + return error; +} + +static int ncp_unlink(struct inode *dir, struct dentry *dentry) +{ + struct inode *inode = d_inode(dentry); + struct ncp_server *server; + int error; + + server = NCP_SERVER(dir); + ncp_dbg(1, "unlinking %pd2\n", dentry); + + /* + * Check whether to close the file ... + */ + if (inode) { + ncp_vdbg("closing file\n"); + ncp_make_closed(inode); + } + + error = ncp_del_file_or_subdir2(server, dentry); +#ifdef CONFIG_NCPFS_STRONG + /* 9C is Invalid path.. It should be 8F, 90 - read only, but + it is not :-( */ + if ((error == 0x9C || error == 0x90) && server->m.flags & NCP_MOUNT_STRONG) { /* R/O */ + error = ncp_force_unlink(dir, dentry); + } +#endif + switch (error) { + case 0x00: + ncp_dbg(1, "removed %pd2\n", dentry); + break; + case 0x85: + case 0x8A: + error = -EACCES; + break; + case 0x8D: /* some files in use */ + case 0x8E: /* all files in use */ + error = -EBUSY; + break; + case 0x8F: /* some read only */ + case 0x90: /* all read only */ + case 0x9C: /* !!! returned when in-use or read-only by NW4 */ + error = -EPERM; + break; + case 0xFF: + error = -ENOENT; + break; + default: + error = error < 0 ? error : -EACCES; + break; + } + return error; +} + +static int ncp_rename(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry, + unsigned int flags) +{ + struct ncp_server *server = NCP_SERVER(old_dir); + int error; + int old_len, new_len; + __u8 __old_name[NCP_MAXPATHLEN + 1], __new_name[NCP_MAXPATHLEN + 1]; + + if (flags) + return -EINVAL; + + ncp_dbg(1, "%pd2 to %pd2\n", old_dentry, new_dentry); + + ncp_age_dentry(server, old_dentry); + ncp_age_dentry(server, new_dentry); + + old_len = sizeof(__old_name); + error = ncp_io2vol(server, __old_name, &old_len, + old_dentry->d_name.name, old_dentry->d_name.len, + !ncp_preserve_case(old_dir)); + if (error) + goto out; + + new_len = sizeof(__new_name); + error = ncp_io2vol(server, __new_name, &new_len, + new_dentry->d_name.name, new_dentry->d_name.len, + !ncp_preserve_case(new_dir)); + if (error) + goto out; + + error = ncp_ren_or_mov_file_or_subdir(server, old_dir, __old_name, + new_dir, __new_name); +#ifdef CONFIG_NCPFS_STRONG + if ((error == 0x90 || error == 0x8B || error == -EACCES) && + server->m.flags & NCP_MOUNT_STRONG) { /* RO */ + error = ncp_force_rename(old_dir, old_dentry, __old_name, + new_dir, new_dentry, __new_name); + } +#endif + switch (error) { + case 0x00: + ncp_dbg(1, "renamed %pd -> %pd\n", + old_dentry, new_dentry); + ncp_d_prune(old_dentry); + ncp_d_prune(new_dentry); + break; + case 0x9E: + error = -ENAMETOOLONG; + break; + case 0xFF: + error = -ENOENT; + break; + default: + error = error < 0 ? error : -EACCES; + break; + } +out: + return error; +} + +static int ncp_mknod(struct inode * dir, struct dentry *dentry, + umode_t mode, dev_t rdev) +{ + if (ncp_is_nfs_extras(NCP_SERVER(dir), NCP_FINFO(dir)->volNumber)) { + ncp_dbg(1, "mode = 0%ho\n", mode); + return ncp_create_new(dir, dentry, mode, rdev, 0); + } + return -EPERM; /* Strange, but true */ +} + +/* The following routines are taken directly from msdos-fs */ + +/* Linear day numbers of the respective 1sts in non-leap years. */ + +static int day_n[] = +{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0}; +/* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec */ + +static int utc2local(int time) +{ + return time - sys_tz.tz_minuteswest * 60; +} + +static int local2utc(int time) +{ + return time + sys_tz.tz_minuteswest * 60; +} + +/* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */ +int +ncp_date_dos2unix(__le16 t, __le16 d) +{ + unsigned short time = le16_to_cpu(t), date = le16_to_cpu(d); + int month, year, secs; + + /* first subtract and mask after that... Otherwise, if + date == 0, bad things happen */ + month = ((date >> 5) - 1) & 15; + year = date >> 9; + secs = (time & 31) * 2 + 60 * ((time >> 5) & 63) + (time >> 11) * 3600 + + 86400 * ((date & 31) - 1 + day_n[month] + (year / 4) + + year * 365 - ((year & 3) == 0 && month < 2 ? 1 : 0) + 3653); + /* days since 1.1.70 plus 80's leap day */ + return local2utc(secs); +} + + +/* Convert linear UNIX date to a MS-DOS time/date pair. */ +void +ncp_date_unix2dos(int unix_date, __le16 *time, __le16 *date) +{ + int day, year, nl_day, month; + + unix_date = utc2local(unix_date); + *time = cpu_to_le16( + (unix_date % 60) / 2 + (((unix_date / 60) % 60) << 5) + + (((unix_date / 3600) % 24) << 11)); + day = unix_date / 86400 - 3652; + year = day / 365; + if ((year + 3) / 4 + 365 * year > day) + year--; + day -= (year + 3) / 4 + 365 * year; + if (day == 59 && !(year & 3)) { + nl_day = day; + month = 2; + } else { + nl_day = (year & 3) || day <= 59 ? day : day - 1; + for (month = 1; month < 12; month++) + if (day_n[month] > nl_day) + break; + } + *date = cpu_to_le16(nl_day - day_n[month - 1] + 1 + (month << 5) + (year << 9)); +} diff --git a/drivers/staging/ncpfs/file.c b/drivers/staging/ncpfs/file.c new file mode 100644 index 000000000000..8f8cc0334ddd --- /dev/null +++ b/drivers/staging/ncpfs/file.c @@ -0,0 +1,263 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * file.c + * + * Copyright (C) 1995, 1996 by Volker Lendecke + * Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache + * + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/uaccess.h> + +#include <linux/time.h> +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/fcntl.h> +#include <linux/stat.h> +#include <linux/mm.h> +#include <linux/vmalloc.h> +#include <linux/sched.h> + +#include "ncp_fs.h" + +static int ncp_fsync(struct file *file, loff_t start, loff_t end, int datasync) +{ + return file_write_and_wait_range(file, start, end); +} + +/* + * Open a file with the specified read/write mode. + */ +int ncp_make_open(struct inode *inode, int right) +{ + int error; + int access; + + error = -EINVAL; + if (!inode) { + pr_err("%s: got NULL inode\n", __func__); + goto out; + } + + ncp_dbg(1, "opened=%d, volume # %u, dir entry # %u\n", + atomic_read(&NCP_FINFO(inode)->opened), + NCP_FINFO(inode)->volNumber, + NCP_FINFO(inode)->dirEntNum); + error = -EACCES; + mutex_lock(&NCP_FINFO(inode)->open_mutex); + if (!atomic_read(&NCP_FINFO(inode)->opened)) { + struct ncp_entry_info finfo; + int result; + + /* tries max. rights */ + finfo.access = O_RDWR; + result = ncp_open_create_file_or_subdir(NCP_SERVER(inode), + inode, NULL, OC_MODE_OPEN, + 0, AR_READ | AR_WRITE, &finfo); + if (!result) + goto update; + /* RDWR did not succeeded, try readonly or writeonly as requested */ + switch (right) { + case O_RDONLY: + finfo.access = O_RDONLY; + result = ncp_open_create_file_or_subdir(NCP_SERVER(inode), + inode, NULL, OC_MODE_OPEN, + 0, AR_READ, &finfo); + break; + case O_WRONLY: + finfo.access = O_WRONLY; + result = ncp_open_create_file_or_subdir(NCP_SERVER(inode), + inode, NULL, OC_MODE_OPEN, + 0, AR_WRITE, &finfo); + break; + } + if (result) { + ncp_vdbg("failed, result=%d\n", result); + goto out_unlock; + } + /* + * Update the inode information. + */ + update: + ncp_update_inode(inode, &finfo); + atomic_set(&NCP_FINFO(inode)->opened, 1); + } + + access = NCP_FINFO(inode)->access; + ncp_vdbg("file open, access=%x\n", access); + if (access == right || access == O_RDWR) { + atomic_inc(&NCP_FINFO(inode)->opened); + error = 0; + } + +out_unlock: + mutex_unlock(&NCP_FINFO(inode)->open_mutex); +out: + return error; +} + +static ssize_t +ncp_file_read_iter(struct kiocb *iocb, struct iov_iter *to) +{ + struct file *file = iocb->ki_filp; + struct inode *inode = file_inode(file); + size_t already_read = 0; + off_t pos = iocb->ki_pos; + size_t bufsize; + int error; + void *freepage; + size_t freelen; + + ncp_dbg(1, "enter %pD2\n", file); + + if (!iov_iter_count(to)) + return 0; + if (pos > inode->i_sb->s_maxbytes) + return 0; + iov_iter_truncate(to, inode->i_sb->s_maxbytes - pos); + + error = ncp_make_open(inode, O_RDONLY); + if (error) { + ncp_dbg(1, "open failed, error=%d\n", error); + return error; + } + + bufsize = NCP_SERVER(inode)->buffer_size; + + error = -EIO; + freelen = ncp_read_bounce_size(bufsize); + freepage = vmalloc(freelen); + if (!freepage) + goto outrel; + error = 0; + /* First read in as much as possible for each bufsize. */ + while (iov_iter_count(to)) { + int read_this_time; + size_t to_read = min_t(size_t, + bufsize - (pos % bufsize), + iov_iter_count(to)); + + error = ncp_read_bounce(NCP_SERVER(inode), + NCP_FINFO(inode)->file_handle, + pos, to_read, to, &read_this_time, + freepage, freelen); + if (error) { + error = -EIO; /* NW errno -> Linux errno */ + break; + } + pos += read_this_time; + already_read += read_this_time; + + if (read_this_time != to_read) + break; + } + vfree(freepage); + + iocb->ki_pos = pos; + + file_accessed(file); + + ncp_dbg(1, "exit %pD2\n", file); +outrel: + ncp_inode_close(inode); + return already_read ? already_read : error; +} + +static ssize_t +ncp_file_write_iter(struct kiocb *iocb, struct iov_iter *from) +{ + struct file *file = iocb->ki_filp; + struct inode *inode = file_inode(file); + size_t already_written = 0; + size_t bufsize; + int errno; + void *bouncebuffer; + off_t pos; + + ncp_dbg(1, "enter %pD2\n", file); + errno = generic_write_checks(iocb, from); + if (errno <= 0) + return errno; + + errno = ncp_make_open(inode, O_WRONLY); + if (errno) { + ncp_dbg(1, "open failed, error=%d\n", errno); + return errno; + } + bufsize = NCP_SERVER(inode)->buffer_size; + + errno = file_update_time(file); + if (errno) + goto outrel; + + bouncebuffer = vmalloc(bufsize); + if (!bouncebuffer) { + errno = -EIO; /* -ENOMEM */ + goto outrel; + } + pos = iocb->ki_pos; + while (iov_iter_count(from)) { + int written_this_time; + size_t to_write = min_t(size_t, + bufsize - (pos % bufsize), + iov_iter_count(from)); + + if (!copy_from_iter_full(bouncebuffer, to_write, from)) { + errno = -EFAULT; + break; + } + if (ncp_write_kernel(NCP_SERVER(inode), + NCP_FINFO(inode)->file_handle, + pos, to_write, bouncebuffer, &written_this_time) != 0) { + errno = -EIO; + break; + } + pos += written_this_time; + already_written += written_this_time; + + if (written_this_time != to_write) + break; + } + vfree(bouncebuffer); + + iocb->ki_pos = pos; + + if (pos > i_size_read(inode)) { + inode_lock(inode); + if (pos > i_size_read(inode)) + i_size_write(inode, pos); + inode_unlock(inode); + } + ncp_dbg(1, "exit %pD2\n", file); +outrel: + ncp_inode_close(inode); + return already_written ? already_written : errno; +} + +static int ncp_release(struct inode *inode, struct file *file) { + if (ncp_make_closed(inode)) { + ncp_dbg(1, "failed to close\n"); + } + return 0; +} + +const struct file_operations ncp_file_operations = +{ + .llseek = generic_file_llseek, + .read_iter = ncp_file_read_iter, + .write_iter = ncp_file_write_iter, + .unlocked_ioctl = ncp_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = ncp_compat_ioctl, +#endif + .mmap = ncp_mmap, + .release = ncp_release, + .fsync = ncp_fsync, +}; + +const struct inode_operations ncp_file_inode_operations = +{ + .setattr = ncp_notify_change, +}; diff --git a/drivers/staging/ncpfs/getopt.c b/drivers/staging/ncpfs/getopt.c new file mode 100644 index 000000000000..5c941bef14c4 --- /dev/null +++ b/drivers/staging/ncpfs/getopt.c @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * getopt.c + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/kernel.h> +#include <linux/string.h> + +#include <asm/errno.h> + +#include "getopt.h" + +/** + * ncp_getopt - option parser + * @caller: name of the caller, for error messages + * @options: the options string + * @opts: an array of &struct option entries controlling parser operations + * @optopt: output; will contain the current option + * @optarg: output; will contain the value (if one exists) + * @value: output; may be NULL; will be overwritten with the integer value + * of the current argument. + * + * Helper to parse options on the format used by mount ("a=b,c=d,e,f"). + * Returns opts->val if a matching entry in the 'opts' array is found, + * 0 when no more tokens are found, -1 if an error is encountered. + */ +int ncp_getopt(const char *caller, char **options, const struct ncp_option *opts, + char **optopt, char **optarg, unsigned long *value) +{ + char *token; + char *val; + + do { + if ((token = strsep(options, ",")) == NULL) + return 0; + } while (*token == '\0'); + if (optopt) + *optopt = token; + + if ((val = strchr (token, '=')) != NULL) { + *val++ = 0; + } + *optarg = val; + for (; opts->name; opts++) { + if (!strcmp(opts->name, token)) { + if (!val) { + if (opts->has_arg & OPT_NOPARAM) { + return opts->val; + } + pr_info("%s: the %s option requires an argument\n", + caller, token); + return -EINVAL; + } + if (opts->has_arg & OPT_INT) { + int rc = kstrtoul(val, 0, value); + + if (rc) { + pr_info("%s: invalid numeric value in %s=%s\n", + caller, token, val); + return rc; + } + return opts->val; + } + if (opts->has_arg & OPT_STRING) { + return opts->val; + } + pr_info("%s: unexpected argument %s to the %s option\n", + caller, val, token); + return -EINVAL; + } + } + pr_info("%s: Unrecognized mount option %s\n", caller, token); + return -EOPNOTSUPP; +} diff --git a/drivers/staging/ncpfs/getopt.h b/drivers/staging/ncpfs/getopt.h new file mode 100644 index 000000000000..30f0da317670 --- /dev/null +++ b/drivers/staging/ncpfs/getopt.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_GETOPT_H +#define _LINUX_GETOPT_H + +#define OPT_NOPARAM 1 +#define OPT_INT 2 +#define OPT_STRING 4 +struct ncp_option { + const char *name; + unsigned int has_arg; + int val; +}; + +extern int ncp_getopt(const char *caller, char **options, const struct ncp_option *opts, + char **optopt, char **optarg, unsigned long *value); + +#endif /* _LINUX_GETOPT_H */ diff --git a/drivers/staging/ncpfs/inode.c b/drivers/staging/ncpfs/inode.c new file mode 100644 index 000000000000..bb411610a071 --- /dev/null +++ b/drivers/staging/ncpfs/inode.c @@ -0,0 +1,1067 @@ +/* + * inode.c + * + * Copyright (C) 1995, 1996 by Volker Lendecke + * Modified for big endian by J.F. Chadima and David S. Miller + * Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache + * Modified 1998 Wolfram Pienkoss for NLS + * Modified 2000 Ben Harris, University of Cambridge for NFS NS meta-info + * + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/module.h> + +#include <linux/uaccess.h> +#include <asm/byteorder.h> + +#include <linux/time.h> +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/string.h> +#include <linux/stat.h> +#include <linux/errno.h> +#include <linux/file.h> +#include <linux/fcntl.h> +#include <linux/slab.h> +#include <linux/vmalloc.h> +#include <linux/init.h> +#include <linux/vfs.h> +#include <linux/mount.h> +#include <linux/seq_file.h> +#include <linux/sched/signal.h> +#include <linux/namei.h> + +#include <net/sock.h> + +#include "ncp_fs.h" +#include "getopt.h" + +#define NCP_DEFAULT_FILE_MODE 0600 +#define NCP_DEFAULT_DIR_MODE 0700 +#define NCP_DEFAULT_TIME_OUT 10 +#define NCP_DEFAULT_RETRY_COUNT 20 + +static void ncp_evict_inode(struct inode *); +static void ncp_put_super(struct super_block *); +static int ncp_statfs(struct dentry *, struct kstatfs *); +static int ncp_show_options(struct seq_file *, struct dentry *); + +static struct kmem_cache * ncp_inode_cachep; + +static struct inode *ncp_alloc_inode(struct super_block *sb) +{ + struct ncp_inode_info *ei; + + ei = kmem_cache_alloc(ncp_inode_cachep, GFP_KERNEL); + if (!ei) + return NULL; + return &ei->vfs_inode; +} + +static void ncp_i_callback(struct rcu_head *head) +{ + struct inode *inode = container_of(head, struct inode, i_rcu); + kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode)); +} + +static void ncp_destroy_inode(struct inode *inode) +{ + call_rcu(&inode->i_rcu, ncp_i_callback); +} + +static void init_once(void *foo) +{ + struct ncp_inode_info *ei = (struct ncp_inode_info *) foo; + + mutex_init(&ei->open_mutex); + inode_init_once(&ei->vfs_inode); +} + +static int init_inodecache(void) +{ + ncp_inode_cachep = kmem_cache_create("ncp_inode_cache", + sizeof(struct ncp_inode_info), + 0, (SLAB_RECLAIM_ACCOUNT| + SLAB_MEM_SPREAD|SLAB_ACCOUNT), + init_once); + if (ncp_inode_cachep == NULL) + return -ENOMEM; + return 0; +} + +static void destroy_inodecache(void) +{ + /* + * Make sure all delayed rcu free inodes are flushed before we + * destroy cache. + */ + rcu_barrier(); + kmem_cache_destroy(ncp_inode_cachep); +} + +static int ncp_remount(struct super_block *sb, int *flags, char* data) +{ + sync_filesystem(sb); + *flags |= SB_NODIRATIME; + return 0; +} + +static const struct super_operations ncp_sops = +{ + .alloc_inode = ncp_alloc_inode, + .destroy_inode = ncp_destroy_inode, + .drop_inode = generic_delete_inode, + .evict_inode = ncp_evict_inode, + .put_super = ncp_put_super, + .statfs = ncp_statfs, + .remount_fs = ncp_remount, + .show_options = ncp_show_options, +}; + +/* + * Fill in the ncpfs-specific information in the inode. + */ +static void ncp_update_dirent(struct inode *inode, struct ncp_entry_info *nwinfo) +{ + NCP_FINFO(inode)->DosDirNum = nwinfo->i.DosDirNum; + NCP_FINFO(inode)->dirEntNum = nwinfo->i.dirEntNum; + NCP_FINFO(inode)->volNumber = nwinfo->volume; +} + +void ncp_update_inode(struct inode *inode, struct ncp_entry_info *nwinfo) +{ + ncp_update_dirent(inode, nwinfo); + NCP_FINFO(inode)->nwattr = nwinfo->i.attributes; + NCP_FINFO(inode)->access = nwinfo->access; + memcpy(NCP_FINFO(inode)->file_handle, nwinfo->file_handle, + sizeof(nwinfo->file_handle)); + ncp_dbg(1, "updated %s, volnum=%d, dirent=%u\n", + nwinfo->i.entryName, NCP_FINFO(inode)->volNumber, + NCP_FINFO(inode)->dirEntNum); +} + +static void ncp_update_dates(struct inode *inode, struct nw_info_struct *nwi) +{ + /* NFS namespace mode overrides others if it's set. */ + ncp_dbg(1, "(%s) nfs.mode=0%o\n", nwi->entryName, nwi->nfs.mode); + if (nwi->nfs.mode) { + /* XXX Security? */ + inode->i_mode = nwi->nfs.mode; + } + + inode->i_blocks = (i_size_read(inode) + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT; + + inode->i_mtime.tv_sec = ncp_date_dos2unix(nwi->modifyTime, nwi->modifyDate); + inode->i_ctime.tv_sec = ncp_date_dos2unix(nwi->creationTime, nwi->creationDate); + inode->i_atime.tv_sec = ncp_date_dos2unix(0, nwi->lastAccessDate); + inode->i_atime.tv_nsec = 0; + inode->i_mtime.tv_nsec = 0; + inode->i_ctime.tv_nsec = 0; +} + +static void ncp_update_attrs(struct inode *inode, struct ncp_entry_info *nwinfo) +{ + struct nw_info_struct *nwi = &nwinfo->i; + struct ncp_server *server = NCP_SERVER(inode); + + if (nwi->attributes & aDIR) { + inode->i_mode = server->m.dir_mode; + /* for directories dataStreamSize seems to be some + Object ID ??? */ + i_size_write(inode, NCP_BLOCK_SIZE); + } else { + u32 size; + + inode->i_mode = server->m.file_mode; + size = le32_to_cpu(nwi->dataStreamSize); + i_size_write(inode, size); +#ifdef CONFIG_NCPFS_EXTRAS + if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS)) + && (nwi->attributes & aSHARED)) { + switch (nwi->attributes & (aHIDDEN|aSYSTEM)) { + case aHIDDEN: + if (server->m.flags & NCP_MOUNT_SYMLINKS) { + if (/* (size >= NCP_MIN_SYMLINK_SIZE) + && */ (size <= NCP_MAX_SYMLINK_SIZE)) { + inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK; + NCP_FINFO(inode)->flags |= NCPI_KLUDGE_SYMLINK; + break; + } + } + /* FALLTHROUGH */ + case 0: + if (server->m.flags & NCP_MOUNT_EXTRAS) + inode->i_mode |= S_IRUGO; + break; + case aSYSTEM: + if (server->m.flags & NCP_MOUNT_EXTRAS) + inode->i_mode |= (inode->i_mode >> 2) & S_IXUGO; + break; + /* case aSYSTEM|aHIDDEN: */ + default: + /* reserved combination */ + break; + } + } +#endif + } + if (nwi->attributes & aRONLY) inode->i_mode &= ~S_IWUGO; +} + +void ncp_update_inode2(struct inode* inode, struct ncp_entry_info *nwinfo) +{ + NCP_FINFO(inode)->flags = 0; + if (!atomic_read(&NCP_FINFO(inode)->opened)) { + NCP_FINFO(inode)->nwattr = nwinfo->i.attributes; + ncp_update_attrs(inode, nwinfo); + } + + ncp_update_dates(inode, &nwinfo->i); + ncp_update_dirent(inode, nwinfo); +} + +/* + * Fill in the inode based on the ncp_entry_info structure. Used only for brand new inodes. + */ +static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo) +{ + struct ncp_server *server = NCP_SERVER(inode); + + NCP_FINFO(inode)->flags = 0; + + ncp_update_attrs(inode, nwinfo); + + ncp_dbg(2, "inode->i_mode = %u\n", inode->i_mode); + + set_nlink(inode, 1); + inode->i_uid = server->m.uid; + inode->i_gid = server->m.gid; + + ncp_update_dates(inode, &nwinfo->i); + ncp_update_inode(inode, nwinfo); +} + +#if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS) +static const struct inode_operations ncp_symlink_inode_operations = { + .get_link = page_get_link, + .setattr = ncp_notify_change, +}; +#endif + +/* + * Get a new inode. + */ +struct inode * +ncp_iget(struct super_block *sb, struct ncp_entry_info *info) +{ + struct inode *inode; + + if (info == NULL) { + pr_err("%s: info is NULL\n", __func__); + return NULL; + } + + inode = new_inode(sb); + if (inode) { + atomic_set(&NCP_FINFO(inode)->opened, info->opened); + + inode->i_ino = info->ino; + ncp_set_attr(inode, info); + if (S_ISREG(inode->i_mode)) { + inode->i_op = &ncp_file_inode_operations; + inode->i_fop = &ncp_file_operations; + } else if (S_ISDIR(inode->i_mode)) { + inode->i_op = &ncp_dir_inode_operations; + inode->i_fop = &ncp_dir_operations; +#ifdef CONFIG_NCPFS_NFS_NS + } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { + init_special_inode(inode, inode->i_mode, + new_decode_dev(info->i.nfs.rdev)); +#endif +#if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS) + } else if (S_ISLNK(inode->i_mode)) { + inode->i_op = &ncp_symlink_inode_operations; + inode_nohighmem(inode); + inode->i_data.a_ops = &ncp_symlink_aops; +#endif + } else { + make_bad_inode(inode); + } + insert_inode_hash(inode); + } else + pr_err("%s: iget failed!\n", __func__); + return inode; +} + +static void +ncp_evict_inode(struct inode *inode) +{ + truncate_inode_pages_final(&inode->i_data); + clear_inode(inode); + + if (S_ISDIR(inode->i_mode)) { + ncp_dbg(2, "put directory %ld\n", inode->i_ino); + } + + if (ncp_make_closed(inode) != 0) { + /* We can't do anything but complain. */ + pr_err("%s: could not close\n", __func__); + } +} + +static void ncp_stop_tasks(struct ncp_server *server) { + struct sock* sk = server->ncp_sock->sk; + + lock_sock(sk); + sk->sk_error_report = server->error_report; + sk->sk_data_ready = server->data_ready; + sk->sk_write_space = server->write_space; + release_sock(sk); + del_timer_sync(&server->timeout_tm); + + flush_work(&server->rcv.tq); + if (sk->sk_socket->type == SOCK_STREAM) + flush_work(&server->tx.tq); + else + flush_work(&server->timeout_tq); +} + +static int ncp_show_options(struct seq_file *seq, struct dentry *root) +{ + struct ncp_server *server = NCP_SBP(root->d_sb); + unsigned int tmp; + + if (!uid_eq(server->m.uid, GLOBAL_ROOT_UID)) + seq_printf(seq, ",uid=%u", + from_kuid_munged(&init_user_ns, server->m.uid)); + if (!gid_eq(server->m.gid, GLOBAL_ROOT_GID)) + seq_printf(seq, ",gid=%u", + from_kgid_munged(&init_user_ns, server->m.gid)); + if (!uid_eq(server->m.mounted_uid, GLOBAL_ROOT_UID)) + seq_printf(seq, ",owner=%u", + from_kuid_munged(&init_user_ns, server->m.mounted_uid)); + tmp = server->m.file_mode & S_IALLUGO; + if (tmp != NCP_DEFAULT_FILE_MODE) + seq_printf(seq, ",mode=0%o", tmp); + tmp = server->m.dir_mode & S_IALLUGO; + if (tmp != NCP_DEFAULT_DIR_MODE) + seq_printf(seq, ",dirmode=0%o", tmp); + if (server->m.time_out != NCP_DEFAULT_TIME_OUT * HZ / 100) { + tmp = server->m.time_out * 100 / HZ; + seq_printf(seq, ",timeout=%u", tmp); + } + if (server->m.retry_count != NCP_DEFAULT_RETRY_COUNT) + seq_printf(seq, ",retry=%u", server->m.retry_count); + if (server->m.flags != 0) + seq_printf(seq, ",flags=%lu", server->m.flags); + if (server->m.wdog_pid != NULL) + seq_printf(seq, ",wdogpid=%u", pid_vnr(server->m.wdog_pid)); + + return 0; +} + +static const struct ncp_option ncp_opts[] = { + { "uid", OPT_INT, 'u' }, + { "gid", OPT_INT, 'g' }, + { "owner", OPT_INT, 'o' }, + { "mode", OPT_INT, 'm' }, + { "dirmode", OPT_INT, 'd' }, + { "timeout", OPT_INT, 't' }, + { "retry", OPT_INT, 'r' }, + { "flags", OPT_INT, 'f' }, + { "wdogpid", OPT_INT, 'w' }, + { "ncpfd", OPT_INT, 'n' }, + { "infofd", OPT_INT, 'i' }, /* v5 */ + { "version", OPT_INT, 'v' }, + { NULL, 0, 0 } }; + +static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options) { + int optval; + char *optarg; + unsigned long optint; + int version = 0; + int ret; + + data->flags = 0; + data->int_flags = 0; + data->mounted_uid = GLOBAL_ROOT_UID; + data->wdog_pid = NULL; + data->ncp_fd = ~0; + data->time_out = NCP_DEFAULT_TIME_OUT; + data->retry_count = NCP_DEFAULT_RETRY_COUNT; + data->uid = GLOBAL_ROOT_UID; + data->gid = GLOBAL_ROOT_GID; + data->file_mode = NCP_DEFAULT_FILE_MODE; + data->dir_mode = NCP_DEFAULT_DIR_MODE; + data->info_fd = -1; + data->mounted_vol[0] = 0; + + while ((optval = ncp_getopt("ncpfs", &options, ncp_opts, NULL, &optarg, &optint)) != 0) { + ret = optval; + if (ret < 0) + goto err; + switch (optval) { + case 'u': + data->uid = make_kuid(current_user_ns(), optint); + if (!uid_valid(data->uid)) { + ret = -EINVAL; + goto err; + } + break; + case 'g': + data->gid = make_kgid(current_user_ns(), optint); + if (!gid_valid(data->gid)) { + ret = -EINVAL; + goto err; + } + break; + case 'o': + data->mounted_uid = make_kuid(current_user_ns(), optint); + if (!uid_valid(data->mounted_uid)) { + ret = -EINVAL; + goto err; + } + break; + case 'm': + data->file_mode = optint; + break; + case 'd': + data->dir_mode = optint; + break; + case 't': + data->time_out = optint; + break; + case 'r': + data->retry_count = optint; + break; + case 'f': + data->flags = optint; + break; + case 'w': + data->wdog_pid = find_get_pid(optint); + break; + case 'n': + data->ncp_fd = optint; + break; + case 'i': + data->info_fd = optint; + break; + case 'v': + ret = -ECHRNG; + if (optint < NCP_MOUNT_VERSION_V4) + goto err; + if (optint > NCP_MOUNT_VERSION_V5) + goto err; + version = optint; + break; + + } + } + return 0; +err: + put_pid(data->wdog_pid); + data->wdog_pid = NULL; + return ret; +} + +static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) +{ + struct ncp_mount_data_kernel data; + struct ncp_server *server; + struct inode *root_inode; + struct socket *sock; + int error; + int default_bufsize; +#ifdef CONFIG_NCPFS_PACKET_SIGNING + int options; +#endif + struct ncp_entry_info finfo; + + memset(&data, 0, sizeof(data)); + server = kzalloc(sizeof(struct ncp_server), GFP_KERNEL); + if (!server) + return -ENOMEM; + sb->s_fs_info = server; + + error = -EFAULT; + if (raw_data == NULL) + goto out; + switch (*(int*)raw_data) { + case NCP_MOUNT_VERSION: + { + struct ncp_mount_data* md = (struct ncp_mount_data*)raw_data; + + data.flags = md->flags; + data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE; + data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid); + data.wdog_pid = find_get_pid(md->wdog_pid); + data.ncp_fd = md->ncp_fd; + data.time_out = md->time_out; + data.retry_count = md->retry_count; + data.uid = make_kuid(current_user_ns(), md->uid); + data.gid = make_kgid(current_user_ns(), md->gid); + data.file_mode = md->file_mode; + data.dir_mode = md->dir_mode; + data.info_fd = -1; + memcpy(data.mounted_vol, md->mounted_vol, + NCP_VOLNAME_LEN+1); + } + break; + case NCP_MOUNT_VERSION_V4: + { + struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data; + + data.flags = md->flags; + data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid); + data.wdog_pid = find_get_pid(md->wdog_pid); + data.ncp_fd = md->ncp_fd; + data.time_out = md->time_out; + data.retry_count = md->retry_count; + data.uid = make_kuid(current_user_ns(), md->uid); + data.gid = make_kgid(current_user_ns(), md->gid); + data.file_mode = md->file_mode; + data.dir_mode = md->dir_mode; + data.info_fd = -1; + } + break; + default: + error = -ECHRNG; + if (memcmp(raw_data, "vers", 4) == 0) { + error = ncp_parse_options(&data, raw_data); + } + if (error) + goto out; + break; + } + error = -EINVAL; + if (!uid_valid(data.mounted_uid) || !uid_valid(data.uid) || + !gid_valid(data.gid)) + goto out; + sock = sockfd_lookup(data.ncp_fd, &error); + if (!sock) + goto out; + + if (sock->type == SOCK_STREAM) + default_bufsize = 0xF000; + else + default_bufsize = 1024; + + sb->s_flags |= SB_NODIRATIME; /* probably even noatime */ + sb->s_maxbytes = 0xFFFFFFFFU; + sb->s_blocksize = 1024; /* Eh... Is this correct? */ + sb->s_blocksize_bits = 10; + sb->s_magic = NCP_SUPER_MAGIC; + sb->s_op = &ncp_sops; + sb->s_d_op = &ncp_dentry_operations; + + server = NCP_SBP(sb); + memset(server, 0, sizeof(*server)); + + error = super_setup_bdi(sb); + if (error) + goto out_fput; + + server->ncp_sock = sock; + + if (data.info_fd != -1) { + struct socket *info_sock = sockfd_lookup(data.info_fd, &error); + if (!info_sock) + goto out_fput; + server->info_sock = info_sock; + error = -EBADFD; + if (info_sock->type != SOCK_STREAM) + goto out_fput2; + } + +/* server->lock = 0; */ + mutex_init(&server->mutex); + server->packet = NULL; +/* server->buffer_size = 0; */ +/* server->conn_status = 0; */ +/* server->root_dentry = NULL; */ +/* server->root_setuped = 0; */ + mutex_init(&server->root_setup_lock); +#ifdef CONFIG_NCPFS_PACKET_SIGNING +/* server->sign_wanted = 0; */ +/* server->sign_active = 0; */ +#endif + init_rwsem(&server->auth_rwsem); + server->auth.auth_type = NCP_AUTH_NONE; +/* server->auth.object_name_len = 0; */ +/* server->auth.object_name = NULL; */ +/* server->auth.object_type = 0; */ +/* server->priv.len = 0; */ +/* server->priv.data = NULL; */ + + server->m = data; + /* Although anything producing this is buggy, it happens + now because of PATH_MAX changes.. */ + if (server->m.time_out < 1) { + server->m.time_out = 10; + pr_info("You need to recompile your ncpfs utils..\n"); + } + server->m.time_out = server->m.time_out * HZ / 100; + server->m.file_mode = (server->m.file_mode & S_IRWXUGO) | S_IFREG; + server->m.dir_mode = (server->m.dir_mode & S_IRWXUGO) | S_IFDIR; + +#ifdef CONFIG_NCPFS_NLS + /* load the default NLS charsets */ + server->nls_vol = load_nls_default(); + server->nls_io = load_nls_default(); +#endif /* CONFIG_NCPFS_NLS */ + + atomic_set(&server->dentry_ttl, 0); /* no caching */ + + INIT_LIST_HEAD(&server->tx.requests); + mutex_init(&server->rcv.creq_mutex); + server->tx.creq = NULL; + server->rcv.creq = NULL; + + timer_setup(&server->timeout_tm, ncpdgram_timeout_call, 0); +#undef NCP_PACKET_SIZE +#define NCP_PACKET_SIZE 131072 + error = -ENOMEM; + server->packet_size = NCP_PACKET_SIZE; + server->packet = vmalloc(NCP_PACKET_SIZE); + if (server->packet == NULL) + goto out_nls; + server->txbuf = vmalloc(NCP_PACKET_SIZE); + if (server->txbuf == NULL) + goto out_packet; + server->rxbuf = vmalloc(NCP_PACKET_SIZE); + if (server->rxbuf == NULL) + goto out_txbuf; + + lock_sock(sock->sk); + server->data_ready = sock->sk->sk_data_ready; + server->write_space = sock->sk->sk_write_space; + server->error_report = sock->sk->sk_error_report; + sock->sk->sk_user_data = server; + sock->sk->sk_data_ready = ncp_tcp_data_ready; + sock->sk->sk_error_report = ncp_tcp_error_report; + if (sock->type == SOCK_STREAM) { + server->rcv.ptr = (unsigned char*)&server->rcv.buf; + server->rcv.len = 10; + server->rcv.state = 0; + INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc); + INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc); + sock->sk->sk_write_space = ncp_tcp_write_space; + } else { + INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc); + INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc); + } + release_sock(sock->sk); + + ncp_lock_server(server); + error = ncp_connect(server); + ncp_unlock_server(server); + if (error < 0) + goto out_rxbuf; + ncp_dbg(1, "NCP_SBP(sb) = %p\n", NCP_SBP(sb)); + + error = -EMSGSIZE; /* -EREMOTESIDEINCOMPATIBLE */ +#ifdef CONFIG_NCPFS_PACKET_SIGNING + if (ncp_negotiate_size_and_options(server, default_bufsize, + NCP_DEFAULT_OPTIONS, &(server->buffer_size), &options) == 0) + { + if (options != NCP_DEFAULT_OPTIONS) + { + if (ncp_negotiate_size_and_options(server, + default_bufsize, + options & 2, + &(server->buffer_size), &options) != 0) + + { + goto out_disconnect; + } + } + ncp_lock_server(server); + if (options & 2) + server->sign_wanted = 1; + ncp_unlock_server(server); + } + else +#endif /* CONFIG_NCPFS_PACKET_SIGNING */ + if (ncp_negotiate_buffersize(server, default_bufsize, + &(server->buffer_size)) != 0) + goto out_disconnect; + ncp_dbg(1, "bufsize = %d\n", server->buffer_size); + + memset(&finfo, 0, sizeof(finfo)); + finfo.i.attributes = aDIR; + finfo.i.dataStreamSize = 0; /* ignored */ + finfo.i.dirEntNum = 0; + finfo.i.DosDirNum = 0; +#ifdef CONFIG_NCPFS_SMALLDOS + finfo.i.NSCreator = NW_NS_DOS; +#endif + finfo.volume = NCP_NUMBER_OF_VOLUMES; + /* set dates of mountpoint to Jan 1, 1986; 00:00 */ + finfo.i.creationTime = finfo.i.modifyTime + = cpu_to_le16(0x0000); + finfo.i.creationDate = finfo.i.modifyDate + = finfo.i.lastAccessDate + = cpu_to_le16(0x0C21); + finfo.i.nameLen = 0; + finfo.i.entryName[0] = '\0'; + + finfo.opened = 0; + finfo.ino = 2; /* tradition */ + + server->name_space[finfo.volume] = NW_NS_DOS; + + error = -ENOMEM; + root_inode = ncp_iget(sb, &finfo); + if (!root_inode) + goto out_disconnect; + ncp_dbg(1, "root vol=%d\n", NCP_FINFO(root_inode)->volNumber); + sb->s_root = d_make_root(root_inode); + if (!sb->s_root) + goto out_disconnect; + return 0; + +out_disconnect: + ncp_lock_server(server); + ncp_disconnect(server); + ncp_unlock_server(server); +out_rxbuf: + ncp_stop_tasks(server); + vfree(server->rxbuf); +out_txbuf: + vfree(server->txbuf); +out_packet: + vfree(server->packet); +out_nls: +#ifdef CONFIG_NCPFS_NLS + unload_nls(server->nls_io); + unload_nls(server->nls_vol); +#endif + mutex_destroy(&server->rcv.creq_mutex); + mutex_destroy(&server->root_setup_lock); + mutex_destroy(&server->mutex); +out_fput2: + if (server->info_sock) + sockfd_put(server->info_sock); +out_fput: + sockfd_put(sock); +out: + put_pid(data.wdog_pid); + sb->s_fs_info = NULL; + kfree(server); + return error; +} + +static void delayed_free(struct rcu_head *p) +{ + struct ncp_server *server = container_of(p, struct ncp_server, rcu); +#ifdef CONFIG_NCPFS_NLS + /* unload the NLS charsets */ + unload_nls(server->nls_vol); + unload_nls(server->nls_io); +#endif /* CONFIG_NCPFS_NLS */ + kfree(server); +} + +static void ncp_put_super(struct super_block *sb) +{ + struct ncp_server *server = NCP_SBP(sb); + + ncp_lock_server(server); + ncp_disconnect(server); + ncp_unlock_server(server); + + ncp_stop_tasks(server); + + mutex_destroy(&server->rcv.creq_mutex); + mutex_destroy(&server->root_setup_lock); + mutex_destroy(&server->mutex); + + if (server->info_sock) + sockfd_put(server->info_sock); + sockfd_put(server->ncp_sock); + kill_pid(server->m.wdog_pid, SIGTERM, 1); + put_pid(server->m.wdog_pid); + + kfree(server->priv.data); + kfree(server->auth.object_name); + vfree(server->rxbuf); + vfree(server->txbuf); + vfree(server->packet); + call_rcu(&server->rcu, delayed_free); +} + +static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf) +{ + struct dentry* d; + struct inode* i; + struct ncp_inode_info* ni; + struct ncp_server* s; + struct ncp_volume_info vi; + struct super_block *sb = dentry->d_sb; + int err; + __u8 dh; + + d = sb->s_root; + if (!d) { + goto dflt; + } + i = d_inode(d); + if (!i) { + goto dflt; + } + ni = NCP_FINFO(i); + if (!ni) { + goto dflt; + } + s = NCP_SBP(sb); + if (!s) { + goto dflt; + } + if (!s->m.mounted_vol[0]) { + goto dflt; + } + + err = ncp_dirhandle_alloc(s, ni->volNumber, ni->DosDirNum, &dh); + if (err) { + goto dflt; + } + err = ncp_get_directory_info(s, dh, &vi); + ncp_dirhandle_free(s, dh); + if (err) { + goto dflt; + } + buf->f_type = NCP_SUPER_MAGIC; + buf->f_bsize = vi.sectors_per_block * 512; + buf->f_blocks = vi.total_blocks; + buf->f_bfree = vi.free_blocks; + buf->f_bavail = vi.free_blocks; + buf->f_files = vi.total_dir_entries; + buf->f_ffree = vi.available_dir_entries; + buf->f_namelen = 12; + return 0; + + /* We cannot say how much disk space is left on a mounted + NetWare Server, because free space is distributed over + volumes, and the current user might have disk quotas. So + free space is not that simple to determine. Our decision + here is to err conservatively. */ + +dflt:; + buf->f_type = NCP_SUPER_MAGIC; + buf->f_bsize = NCP_BLOCK_SIZE; + buf->f_blocks = 0; + buf->f_bfree = 0; + buf->f_bavail = 0; + buf->f_namelen = 12; + return 0; +} + +int ncp_notify_change(struct dentry *dentry, struct iattr *attr) +{ + struct inode *inode = d_inode(dentry); + int result = 0; + __le32 info_mask; + struct nw_modify_dos_info info; + struct ncp_server *server; + + result = -EIO; + + server = NCP_SERVER(inode); + if (!server) /* How this could happen? */ + goto out; + + result = -EPERM; + if (IS_DEADDIR(d_inode(dentry))) + goto out; + + /* ageing the dentry to force validation */ + ncp_age_dentry(server, dentry); + + result = setattr_prepare(dentry, attr); + if (result < 0) + goto out; + + result = -EPERM; + if ((attr->ia_valid & ATTR_UID) && !uid_eq(attr->ia_uid, server->m.uid)) + goto out; + + if ((attr->ia_valid & ATTR_GID) && !gid_eq(attr->ia_gid, server->m.gid)) + goto out; + + if (((attr->ia_valid & ATTR_MODE) && + (attr->ia_mode & + ~(S_IFREG | S_IFDIR | S_IRWXUGO)))) + goto out; + + info_mask = 0; + memset(&info, 0, sizeof(info)); + +#if 1 + if ((attr->ia_valid & ATTR_MODE) != 0) + { + umode_t newmode = attr->ia_mode; + + info_mask |= DM_ATTRIBUTES; + + if (S_ISDIR(inode->i_mode)) { + newmode &= server->m.dir_mode; + } else { +#ifdef CONFIG_NCPFS_EXTRAS + if (server->m.flags & NCP_MOUNT_EXTRAS) { + /* any non-default execute bit set */ + if (newmode & ~server->m.file_mode & S_IXUGO) + info.attributes |= aSHARED | aSYSTEM; + /* read for group/world and not in default file_mode */ + else if (newmode & ~server->m.file_mode & S_IRUGO) + info.attributes |= aSHARED; + } else +#endif + newmode &= server->m.file_mode; + } + if (newmode & S_IWUGO) + info.attributes &= ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT); + else + info.attributes |= (aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT); + +#ifdef CONFIG_NCPFS_NFS_NS + if (ncp_is_nfs_extras(server, NCP_FINFO(inode)->volNumber)) { + result = ncp_modify_nfs_info(server, + NCP_FINFO(inode)->volNumber, + NCP_FINFO(inode)->dirEntNum, + attr->ia_mode, 0); + if (result != 0) + goto out; + info.attributes &= ~(aSHARED | aSYSTEM); + { + /* mark partial success */ + struct iattr tmpattr; + + tmpattr.ia_valid = ATTR_MODE; + tmpattr.ia_mode = attr->ia_mode; + + setattr_copy(inode, &tmpattr); + mark_inode_dirty(inode); + } + } +#endif + } +#endif + + /* Do SIZE before attributes, otherwise mtime together with size does not work... + */ + if ((attr->ia_valid & ATTR_SIZE) != 0) { + int written; + + ncp_dbg(1, "trying to change size to %llu\n", attr->ia_size); + + if ((result = ncp_make_open(inode, O_WRONLY)) < 0) { + result = -EACCES; + goto out; + } + ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle, + attr->ia_size, 0, "", &written); + + /* According to ndir, the changes only take effect after + closing the file */ + ncp_inode_close(inode); + result = ncp_make_closed(inode); + if (result) + goto out; + + if (attr->ia_size != i_size_read(inode)) { + truncate_setsize(inode, attr->ia_size); + mark_inode_dirty(inode); + } + } + if ((attr->ia_valid & ATTR_CTIME) != 0) { + info_mask |= (DM_CREATE_TIME | DM_CREATE_DATE); + ncp_date_unix2dos(attr->ia_ctime.tv_sec, + &info.creationTime, &info.creationDate); + } + if ((attr->ia_valid & ATTR_MTIME) != 0) { + info_mask |= (DM_MODIFY_TIME | DM_MODIFY_DATE); + ncp_date_unix2dos(attr->ia_mtime.tv_sec, + &info.modifyTime, &info.modifyDate); + } + if ((attr->ia_valid & ATTR_ATIME) != 0) { + __le16 dummy; + info_mask |= (DM_LAST_ACCESS_DATE); + ncp_date_unix2dos(attr->ia_atime.tv_sec, + &dummy, &info.lastAccessDate); + } + if (info_mask != 0) { + result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode), + inode, info_mask, &info); + if (result != 0) { + if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) { + /* NetWare seems not to allow this. I + do not know why. So, just tell the + user everything went fine. This is + a terrible hack, but I do not know + how to do this correctly. */ + result = 0; + } else + goto out; + } +#ifdef CONFIG_NCPFS_STRONG + if ((!result) && (info_mask & DM_ATTRIBUTES)) + NCP_FINFO(inode)->nwattr = info.attributes; +#endif + } + if (result) + goto out; + + setattr_copy(inode, attr); + mark_inode_dirty(inode); + +out: + if (result > 0) + result = -EACCES; + return result; +} + +static struct dentry *ncp_mount(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data) +{ + return mount_nodev(fs_type, flags, data, ncp_fill_super); +} + +static struct file_system_type ncp_fs_type = { + .owner = THIS_MODULE, + .name = "ncpfs", + .mount = ncp_mount, + .kill_sb = kill_anon_super, + .fs_flags = FS_BINARY_MOUNTDATA, +}; +MODULE_ALIAS_FS("ncpfs"); + +static int __init init_ncp_fs(void) +{ + int err; + ncp_dbg(1, "called\n"); + + err = init_inodecache(); + if (err) + goto out1; + err = register_filesystem(&ncp_fs_type); + if (err) + goto out; + return 0; +out: + destroy_inodecache(); +out1: + return err; +} + +static void __exit exit_ncp_fs(void) +{ + ncp_dbg(1, "called\n"); + unregister_filesystem(&ncp_fs_type); + destroy_inodecache(); +} + +module_init(init_ncp_fs) +module_exit(exit_ncp_fs) +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/ncpfs/ioctl.c b/drivers/staging/ncpfs/ioctl.c new file mode 100644 index 000000000000..d378b98cd7b6 --- /dev/null +++ b/drivers/staging/ncpfs/ioctl.c @@ -0,0 +1,923 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ioctl.c + * + * Copyright (C) 1995, 1996 by Volker Lendecke + * Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache + * Modified 1998, 1999 Wolfram Pienkoss for NLS + * + */ + +#include <linux/capability.h> +#include <linux/compat.h> +#include <linux/errno.h> +#include <linux/fs.h> +#include <linux/ioctl.h> +#include <linux/time.h> +#include <linux/mm.h> +#include <linux/mount.h> +#include <linux/slab.h> +#include <linux/highuid.h> +#include <linux/vmalloc.h> +#include <linux/sched.h> +#include <linux/cred.h> + +#include <linux/uaccess.h> + +#include "ncp_fs.h" + +/* maximum limit for ncp_objectname_ioctl */ +#define NCP_OBJECT_NAME_MAX_LEN 4096 +/* maximum limit for ncp_privatedata_ioctl */ +#define NCP_PRIVATE_DATA_MAX_LEN 8192 +/* maximum negotiable packet size */ +#define NCP_PACKET_SIZE_INTERNAL 65536 + +static int +ncp_get_fs_info(struct ncp_server * server, struct inode *inode, + struct ncp_fs_info __user *arg) +{ + struct ncp_fs_info info; + + if (copy_from_user(&info, arg, sizeof(info))) + return -EFAULT; + + if (info.version != NCP_GET_FS_INFO_VERSION) { + ncp_dbg(1, "info.version invalid: %d\n", info.version); + return -EINVAL; + } + /* TODO: info.addr = server->m.serv_addr; */ + SET_UID(info.mounted_uid, from_kuid_munged(current_user_ns(), server->m.mounted_uid)); + info.connection = server->connection; + info.buffer_size = server->buffer_size; + info.volume_number = NCP_FINFO(inode)->volNumber; + info.directory_id = NCP_FINFO(inode)->DosDirNum; + + if (copy_to_user(arg, &info, sizeof(info))) + return -EFAULT; + return 0; +} + +static int +ncp_get_fs_info_v2(struct ncp_server * server, struct inode *inode, + struct ncp_fs_info_v2 __user * arg) +{ + struct ncp_fs_info_v2 info2; + + if (copy_from_user(&info2, arg, sizeof(info2))) + return -EFAULT; + + if (info2.version != NCP_GET_FS_INFO_VERSION_V2) { + ncp_dbg(1, "info.version invalid: %d\n", info2.version); + return -EINVAL; + } + info2.mounted_uid = from_kuid_munged(current_user_ns(), server->m.mounted_uid); + info2.connection = server->connection; + info2.buffer_size = server->buffer_size; + info2.volume_number = NCP_FINFO(inode)->volNumber; + info2.directory_id = NCP_FINFO(inode)->DosDirNum; + info2.dummy1 = info2.dummy2 = info2.dummy3 = 0; + + if (copy_to_user(arg, &info2, sizeof(info2))) + return -EFAULT; + return 0; +} + +#ifdef CONFIG_COMPAT +struct compat_ncp_objectname_ioctl +{ + s32 auth_type; + u32 object_name_len; + compat_caddr_t object_name; /* a userspace data, in most cases user name */ +}; + +struct compat_ncp_fs_info_v2 { + s32 version; + u32 mounted_uid; + u32 connection; + u32 buffer_size; + + u32 volume_number; + u32 directory_id; + + u32 dummy1; + u32 dummy2; + u32 dummy3; +}; + +struct compat_ncp_ioctl_request { + u32 function; + u32 size; + compat_caddr_t data; +}; + +struct compat_ncp_privatedata_ioctl +{ + u32 len; + compat_caddr_t data; /* ~1000 for NDS */ +}; + +#define NCP_IOC_GET_FS_INFO_V2_32 _IOWR('n', 4, struct compat_ncp_fs_info_v2) +#define NCP_IOC_NCPREQUEST_32 _IOR('n', 1, struct compat_ncp_ioctl_request) +#define NCP_IOC_GETOBJECTNAME_32 _IOWR('n', 9, struct compat_ncp_objectname_ioctl) +#define NCP_IOC_SETOBJECTNAME_32 _IOR('n', 9, struct compat_ncp_objectname_ioctl) +#define NCP_IOC_GETPRIVATEDATA_32 _IOWR('n', 10, struct compat_ncp_privatedata_ioctl) +#define NCP_IOC_SETPRIVATEDATA_32 _IOR('n', 10, struct compat_ncp_privatedata_ioctl) + +static int +ncp_get_compat_fs_info_v2(struct ncp_server * server, struct inode *inode, + struct compat_ncp_fs_info_v2 __user * arg) +{ + struct compat_ncp_fs_info_v2 info2; + + if (copy_from_user(&info2, arg, sizeof(info2))) + return -EFAULT; + + if (info2.version != NCP_GET_FS_INFO_VERSION_V2) { + ncp_dbg(1, "info.version invalid: %d\n", info2.version); + return -EINVAL; + } + info2.mounted_uid = from_kuid_munged(current_user_ns(), server->m.mounted_uid); + info2.connection = server->connection; + info2.buffer_size = server->buffer_size; + info2.volume_number = NCP_FINFO(inode)->volNumber; + info2.directory_id = NCP_FINFO(inode)->DosDirNum; + info2.dummy1 = info2.dummy2 = info2.dummy3 = 0; + + if (copy_to_user(arg, &info2, sizeof(info2))) + return -EFAULT; + return 0; +} +#endif + +#define NCP_IOC_GETMOUNTUID16 _IOW('n', 2, u16) +#define NCP_IOC_GETMOUNTUID32 _IOW('n', 2, u32) +#define NCP_IOC_GETMOUNTUID64 _IOW('n', 2, u64) + +#ifdef CONFIG_NCPFS_NLS +/* Here we are select the iocharset and the codepage for NLS. + * Thanks Petr Vandrovec for idea and many hints. + */ +static int +ncp_set_charsets(struct ncp_server* server, struct ncp_nls_ioctl __user *arg) +{ + struct ncp_nls_ioctl user; + struct nls_table *codepage; + struct nls_table *iocharset; + struct nls_table *oldset_io; + struct nls_table *oldset_cp; + int utf8; + int err; + + if (copy_from_user(&user, arg, sizeof(user))) + return -EFAULT; + + codepage = NULL; + user.codepage[NCP_IOCSNAME_LEN] = 0; + if (!user.codepage[0] || !strcmp(user.codepage, "default")) + codepage = load_nls_default(); + else { + codepage = load_nls(user.codepage); + if (!codepage) { + return -EBADRQC; + } + } + + iocharset = NULL; + user.iocharset[NCP_IOCSNAME_LEN] = 0; + if (!user.iocharset[0] || !strcmp(user.iocharset, "default")) { + iocharset = load_nls_default(); + utf8 = 0; + } else if (!strcmp(user.iocharset, "utf8")) { + iocharset = load_nls_default(); + utf8 = 1; + } else { + iocharset = load_nls(user.iocharset); + if (!iocharset) { + unload_nls(codepage); + return -EBADRQC; + } + utf8 = 0; + } + + mutex_lock(&server->root_setup_lock); + if (server->root_setuped) { + oldset_cp = codepage; + oldset_io = iocharset; + err = -EBUSY; + } else { + if (utf8) + NCP_SET_FLAG(server, NCP_FLAG_UTF8); + else + NCP_CLR_FLAG(server, NCP_FLAG_UTF8); + oldset_cp = server->nls_vol; + server->nls_vol = codepage; + oldset_io = server->nls_io; + server->nls_io = iocharset; + err = 0; + } + mutex_unlock(&server->root_setup_lock); + unload_nls(oldset_cp); + unload_nls(oldset_io); + + return err; +} + +static int +ncp_get_charsets(struct ncp_server* server, struct ncp_nls_ioctl __user *arg) +{ + struct ncp_nls_ioctl user; + int len; + + memset(&user, 0, sizeof(user)); + mutex_lock(&server->root_setup_lock); + if (server->nls_vol && server->nls_vol->charset) { + len = strlen(server->nls_vol->charset); + if (len > NCP_IOCSNAME_LEN) + len = NCP_IOCSNAME_LEN; + strncpy(user.codepage, server->nls_vol->charset, len); + user.codepage[len] = 0; + } + + if (NCP_IS_FLAG(server, NCP_FLAG_UTF8)) + strcpy(user.iocharset, "utf8"); + else if (server->nls_io && server->nls_io->charset) { + len = strlen(server->nls_io->charset); + if (len > NCP_IOCSNAME_LEN) + len = NCP_IOCSNAME_LEN; + strncpy(user.iocharset, server->nls_io->charset, len); + user.iocharset[len] = 0; + } + mutex_unlock(&server->root_setup_lock); + + if (copy_to_user(arg, &user, sizeof(user))) + return -EFAULT; + return 0; +} +#endif /* CONFIG_NCPFS_NLS */ + +static long __ncp_ioctl(struct inode *inode, unsigned int cmd, unsigned long arg) +{ + struct ncp_server *server = NCP_SERVER(inode); + int result; + struct ncp_ioctl_request request; + char* bouncebuffer; + void __user *argp = (void __user *)arg; + + switch (cmd) { +#ifdef CONFIG_COMPAT + case NCP_IOC_NCPREQUEST_32: +#endif + case NCP_IOC_NCPREQUEST: +#ifdef CONFIG_COMPAT + if (cmd == NCP_IOC_NCPREQUEST_32) { + struct compat_ncp_ioctl_request request32; + if (copy_from_user(&request32, argp, sizeof(request32))) + return -EFAULT; + request.function = request32.function; + request.size = request32.size; + request.data = compat_ptr(request32.data); + } else +#endif + if (copy_from_user(&request, argp, sizeof(request))) + return -EFAULT; + + if ((request.function > 255) + || (request.size > + NCP_PACKET_SIZE - sizeof(struct ncp_request_header))) { + return -EINVAL; + } + bouncebuffer = vmalloc(NCP_PACKET_SIZE_INTERNAL); + if (!bouncebuffer) + return -ENOMEM; + if (copy_from_user(bouncebuffer, request.data, request.size)) { + vfree(bouncebuffer); + return -EFAULT; + } + ncp_lock_server(server); + + /* FIXME: We hack around in the server's structures + here to be able to use ncp_request */ + + server->has_subfunction = 0; + server->current_size = request.size; + memcpy(server->packet, bouncebuffer, request.size); + + result = ncp_request2(server, request.function, + bouncebuffer, NCP_PACKET_SIZE_INTERNAL); + if (result < 0) + result = -EIO; + else + result = server->reply_size; + ncp_unlock_server(server); + ncp_dbg(1, "copy %d bytes\n", result); + if (result >= 0) + if (copy_to_user(request.data, bouncebuffer, result)) + result = -EFAULT; + vfree(bouncebuffer); + return result; + + case NCP_IOC_CONN_LOGGED_IN: + + if (!(server->m.int_flags & NCP_IMOUNT_LOGGEDIN_POSSIBLE)) + return -EINVAL; + mutex_lock(&server->root_setup_lock); + if (server->root_setuped) + result = -EBUSY; + else { + result = ncp_conn_logged_in(inode->i_sb); + if (result == 0) + server->root_setuped = 1; + } + mutex_unlock(&server->root_setup_lock); + return result; + + case NCP_IOC_GET_FS_INFO: + return ncp_get_fs_info(server, inode, argp); + + case NCP_IOC_GET_FS_INFO_V2: + return ncp_get_fs_info_v2(server, inode, argp); + +#ifdef CONFIG_COMPAT + case NCP_IOC_GET_FS_INFO_V2_32: + return ncp_get_compat_fs_info_v2(server, inode, argp); +#endif + /* we have too many combinations of CONFIG_COMPAT, + * CONFIG_64BIT and CONFIG_UID16, so just handle + * any of the possible ioctls */ + case NCP_IOC_GETMOUNTUID16: + { + u16 uid; + + SET_UID(uid, from_kuid_munged(current_user_ns(), server->m.mounted_uid)); + if (put_user(uid, (u16 __user *)argp)) + return -EFAULT; + return 0; + } + case NCP_IOC_GETMOUNTUID32: + { + uid_t uid = from_kuid_munged(current_user_ns(), server->m.mounted_uid); + if (put_user(uid, (u32 __user *)argp)) + return -EFAULT; + return 0; + } + case NCP_IOC_GETMOUNTUID64: + { + uid_t uid = from_kuid_munged(current_user_ns(), server->m.mounted_uid); + if (put_user(uid, (u64 __user *)argp)) + return -EFAULT; + return 0; + } + case NCP_IOC_GETROOT: + { + struct ncp_setroot_ioctl sr; + + result = -EACCES; + mutex_lock(&server->root_setup_lock); + if (server->m.mounted_vol[0]) { + struct dentry* dentry = inode->i_sb->s_root; + + if (dentry) { + struct inode* s_inode = d_inode(dentry); + + if (s_inode) { + sr.volNumber = NCP_FINFO(s_inode)->volNumber; + sr.dirEntNum = NCP_FINFO(s_inode)->dirEntNum; + sr.namespace = server->name_space[sr.volNumber]; + result = 0; + } else + ncp_dbg(1, "d_inode(s_root)==NULL\n"); + } else + ncp_dbg(1, "s_root==NULL\n"); + } else { + sr.volNumber = -1; + sr.namespace = 0; + sr.dirEntNum = 0; + result = 0; + } + mutex_unlock(&server->root_setup_lock); + if (!result && copy_to_user(argp, &sr, sizeof(sr))) + result = -EFAULT; + return result; + } + + case NCP_IOC_SETROOT: + { + struct ncp_setroot_ioctl sr; + __u32 vnum; + __le32 de; + __le32 dosde; + struct dentry* dentry; + + if (copy_from_user(&sr, argp, sizeof(sr))) + return -EFAULT; + mutex_lock(&server->root_setup_lock); + if (server->root_setuped) + result = -EBUSY; + else { + if (sr.volNumber < 0) { + server->m.mounted_vol[0] = 0; + vnum = NCP_NUMBER_OF_VOLUMES; + de = 0; + dosde = 0; + result = 0; + } else if (sr.volNumber >= NCP_NUMBER_OF_VOLUMES) { + result = -EINVAL; + } else if (ncp_mount_subdir(server, sr.volNumber, + sr.namespace, sr.dirEntNum, + &vnum, &de, &dosde)) { + result = -ENOENT; + } else + result = 0; + + if (result == 0) { + dentry = inode->i_sb->s_root; + if (dentry) { + struct inode* s_inode = d_inode(dentry); + + if (s_inode) { + NCP_FINFO(s_inode)->volNumber = vnum; + NCP_FINFO(s_inode)->dirEntNum = de; + NCP_FINFO(s_inode)->DosDirNum = dosde; + server->root_setuped = 1; + } else { + ncp_dbg(1, "d_inode(s_root)==NULL\n"); + result = -EIO; + } + } else { + ncp_dbg(1, "s_root==NULL\n"); + result = -EIO; + } + } + } + mutex_unlock(&server->root_setup_lock); + + return result; + } + +#ifdef CONFIG_NCPFS_PACKET_SIGNING + case NCP_IOC_SIGN_INIT: + { + struct ncp_sign_init sign; + + if (argp) + if (copy_from_user(&sign, argp, sizeof(sign))) + return -EFAULT; + ncp_lock_server(server); + mutex_lock(&server->rcv.creq_mutex); + if (argp) { + if (server->sign_wanted) { + memcpy(server->sign_root,sign.sign_root,8); + memcpy(server->sign_last,sign.sign_last,16); + server->sign_active = 1; + } + /* ignore when signatures not wanted */ + } else { + server->sign_active = 0; + } + mutex_unlock(&server->rcv.creq_mutex); + ncp_unlock_server(server); + return 0; + } + + case NCP_IOC_SIGN_WANTED: + { + int state; + + ncp_lock_server(server); + state = server->sign_wanted; + ncp_unlock_server(server); + if (put_user(state, (int __user *)argp)) + return -EFAULT; + return 0; + } + + case NCP_IOC_SET_SIGN_WANTED: + { + int newstate; + + /* get only low 8 bits... */ + if (get_user(newstate, (unsigned char __user *)argp)) + return -EFAULT; + result = 0; + ncp_lock_server(server); + if (server->sign_active) { + /* cannot turn signatures OFF when active */ + if (!newstate) + result = -EINVAL; + } else { + server->sign_wanted = newstate != 0; + } + ncp_unlock_server(server); + return result; + } + +#endif /* CONFIG_NCPFS_PACKET_SIGNING */ + +#ifdef CONFIG_NCPFS_IOCTL_LOCKING + case NCP_IOC_LOCKUNLOCK: + { + struct ncp_lock_ioctl rqdata; + + if (copy_from_user(&rqdata, argp, sizeof(rqdata))) + return -EFAULT; + if (rqdata.origin != 0) + return -EINVAL; + /* check for cmd */ + switch (rqdata.cmd) { + case NCP_LOCK_EX: + case NCP_LOCK_SH: + if (rqdata.timeout < 0) + return -EINVAL; + if (rqdata.timeout == 0) + rqdata.timeout = NCP_LOCK_DEFAULT_TIMEOUT; + else if (rqdata.timeout > NCP_LOCK_MAX_TIMEOUT) + rqdata.timeout = NCP_LOCK_MAX_TIMEOUT; + break; + case NCP_LOCK_LOG: + rqdata.timeout = NCP_LOCK_DEFAULT_TIMEOUT; /* has no effect */ + case NCP_LOCK_CLEAR: + break; + default: + return -EINVAL; + } + /* locking needs both read and write access */ + if ((result = ncp_make_open(inode, O_RDWR)) != 0) + { + return result; + } + result = -EISDIR; + if (!S_ISREG(inode->i_mode)) + goto outrel; + if (rqdata.cmd == NCP_LOCK_CLEAR) + { + result = ncp_ClearPhysicalRecord(NCP_SERVER(inode), + NCP_FINFO(inode)->file_handle, + rqdata.offset, + rqdata.length); + if (result > 0) result = 0; /* no such lock */ + } + else + { + int lockcmd; + + switch (rqdata.cmd) + { + case NCP_LOCK_EX: lockcmd=1; break; + case NCP_LOCK_SH: lockcmd=3; break; + default: lockcmd=0; break; + } + result = ncp_LogPhysicalRecord(NCP_SERVER(inode), + NCP_FINFO(inode)->file_handle, + lockcmd, + rqdata.offset, + rqdata.length, + rqdata.timeout); + if (result > 0) result = -EAGAIN; + } +outrel: + ncp_inode_close(inode); + return result; + } +#endif /* CONFIG_NCPFS_IOCTL_LOCKING */ + +#ifdef CONFIG_COMPAT + case NCP_IOC_GETOBJECTNAME_32: + { + struct compat_ncp_objectname_ioctl user; + size_t outl; + + if (copy_from_user(&user, argp, sizeof(user))) + return -EFAULT; + down_read(&server->auth_rwsem); + user.auth_type = server->auth.auth_type; + outl = user.object_name_len; + user.object_name_len = server->auth.object_name_len; + if (outl > user.object_name_len) + outl = user.object_name_len; + result = 0; + if (outl) { + if (copy_to_user(compat_ptr(user.object_name), + server->auth.object_name, + outl)) + result = -EFAULT; + } + up_read(&server->auth_rwsem); + if (!result && copy_to_user(argp, &user, sizeof(user))) + result = -EFAULT; + return result; + } +#endif + + case NCP_IOC_GETOBJECTNAME: + { + struct ncp_objectname_ioctl user; + size_t outl; + + if (copy_from_user(&user, argp, sizeof(user))) + return -EFAULT; + down_read(&server->auth_rwsem); + user.auth_type = server->auth.auth_type; + outl = user.object_name_len; + user.object_name_len = server->auth.object_name_len; + if (outl > user.object_name_len) + outl = user.object_name_len; + result = 0; + if (outl) { + if (copy_to_user(user.object_name, + server->auth.object_name, + outl)) + result = -EFAULT; + } + up_read(&server->auth_rwsem); + if (!result && copy_to_user(argp, &user, sizeof(user))) + result = -EFAULT; + return result; + } + +#ifdef CONFIG_COMPAT + case NCP_IOC_SETOBJECTNAME_32: +#endif + case NCP_IOC_SETOBJECTNAME: + { + struct ncp_objectname_ioctl user; + void* newname; + void* oldname; + size_t oldnamelen; + void* oldprivate; + size_t oldprivatelen; + +#ifdef CONFIG_COMPAT + if (cmd == NCP_IOC_SETOBJECTNAME_32) { + struct compat_ncp_objectname_ioctl user32; + if (copy_from_user(&user32, argp, sizeof(user32))) + return -EFAULT; + user.auth_type = user32.auth_type; + user.object_name_len = user32.object_name_len; + user.object_name = compat_ptr(user32.object_name); + } else +#endif + if (copy_from_user(&user, argp, sizeof(user))) + return -EFAULT; + + if (user.object_name_len > NCP_OBJECT_NAME_MAX_LEN) + return -ENOMEM; + if (user.object_name_len) { + newname = memdup_user(user.object_name, + user.object_name_len); + if (IS_ERR(newname)) + return PTR_ERR(newname); + } else { + newname = NULL; + } + down_write(&server->auth_rwsem); + oldname = server->auth.object_name; + oldnamelen = server->auth.object_name_len; + oldprivate = server->priv.data; + oldprivatelen = server->priv.len; + server->auth.auth_type = user.auth_type; + server->auth.object_name_len = user.object_name_len; + server->auth.object_name = newname; + server->priv.len = 0; + server->priv.data = NULL; + up_write(&server->auth_rwsem); + kfree(oldprivate); + kfree(oldname); + return 0; + } + +#ifdef CONFIG_COMPAT + case NCP_IOC_GETPRIVATEDATA_32: +#endif + case NCP_IOC_GETPRIVATEDATA: + { + struct ncp_privatedata_ioctl user; + size_t outl; + +#ifdef CONFIG_COMPAT + if (cmd == NCP_IOC_GETPRIVATEDATA_32) { + struct compat_ncp_privatedata_ioctl user32; + if (copy_from_user(&user32, argp, sizeof(user32))) + return -EFAULT; + user.len = user32.len; + user.data = compat_ptr(user32.data); + } else +#endif + if (copy_from_user(&user, argp, sizeof(user))) + return -EFAULT; + + down_read(&server->auth_rwsem); + outl = user.len; + user.len = server->priv.len; + if (outl > user.len) outl = user.len; + result = 0; + if (outl) { + if (copy_to_user(user.data, + server->priv.data, + outl)) + result = -EFAULT; + } + up_read(&server->auth_rwsem); + if (result) + return result; +#ifdef CONFIG_COMPAT + if (cmd == NCP_IOC_GETPRIVATEDATA_32) { + struct compat_ncp_privatedata_ioctl user32; + user32.len = user.len; + user32.data = (unsigned long) user.data; + if (copy_to_user(argp, &user32, sizeof(user32))) + return -EFAULT; + } else +#endif + if (copy_to_user(argp, &user, sizeof(user))) + return -EFAULT; + + return 0; + } + +#ifdef CONFIG_COMPAT + case NCP_IOC_SETPRIVATEDATA_32: +#endif + case NCP_IOC_SETPRIVATEDATA: + { + struct ncp_privatedata_ioctl user; + void* new; + void* old; + size_t oldlen; + +#ifdef CONFIG_COMPAT + if (cmd == NCP_IOC_SETPRIVATEDATA_32) { + struct compat_ncp_privatedata_ioctl user32; + if (copy_from_user(&user32, argp, sizeof(user32))) + return -EFAULT; + user.len = user32.len; + user.data = compat_ptr(user32.data); + } else +#endif + if (copy_from_user(&user, argp, sizeof(user))) + return -EFAULT; + + if (user.len > NCP_PRIVATE_DATA_MAX_LEN) + return -ENOMEM; + if (user.len) { + new = memdup_user(user.data, user.len); + if (IS_ERR(new)) + return PTR_ERR(new); + } else { + new = NULL; + } + down_write(&server->auth_rwsem); + old = server->priv.data; + oldlen = server->priv.len; + server->priv.len = user.len; + server->priv.data = new; + up_write(&server->auth_rwsem); + kfree(old); + return 0; + } + +#ifdef CONFIG_NCPFS_NLS + case NCP_IOC_SETCHARSETS: + return ncp_set_charsets(server, argp); + + case NCP_IOC_GETCHARSETS: + return ncp_get_charsets(server, argp); + +#endif /* CONFIG_NCPFS_NLS */ + + case NCP_IOC_SETDENTRYTTL: + { + u_int32_t user; + + if (copy_from_user(&user, argp, sizeof(user))) + return -EFAULT; + /* 20 secs at most... */ + if (user > 20000) + return -EINVAL; + user = (user * HZ) / 1000; + atomic_set(&server->dentry_ttl, user); + return 0; + } + + case NCP_IOC_GETDENTRYTTL: + { + u_int32_t user = (atomic_read(&server->dentry_ttl) * 1000) / HZ; + if (copy_to_user(argp, &user, sizeof(user))) + return -EFAULT; + return 0; + } + + } + return -EINVAL; +} + +long ncp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct inode *inode = file_inode(filp); + struct ncp_server *server = NCP_SERVER(inode); + kuid_t uid = current_uid(); + int need_drop_write = 0; + long ret; + + switch (cmd) { + case NCP_IOC_SETCHARSETS: + case NCP_IOC_CONN_LOGGED_IN: + case NCP_IOC_SETROOT: + if (!capable(CAP_SYS_ADMIN)) { + ret = -EPERM; + goto out; + } + break; + } + if (!uid_eq(server->m.mounted_uid, uid)) { + switch (cmd) { + /* + * Only mount owner can issue these ioctls. Information + * necessary to authenticate to other NDS servers are + * stored here. + */ + case NCP_IOC_GETOBJECTNAME: + case NCP_IOC_SETOBJECTNAME: + case NCP_IOC_GETPRIVATEDATA: + case NCP_IOC_SETPRIVATEDATA: +#ifdef CONFIG_COMPAT + case NCP_IOC_GETOBJECTNAME_32: + case NCP_IOC_SETOBJECTNAME_32: + case NCP_IOC_GETPRIVATEDATA_32: + case NCP_IOC_SETPRIVATEDATA_32: +#endif + ret = -EACCES; + goto out; + /* + * These require write access on the inode if user id + * does not match. Note that they do not write to the + * file... But old code did mnt_want_write, so I keep + * it as is. Of course not for mountpoint owner, as + * that breaks read-only mounts altogether as ncpmount + * needs working NCP_IOC_NCPREQUEST and + * NCP_IOC_GET_FS_INFO. Some of these codes (setdentryttl, + * signinit, setsignwanted) should be probably restricted + * to owner only, or even more to CAP_SYS_ADMIN). + */ + case NCP_IOC_GET_FS_INFO: + case NCP_IOC_GET_FS_INFO_V2: + case NCP_IOC_NCPREQUEST: + case NCP_IOC_SETDENTRYTTL: + case NCP_IOC_SIGN_INIT: + case NCP_IOC_LOCKUNLOCK: + case NCP_IOC_SET_SIGN_WANTED: +#ifdef CONFIG_COMPAT + case NCP_IOC_GET_FS_INFO_V2_32: + case NCP_IOC_NCPREQUEST_32: +#endif + ret = mnt_want_write_file(filp); + if (ret) + goto out; + need_drop_write = 1; + ret = inode_permission(inode, MAY_WRITE); + if (ret) + goto outDropWrite; + break; + /* + * Read access required. + */ + case NCP_IOC_GETMOUNTUID16: + case NCP_IOC_GETMOUNTUID32: + case NCP_IOC_GETMOUNTUID64: + case NCP_IOC_GETROOT: + case NCP_IOC_SIGN_WANTED: + ret = inode_permission(inode, MAY_READ); + if (ret) + goto out; + break; + /* + * Anybody can read these. + */ + case NCP_IOC_GETCHARSETS: + case NCP_IOC_GETDENTRYTTL: + default: + /* Three codes below are protected by CAP_SYS_ADMIN above. */ + case NCP_IOC_SETCHARSETS: + case NCP_IOC_CONN_LOGGED_IN: + case NCP_IOC_SETROOT: + break; + } + } + ret = __ncp_ioctl(inode, cmd, arg); +outDropWrite: + if (need_drop_write) + mnt_drop_write_file(filp); +out: + return ret; +} + +#ifdef CONFIG_COMPAT +long ncp_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + long ret; + + arg = (unsigned long) compat_ptr(arg); + ret = ncp_ioctl(file, cmd, arg); + return ret; +} +#endif diff --git a/drivers/staging/ncpfs/mmap.c b/drivers/staging/ncpfs/mmap.c new file mode 100644 index 000000000000..a5c5cf2ff007 --- /dev/null +++ b/drivers/staging/ncpfs/mmap.c @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * mmap.c + * + * Copyright (C) 1995, 1996 by Volker Lendecke + * Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache + * + */ + +#include <linux/stat.h> +#include <linux/time.h> +#include <linux/kernel.h> +#include <linux/gfp.h> +#include <linux/mm.h> +#include <linux/shm.h> +#include <linux/errno.h> +#include <linux/mman.h> +#include <linux/string.h> +#include <linux/fcntl.h> +#include <linux/memcontrol.h> + +#include <linux/uaccess.h> + +#include "ncp_fs.h" + +/* + * Fill in the supplied page for mmap + * XXX: how are we excluding truncate/invalidate here? Maybe need to lock + * page? + */ +static int ncp_file_mmap_fault(struct vm_fault *vmf) +{ + struct inode *inode = file_inode(vmf->vma->vm_file); + char *pg_addr; + unsigned int already_read; + unsigned int count; + int bufsize; + int pos; /* XXX: loff_t ? */ + + /* + * ncpfs has nothing against high pages as long + * as recvmsg and memset works on it + */ + vmf->page = alloc_page(GFP_HIGHUSER); + if (!vmf->page) + return VM_FAULT_OOM; + pg_addr = kmap(vmf->page); + pos = vmf->pgoff << PAGE_SHIFT; + + count = PAGE_SIZE; + /* what we can read in one go */ + bufsize = NCP_SERVER(inode)->buffer_size; + + already_read = 0; + if (ncp_make_open(inode, O_RDONLY) >= 0) { + while (already_read < count) { + int read_this_time; + int to_read; + + to_read = bufsize - (pos % bufsize); + + to_read = min_t(unsigned int, to_read, count - already_read); + + if (ncp_read_kernel(NCP_SERVER(inode), + NCP_FINFO(inode)->file_handle, + pos, to_read, + pg_addr + already_read, + &read_this_time) != 0) { + read_this_time = 0; + } + pos += read_this_time; + already_read += read_this_time; + + if (read_this_time < to_read) { + break; + } + } + ncp_inode_close(inode); + + } + + if (already_read < PAGE_SIZE) + memset(pg_addr + already_read, 0, PAGE_SIZE - already_read); + flush_dcache_page(vmf->page); + kunmap(vmf->page); + + /* + * If I understand ncp_read_kernel() properly, the above always + * fetches from the network, here the analogue of disk. + * -- nyc + */ + count_vm_event(PGMAJFAULT); + count_memcg_event_mm(vmf->vma->vm_mm, PGMAJFAULT); + return VM_FAULT_MAJOR; +} + +static const struct vm_operations_struct ncp_file_mmap = +{ + .fault = ncp_file_mmap_fault, +}; + + +/* This is used for a general mmap of a ncp file */ +int ncp_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct inode *inode = file_inode(file); + + ncp_dbg(1, "called\n"); + + if (!ncp_conn_valid(NCP_SERVER(inode))) + return -EIO; + + /* only PAGE_COW or read-only supported now */ + if (vma->vm_flags & VM_SHARED) + return -EINVAL; + /* we do not support files bigger than 4GB... We eventually + supports just 4GB... */ + if (vma_pages(vma) + vma->vm_pgoff + > (1U << (32 - PAGE_SHIFT))) + return -EFBIG; + + vma->vm_ops = &ncp_file_mmap; + file_accessed(file); + return 0; +} diff --git a/drivers/staging/ncpfs/ncp_fs.h b/drivers/staging/ncpfs/ncp_fs.h new file mode 100644 index 000000000000..bdd262b6c198 --- /dev/null +++ b/drivers/staging/ncpfs/ncp_fs.h @@ -0,0 +1,101 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#include <linux/ncp_fs.h> +#include "ncp_fs_i.h" +#include "ncp_fs_sb.h" + +#undef NCPFS_PARANOIA +#ifdef NCPFS_PARANOIA +#define ncp_vdbg(fmt, ...) \ + pr_debug(fmt, ##__VA_ARGS__) +#else +#define ncp_vdbg(fmt, ...) \ +do { \ + if (0) \ + pr_debug(fmt, ##__VA_ARGS__); \ +} while (0) +#endif + +#ifndef DEBUG_NCP +#define DEBUG_NCP 0 +#endif + +#if DEBUG_NCP > 0 && !defined(DEBUG) +#define DEBUG +#endif + +#define ncp_dbg(level, fmt, ...) \ +do { \ + if (level <= DEBUG_NCP) \ + pr_debug(fmt, ##__VA_ARGS__); \ +} while (0) + +#define NCP_MAX_RPC_TIMEOUT (6*HZ) + + +struct ncp_entry_info { + struct nw_info_struct i; + ino_t ino; + int opened; + int access; + unsigned int volume; + __u8 file_handle[6]; +}; + +static inline struct ncp_server *NCP_SBP(const struct super_block *sb) +{ + return sb->s_fs_info; +} + +#define NCP_SERVER(inode) NCP_SBP((inode)->i_sb) +static inline struct ncp_inode_info *NCP_FINFO(const struct inode *inode) +{ + return container_of(inode, struct ncp_inode_info, vfs_inode); +} + +/* linux/fs/ncpfs/inode.c */ +int ncp_notify_change(struct dentry *, struct iattr *); +struct inode *ncp_iget(struct super_block *, struct ncp_entry_info *); +void ncp_update_inode(struct inode *, struct ncp_entry_info *); +void ncp_update_inode2(struct inode *, struct ncp_entry_info *); + +/* linux/fs/ncpfs/dir.c */ +extern const struct inode_operations ncp_dir_inode_operations; +extern const struct file_operations ncp_dir_operations; +extern const struct dentry_operations ncp_dentry_operations; +int ncp_conn_logged_in(struct super_block *); +int ncp_date_dos2unix(__le16 time, __le16 date); +void ncp_date_unix2dos(int unix_date, __le16 * time, __le16 * date); + +/* linux/fs/ncpfs/ioctl.c */ +long ncp_ioctl(struct file *, unsigned int, unsigned long); +long ncp_compat_ioctl(struct file *, unsigned int, unsigned long); + +/* linux/fs/ncpfs/sock.c */ +int ncp_request2(struct ncp_server *server, int function, + void* reply, int max_reply_size); +static inline int ncp_request(struct ncp_server *server, int function) { + return ncp_request2(server, function, server->packet, server->packet_size); +} +int ncp_connect(struct ncp_server *server); +int ncp_disconnect(struct ncp_server *server); +void ncp_lock_server(struct ncp_server *server); +void ncp_unlock_server(struct ncp_server *server); + +/* linux/fs/ncpfs/symlink.c */ +#if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS) +extern const struct address_space_operations ncp_symlink_aops; +int ncp_symlink(struct inode*, struct dentry*, const char*); +#endif + +/* linux/fs/ncpfs/file.c */ +extern const struct inode_operations ncp_file_inode_operations; +extern const struct file_operations ncp_file_operations; +int ncp_make_open(struct inode *, int); + +/* linux/fs/ncpfs/mmap.c */ +int ncp_mmap(struct file *, struct vm_area_struct *); + +/* linux/fs/ncpfs/ncplib_kernel.c */ +int ncp_make_closed(struct inode *); + +#include "ncplib_kernel.h" diff --git a/drivers/staging/ncpfs/ncp_fs_i.h b/drivers/staging/ncpfs/ncp_fs_i.h new file mode 100644 index 000000000000..3432bafb53a5 --- /dev/null +++ b/drivers/staging/ncpfs/ncp_fs_i.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * ncp_fs_i.h + * + * Copyright (C) 1995 Volker Lendecke + * + */ + +#ifndef _LINUX_NCP_FS_I +#define _LINUX_NCP_FS_I + +/* + * This is the ncpfs part of the inode structure. This must contain + * all the information we need to work with an inode after creation. + */ +struct ncp_inode_info { + __le32 dirEntNum; + __le32 DosDirNum; + __u8 volNumber; + __le32 nwattr; + struct mutex open_mutex; + atomic_t opened; + int access; + int flags; +#define NCPI_KLUDGE_SYMLINK 0x0001 +#define NCPI_DIR_CACHE 0x0002 + __u8 file_handle[6]; + struct inode vfs_inode; +}; + +#endif /* _LINUX_NCP_FS_I */ diff --git a/drivers/staging/ncpfs/ncp_fs_sb.h b/drivers/staging/ncpfs/ncp_fs_sb.h new file mode 100644 index 000000000000..f06cde4adf71 --- /dev/null +++ b/drivers/staging/ncpfs/ncp_fs_sb.h @@ -0,0 +1,174 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * ncp_fs_sb.h + * + * Copyright (C) 1995, 1996 by Volker Lendecke + * + */ + +#ifndef _NCP_FS_SB +#define _NCP_FS_SB + +#include <linux/types.h> +#include <linux/ncp_mount.h> +#include <linux/net.h> +#include <linux/mutex.h> +#include <linux/backing-dev.h> +#include <linux/workqueue.h> + +#define NCP_DEFAULT_OPTIONS 0 /* 2 for packet signatures */ + +struct sock; + +struct ncp_mount_data_kernel { + unsigned long flags; /* NCP_MOUNT_* flags */ + unsigned int int_flags; /* internal flags */ +#define NCP_IMOUNT_LOGGEDIN_POSSIBLE 0x0001 + kuid_t mounted_uid; /* Who may umount() this filesystem? */ + struct pid *wdog_pid; /* Who cares for our watchdog packets? */ + unsigned int ncp_fd; /* The socket to the ncp port */ + unsigned int time_out; /* How long should I wait after + sending a NCP request? */ + unsigned int retry_count; /* And how often should I retry? */ + unsigned char mounted_vol[NCP_VOLNAME_LEN + 1]; + kuid_t uid; + kgid_t gid; + umode_t file_mode; + umode_t dir_mode; + int info_fd; +}; + +struct ncp_server { + struct rcu_head rcu; + struct ncp_mount_data_kernel m; /* Nearly all of the mount data is of + interest for us later, so we store + it completely. */ + + __u8 name_space[NCP_NUMBER_OF_VOLUMES + 2]; + + struct socket *ncp_sock;/* ncp socket */ + struct socket *info_sock; + + u8 sequence; + u8 task; + u16 connection; /* Remote connection number */ + + u8 completion; /* Status message from server */ + u8 conn_status; /* Bit 4 = 1 ==> Server going down, no + requests allowed anymore. + Bit 0 = 1 ==> Server is down. */ + + int buffer_size; /* Negotiated bufsize */ + + int reply_size; /* Size of last reply */ + + int packet_size; + unsigned char *packet; /* Here we prepare requests and + receive replies */ + unsigned char *txbuf; /* Storage for current request */ + unsigned char *rxbuf; /* Storage for reply to current request */ + + int lock; /* To prevent mismatch in protocols. */ + struct mutex mutex; + + int current_size; /* for packet preparation */ + int has_subfunction; + int ncp_reply_size; + + int root_setuped; + struct mutex root_setup_lock; + + /* info for packet signing */ + int sign_wanted; /* 1=Server needs signed packets */ + int sign_active; /* 0=don't do signing, 1=do */ + char sign_root[8]; /* generated from password and encr. key */ + char sign_last[16]; + + /* Authentication info: NDS or BINDERY, username */ + struct { + int auth_type; + size_t object_name_len; + void* object_name; + int object_type; + } auth; + /* Password info */ + struct { + size_t len; + void* data; + } priv; + struct rw_semaphore auth_rwsem; + + /* nls info: codepage for volume and charset for I/O */ + struct nls_table *nls_vol; + struct nls_table *nls_io; + + /* maximum age in jiffies */ + atomic_t dentry_ttl; + + /* miscellaneous */ + unsigned int flags; + + spinlock_t requests_lock; /* Lock accesses to tx.requests, tx.creq and rcv.creq when STREAM mode */ + + void (*data_ready)(struct sock* sk); + void (*error_report)(struct sock* sk); + void (*write_space)(struct sock* sk); /* STREAM mode only */ + struct { + struct work_struct tq; /* STREAM/DGRAM: data/error ready */ + struct ncp_request_reply* creq; /* STREAM/DGRAM: awaiting reply from this request */ + struct mutex creq_mutex; /* DGRAM only: lock accesses to rcv.creq */ + + unsigned int state; /* STREAM only: receiver state */ + struct { + __u32 magic __packed; + __u32 len __packed; + __u16 type __packed; + __u16 p1 __packed; + __u16 p2 __packed; + __u16 p3 __packed; + __u16 type2 __packed; + } buf; /* STREAM only: temporary buffer */ + unsigned char* ptr; /* STREAM only: pointer to data */ + size_t len; /* STREAM only: length of data to receive */ + } rcv; + struct { + struct list_head requests; /* STREAM only: queued requests */ + struct work_struct tq; /* STREAM only: transmitter ready */ + struct ncp_request_reply* creq; /* STREAM only: currently transmitted entry */ + } tx; + struct timer_list timeout_tm; /* DGRAM only: timeout timer */ + struct work_struct timeout_tq; /* DGRAM only: associated queue, we run timers from process context */ + int timeout_last; /* DGRAM only: current timeout length */ + int timeout_retries; /* DGRAM only: retries left */ + struct { + size_t len; + __u8 data[128]; + } unexpected_packet; +}; + +extern void ncp_tcp_rcv_proc(struct work_struct *work); +extern void ncp_tcp_tx_proc(struct work_struct *work); +extern void ncpdgram_rcv_proc(struct work_struct *work); +extern void ncpdgram_timeout_proc(struct work_struct *work); +extern void ncpdgram_timeout_call(struct timer_list *t); +extern void ncp_tcp_data_ready(struct sock* sk); +extern void ncp_tcp_write_space(struct sock* sk); +extern void ncp_tcp_error_report(struct sock* sk); + +#define NCP_FLAG_UTF8 1 + +#define NCP_CLR_FLAG(server, flag) ((server)->flags &= ~(flag)) +#define NCP_SET_FLAG(server, flag) ((server)->flags |= (flag)) +#define NCP_IS_FLAG(server, flag) ((server)->flags & (flag)) + +static inline int ncp_conn_valid(struct ncp_server *server) +{ + return ((server->conn_status & 0x11) == 0); +} + +static inline void ncp_invalidate_conn(struct ncp_server *server) +{ + server->conn_status |= 0x01; +} + +#endif diff --git a/drivers/staging/ncpfs/ncplib_kernel.c b/drivers/staging/ncpfs/ncplib_kernel.c new file mode 100644 index 000000000000..804adfebba2f --- /dev/null +++ b/drivers/staging/ncpfs/ncplib_kernel.c @@ -0,0 +1,1322 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ncplib_kernel.c + * + * Copyright (C) 1995, 1996 by Volker Lendecke + * Modified for big endian by J.F. Chadima and David S. Miller + * Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache + * Modified 1999 Wolfram Pienkoss for NLS + * Modified 2000 Ben Harris, University of Cambridge for NFS NS meta-info + * + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include "ncp_fs.h" + +static inline void assert_server_locked(struct ncp_server *server) +{ + if (server->lock == 0) { + ncp_dbg(1, "server not locked!\n"); + } +} + +static void ncp_add_byte(struct ncp_server *server, __u8 x) +{ + assert_server_locked(server); + *(__u8 *) (&(server->packet[server->current_size])) = x; + server->current_size += 1; + return; +} + +static void ncp_add_word(struct ncp_server *server, __le16 x) +{ + assert_server_locked(server); + put_unaligned(x, (__le16 *) (&(server->packet[server->current_size]))); + server->current_size += 2; + return; +} + +static void ncp_add_be16(struct ncp_server *server, __u16 x) +{ + assert_server_locked(server); + put_unaligned(cpu_to_be16(x), (__be16 *) (&(server->packet[server->current_size]))); + server->current_size += 2; +} + +static void ncp_add_dword(struct ncp_server *server, __le32 x) +{ + assert_server_locked(server); + put_unaligned(x, (__le32 *) (&(server->packet[server->current_size]))); + server->current_size += 4; + return; +} + +static void ncp_add_be32(struct ncp_server *server, __u32 x) +{ + assert_server_locked(server); + put_unaligned(cpu_to_be32(x), (__be32 *)(&(server->packet[server->current_size]))); + server->current_size += 4; +} + +static inline void ncp_add_dword_lh(struct ncp_server *server, __u32 x) { + ncp_add_dword(server, cpu_to_le32(x)); +} + +static void ncp_add_mem(struct ncp_server *server, const void *source, int size) +{ + assert_server_locked(server); + memcpy(&(server->packet[server->current_size]), source, size); + server->current_size += size; + return; +} + +static void ncp_add_pstring(struct ncp_server *server, const char *s) +{ + int len = strlen(s); + assert_server_locked(server); + if (len > 255) { + ncp_dbg(1, "string too long: %s\n", s); + len = 255; + } + ncp_add_byte(server, len); + ncp_add_mem(server, s, len); + return; +} + +static inline void ncp_init_request(struct ncp_server *server) +{ + ncp_lock_server(server); + + server->current_size = sizeof(struct ncp_request_header); + server->has_subfunction = 0; +} + +static inline void ncp_init_request_s(struct ncp_server *server, int subfunction) +{ + ncp_lock_server(server); + + server->current_size = sizeof(struct ncp_request_header) + 2; + ncp_add_byte(server, subfunction); + + server->has_subfunction = 1; +} + +static inline char * +ncp_reply_data(struct ncp_server *server, int offset) +{ + return &(server->packet[sizeof(struct ncp_reply_header) + offset]); +} + +static inline u8 BVAL(const void *data) +{ + return *(const u8 *)data; +} + +static u8 ncp_reply_byte(struct ncp_server *server, int offset) +{ + return *(const u8 *)ncp_reply_data(server, offset); +} + +static inline u16 WVAL_LH(const void *data) +{ + return get_unaligned_le16(data); +} + +static u16 +ncp_reply_le16(struct ncp_server *server, int offset) +{ + return get_unaligned_le16(ncp_reply_data(server, offset)); +} + +static u16 +ncp_reply_be16(struct ncp_server *server, int offset) +{ + return get_unaligned_be16(ncp_reply_data(server, offset)); +} + +static inline u32 DVAL_LH(const void *data) +{ + return get_unaligned_le32(data); +} + +static __le32 +ncp_reply_dword(struct ncp_server *server, int offset) +{ + return get_unaligned((__le32 *)ncp_reply_data(server, offset)); +} + +static inline __u32 ncp_reply_dword_lh(struct ncp_server* server, int offset) { + return le32_to_cpu(ncp_reply_dword(server, offset)); +} + +int +ncp_negotiate_buffersize(struct ncp_server *server, int size, int *target) +{ + int result; + + ncp_init_request(server); + ncp_add_be16(server, size); + + if ((result = ncp_request(server, 33)) != 0) { + ncp_unlock_server(server); + return result; + } + *target = min_t(unsigned int, ncp_reply_be16(server, 0), size); + + ncp_unlock_server(server); + return 0; +} + + +/* options: + * bit 0 ipx checksum + * bit 1 packet signing + */ +int +ncp_negotiate_size_and_options(struct ncp_server *server, + int size, int options, int *ret_size, int *ret_options) { + int result; + + /* there is minimum */ + if (size < NCP_BLOCK_SIZE) size = NCP_BLOCK_SIZE; + + ncp_init_request(server); + ncp_add_be16(server, size); + ncp_add_byte(server, options); + + if ((result = ncp_request(server, 0x61)) != 0) + { + ncp_unlock_server(server); + return result; + } + + /* NCP over UDP returns 0 (!!!) */ + result = ncp_reply_be16(server, 0); + if (result >= NCP_BLOCK_SIZE) + size = min(result, size); + *ret_size = size; + *ret_options = ncp_reply_byte(server, 4); + + ncp_unlock_server(server); + return 0; +} + +int ncp_get_volume_info_with_number(struct ncp_server* server, + int n, struct ncp_volume_info* target) { + int result; + int len; + + ncp_init_request_s(server, 44); + ncp_add_byte(server, n); + + if ((result = ncp_request(server, 22)) != 0) { + goto out; + } + target->total_blocks = ncp_reply_dword_lh(server, 0); + target->free_blocks = ncp_reply_dword_lh(server, 4); + target->purgeable_blocks = ncp_reply_dword_lh(server, 8); + target->not_yet_purgeable_blocks = ncp_reply_dword_lh(server, 12); + target->total_dir_entries = ncp_reply_dword_lh(server, 16); + target->available_dir_entries = ncp_reply_dword_lh(server, 20); + target->sectors_per_block = ncp_reply_byte(server, 28); + + memset(&(target->volume_name), 0, sizeof(target->volume_name)); + + result = -EIO; + len = ncp_reply_byte(server, 29); + if (len > NCP_VOLNAME_LEN) { + ncp_dbg(1, "volume name too long: %d\n", len); + goto out; + } + memcpy(&(target->volume_name), ncp_reply_data(server, 30), len); + result = 0; +out: + ncp_unlock_server(server); + return result; +} + +int ncp_get_directory_info(struct ncp_server* server, __u8 n, + struct ncp_volume_info* target) { + int result; + int len; + + ncp_init_request_s(server, 45); + ncp_add_byte(server, n); + + if ((result = ncp_request(server, 22)) != 0) { + goto out; + } + target->total_blocks = ncp_reply_dword_lh(server, 0); + target->free_blocks = ncp_reply_dword_lh(server, 4); + target->purgeable_blocks = 0; + target->not_yet_purgeable_blocks = 0; + target->total_dir_entries = ncp_reply_dword_lh(server, 8); + target->available_dir_entries = ncp_reply_dword_lh(server, 12); + target->sectors_per_block = ncp_reply_byte(server, 20); + + memset(&(target->volume_name), 0, sizeof(target->volume_name)); + + result = -EIO; + len = ncp_reply_byte(server, 21); + if (len > NCP_VOLNAME_LEN) { + ncp_dbg(1, "volume name too long: %d\n", len); + goto out; + } + memcpy(&(target->volume_name), ncp_reply_data(server, 22), len); + result = 0; +out: + ncp_unlock_server(server); + return result; +} + +int +ncp_close_file(struct ncp_server *server, const char *file_id) +{ + int result; + + ncp_init_request(server); + ncp_add_byte(server, 0); + ncp_add_mem(server, file_id, 6); + + result = ncp_request(server, 66); + ncp_unlock_server(server); + return result; +} + +int +ncp_make_closed(struct inode *inode) +{ + int err; + + err = 0; + mutex_lock(&NCP_FINFO(inode)->open_mutex); + if (atomic_read(&NCP_FINFO(inode)->opened) == 1) { + atomic_set(&NCP_FINFO(inode)->opened, 0); + err = ncp_close_file(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle); + + if (!err) + ncp_vdbg("volnum=%d, dirent=%u, error=%d\n", + NCP_FINFO(inode)->volNumber, + NCP_FINFO(inode)->dirEntNum, err); + } + mutex_unlock(&NCP_FINFO(inode)->open_mutex); + return err; +} + +static void ncp_add_handle_path(struct ncp_server *server, __u8 vol_num, + __le32 dir_base, int have_dir_base, + const char *path) +{ + ncp_add_byte(server, vol_num); + ncp_add_dword(server, dir_base); + if (have_dir_base != 0) { + ncp_add_byte(server, 1); /* dir_base */ + } else { + ncp_add_byte(server, 0xff); /* no handle */ + } + if (path != NULL) { + ncp_add_byte(server, 1); /* 1 component */ + ncp_add_pstring(server, path); + } else { + ncp_add_byte(server, 0); + } +} + +int ncp_dirhandle_alloc(struct ncp_server* server, __u8 volnum, __le32 dirent, + __u8* dirhandle) { + int result; + + ncp_init_request(server); + ncp_add_byte(server, 12); /* subfunction */ + ncp_add_byte(server, NW_NS_DOS); + ncp_add_byte(server, 0); + ncp_add_word(server, 0); + ncp_add_handle_path(server, volnum, dirent, 1, NULL); + if ((result = ncp_request(server, 87)) == 0) { + *dirhandle = ncp_reply_byte(server, 0); + } + ncp_unlock_server(server); + return result; +} + +int ncp_dirhandle_free(struct ncp_server* server, __u8 dirhandle) { + int result; + + ncp_init_request_s(server, 20); + ncp_add_byte(server, dirhandle); + result = ncp_request(server, 22); + ncp_unlock_server(server); + return result; +} + +void ncp_extract_file_info(const void *structure, struct nw_info_struct *target) +{ + const __u8 *name_len; + const int info_struct_size = offsetof(struct nw_info_struct, nameLen); + + memcpy(target, structure, info_struct_size); + name_len = structure + info_struct_size; + target->nameLen = *name_len; + memcpy(target->entryName, name_len + 1, *name_len); + target->entryName[*name_len] = '\0'; + target->volNumber = le32_to_cpu(target->volNumber); + return; +} + +#ifdef CONFIG_NCPFS_NFS_NS +static inline void ncp_extract_nfs_info(const unsigned char *structure, + struct nw_nfs_info *target) +{ + target->mode = DVAL_LH(structure); + target->rdev = DVAL_LH(structure + 8); +} +#endif + +int ncp_obtain_nfs_info(struct ncp_server *server, + struct nw_info_struct *target) + +{ + int result = 0; +#ifdef CONFIG_NCPFS_NFS_NS + __u32 volnum = target->volNumber; + + if (ncp_is_nfs_extras(server, volnum)) { + ncp_init_request(server); + ncp_add_byte(server, 19); /* subfunction */ + ncp_add_byte(server, server->name_space[volnum]); + ncp_add_byte(server, NW_NS_NFS); + ncp_add_byte(server, 0); + ncp_add_byte(server, volnum); + ncp_add_dword(server, target->dirEntNum); + /* We must retrieve both nlinks and rdev, otherwise some server versions + report zeroes instead of valid data */ + ncp_add_dword_lh(server, NSIBM_NFS_MODE | NSIBM_NFS_NLINKS | NSIBM_NFS_RDEV); + + if ((result = ncp_request(server, 87)) == 0) { + ncp_extract_nfs_info(ncp_reply_data(server, 0), &target->nfs); + ncp_dbg(1, "(%s) mode=0%o, rdev=0x%x\n", + target->entryName, target->nfs.mode, + target->nfs.rdev); + } else { + target->nfs.mode = 0; + target->nfs.rdev = 0; + } + ncp_unlock_server(server); + + } else +#endif + { + target->nfs.mode = 0; + target->nfs.rdev = 0; + } + return result; +} + +/* + * Returns information for a (one-component) name relative to + * the specified directory. + */ +int ncp_obtain_info(struct ncp_server *server, struct inode *dir, const char *path, + struct nw_info_struct *target) +{ + __u8 volnum = NCP_FINFO(dir)->volNumber; + __le32 dirent = NCP_FINFO(dir)->dirEntNum; + int result; + + if (target == NULL) { + pr_err("%s: invalid call\n", __func__); + return -EINVAL; + } + ncp_init_request(server); + ncp_add_byte(server, 6); /* subfunction */ + ncp_add_byte(server, server->name_space[volnum]); + ncp_add_byte(server, server->name_space[volnum]); /* N.B. twice ?? */ + ncp_add_word(server, cpu_to_le16(0x8006)); /* get all */ + ncp_add_dword(server, RIM_ALL); + ncp_add_handle_path(server, volnum, dirent, 1, path); + + if ((result = ncp_request(server, 87)) != 0) + goto out; + ncp_extract_file_info(ncp_reply_data(server, 0), target); + ncp_unlock_server(server); + + result = ncp_obtain_nfs_info(server, target); + return result; + +out: + ncp_unlock_server(server); + return result; +} + +#ifdef CONFIG_NCPFS_NFS_NS +static int +ncp_obtain_DOS_dir_base(struct ncp_server *server, + __u8 ns, __u8 volnum, __le32 dirent, + const char *path, /* At most 1 component */ + __le32 *DOS_dir_base) +{ + int result; + + ncp_init_request(server); + ncp_add_byte(server, 6); /* subfunction */ + ncp_add_byte(server, ns); + ncp_add_byte(server, ns); + ncp_add_word(server, cpu_to_le16(0x8006)); /* get all */ + ncp_add_dword(server, RIM_DIRECTORY); + ncp_add_handle_path(server, volnum, dirent, 1, path); + + if ((result = ncp_request(server, 87)) == 0) + { + if (DOS_dir_base) *DOS_dir_base=ncp_reply_dword(server, 0x34); + } + ncp_unlock_server(server); + return result; +} +#endif /* CONFIG_NCPFS_NFS_NS */ + +static inline int +ncp_get_known_namespace(struct ncp_server *server, __u8 volume) +{ +#if defined(CONFIG_NCPFS_OS2_NS) || defined(CONFIG_NCPFS_NFS_NS) + int result; + __u8 *namespace; + __u16 no_namespaces; + + ncp_init_request(server); + ncp_add_byte(server, 24); /* Subfunction: Get Name Spaces Loaded */ + ncp_add_word(server, 0); + ncp_add_byte(server, volume); + + if ((result = ncp_request(server, 87)) != 0) { + ncp_unlock_server(server); + return NW_NS_DOS; /* not result ?? */ + } + + result = NW_NS_DOS; + no_namespaces = ncp_reply_le16(server, 0); + namespace = ncp_reply_data(server, 2); + + while (no_namespaces > 0) { + ncp_dbg(1, "found %d on %d\n", *namespace, volume); + +#ifdef CONFIG_NCPFS_NFS_NS + if ((*namespace == NW_NS_NFS) && !(server->m.flags&NCP_MOUNT_NO_NFS)) + { + result = NW_NS_NFS; + break; + } +#endif /* CONFIG_NCPFS_NFS_NS */ +#ifdef CONFIG_NCPFS_OS2_NS + if ((*namespace == NW_NS_OS2) && !(server->m.flags&NCP_MOUNT_NO_OS2)) + { + result = NW_NS_OS2; + } +#endif /* CONFIG_NCPFS_OS2_NS */ + namespace += 1; + no_namespaces -= 1; + } + ncp_unlock_server(server); + return result; +#else /* neither OS2 nor NFS - only DOS */ + return NW_NS_DOS; +#endif /* defined(CONFIG_NCPFS_OS2_NS) || defined(CONFIG_NCPFS_NFS_NS) */ +} + +int +ncp_update_known_namespace(struct ncp_server *server, __u8 volume, int *ret_ns) +{ + int ns = ncp_get_known_namespace(server, volume); + + if (ret_ns) + *ret_ns = ns; + + ncp_dbg(1, "namespace[%d] = %d\n", volume, server->name_space[volume]); + + if (server->name_space[volume] == ns) + return 0; + server->name_space[volume] = ns; + return 1; +} + +static int +ncp_ObtainSpecificDirBase(struct ncp_server *server, + __u8 nsSrc, __u8 nsDst, __u8 vol_num, __le32 dir_base, + const char *path, /* At most 1 component */ + __le32 *dirEntNum, __le32 *DosDirNum) +{ + int result; + + ncp_init_request(server); + ncp_add_byte(server, 6); /* subfunction */ + ncp_add_byte(server, nsSrc); + ncp_add_byte(server, nsDst); + ncp_add_word(server, cpu_to_le16(0x8006)); /* get all */ + ncp_add_dword(server, RIM_ALL); + ncp_add_handle_path(server, vol_num, dir_base, 1, path); + + if ((result = ncp_request(server, 87)) != 0) + { + ncp_unlock_server(server); + return result; + } + + if (dirEntNum) + *dirEntNum = ncp_reply_dword(server, 0x30); + if (DosDirNum) + *DosDirNum = ncp_reply_dword(server, 0x34); + ncp_unlock_server(server); + return 0; +} + +int +ncp_mount_subdir(struct ncp_server *server, + __u8 volNumber, __u8 srcNS, __le32 dirEntNum, + __u32* volume, __le32* newDirEnt, __le32* newDosEnt) +{ + int dstNS; + int result; + + ncp_update_known_namespace(server, volNumber, &dstNS); + if ((result = ncp_ObtainSpecificDirBase(server, srcNS, dstNS, volNumber, + dirEntNum, NULL, newDirEnt, newDosEnt)) != 0) + { + return result; + } + *volume = volNumber; + server->m.mounted_vol[1] = 0; + server->m.mounted_vol[0] = 'X'; + return 0; +} + +int +ncp_get_volume_root(struct ncp_server *server, + const char *volname, __u32* volume, __le32* dirent, __le32* dosdirent) +{ + int result; + + ncp_dbg(1, "looking up vol %s\n", volname); + + ncp_init_request(server); + ncp_add_byte(server, 22); /* Subfunction: Generate dir handle */ + ncp_add_byte(server, 0); /* DOS namespace */ + ncp_add_byte(server, 0); /* reserved */ + ncp_add_byte(server, 0); /* reserved */ + ncp_add_byte(server, 0); /* reserved */ + + ncp_add_byte(server, 0); /* faked volume number */ + ncp_add_dword(server, 0); /* faked dir_base */ + ncp_add_byte(server, 0xff); /* Don't have a dir_base */ + ncp_add_byte(server, 1); /* 1 path component */ + ncp_add_pstring(server, volname); + + if ((result = ncp_request(server, 87)) != 0) { + ncp_unlock_server(server); + return result; + } + *dirent = *dosdirent = ncp_reply_dword(server, 4); + *volume = ncp_reply_byte(server, 8); + ncp_unlock_server(server); + return 0; +} + +int +ncp_lookup_volume(struct ncp_server *server, + const char *volname, struct nw_info_struct *target) +{ + int result; + + memset(target, 0, sizeof(*target)); + result = ncp_get_volume_root(server, volname, + &target->volNumber, &target->dirEntNum, &target->DosDirNum); + if (result) { + return result; + } + ncp_update_known_namespace(server, target->volNumber, NULL); + target->nameLen = strlen(volname); + memcpy(target->entryName, volname, target->nameLen+1); + target->attributes = aDIR; + /* set dates to Jan 1, 1986 00:00 */ + target->creationTime = target->modifyTime = cpu_to_le16(0x0000); + target->creationDate = target->modifyDate = target->lastAccessDate = cpu_to_le16(0x0C21); + target->nfs.mode = 0; + return 0; +} + +int ncp_modify_file_or_subdir_dos_info_path(struct ncp_server *server, + struct inode *dir, + const char *path, + __le32 info_mask, + const struct nw_modify_dos_info *info) +{ + __u8 volnum = NCP_FINFO(dir)->volNumber; + __le32 dirent = NCP_FINFO(dir)->dirEntNum; + int result; + + ncp_init_request(server); + ncp_add_byte(server, 7); /* subfunction */ + ncp_add_byte(server, server->name_space[volnum]); + ncp_add_byte(server, 0); /* reserved */ + ncp_add_word(server, cpu_to_le16(0x8006)); /* search attribs: all */ + + ncp_add_dword(server, info_mask); + ncp_add_mem(server, info, sizeof(*info)); + ncp_add_handle_path(server, volnum, dirent, 1, path); + + result = ncp_request(server, 87); + ncp_unlock_server(server); + return result; +} + +int ncp_modify_file_or_subdir_dos_info(struct ncp_server *server, + struct inode *dir, + __le32 info_mask, + const struct nw_modify_dos_info *info) +{ + return ncp_modify_file_or_subdir_dos_info_path(server, dir, NULL, + info_mask, info); +} + +#ifdef CONFIG_NCPFS_NFS_NS +int ncp_modify_nfs_info(struct ncp_server *server, __u8 volnum, __le32 dirent, + __u32 mode, __u32 rdev) + +{ + int result = 0; + + ncp_init_request(server); + if (server->name_space[volnum] == NW_NS_NFS) { + ncp_add_byte(server, 25); /* subfunction */ + ncp_add_byte(server, server->name_space[volnum]); + ncp_add_byte(server, NW_NS_NFS); + ncp_add_byte(server, volnum); + ncp_add_dword(server, dirent); + /* we must always operate on both nlinks and rdev, otherwise + rdev is not set */ + ncp_add_dword_lh(server, NSIBM_NFS_MODE | NSIBM_NFS_NLINKS | NSIBM_NFS_RDEV); + ncp_add_dword_lh(server, mode); + ncp_add_dword_lh(server, 1); /* nlinks */ + ncp_add_dword_lh(server, rdev); + result = ncp_request(server, 87); + } + ncp_unlock_server(server); + return result; +} +#endif + + +static int +ncp_DeleteNSEntry(struct ncp_server *server, + __u8 have_dir_base, __u8 volnum, __le32 dirent, + const char* name, __u8 ns, __le16 attr) +{ + int result; + + ncp_init_request(server); + ncp_add_byte(server, 8); /* subfunction */ + ncp_add_byte(server, ns); + ncp_add_byte(server, 0); /* reserved */ + ncp_add_word(server, attr); /* search attribs: all */ + ncp_add_handle_path(server, volnum, dirent, have_dir_base, name); + + result = ncp_request(server, 87); + ncp_unlock_server(server); + return result; +} + +int +ncp_del_file_or_subdir2(struct ncp_server *server, + struct dentry *dentry) +{ + struct inode *inode = d_inode(dentry); + __u8 volnum; + __le32 dirent; + + if (!inode) { + return 0xFF; /* Any error */ + } + volnum = NCP_FINFO(inode)->volNumber; + dirent = NCP_FINFO(inode)->DosDirNum; + return ncp_DeleteNSEntry(server, 1, volnum, dirent, NULL, NW_NS_DOS, cpu_to_le16(0x8006)); +} + +int +ncp_del_file_or_subdir(struct ncp_server *server, + struct inode *dir, const char *name) +{ + __u8 volnum = NCP_FINFO(dir)->volNumber; + __le32 dirent = NCP_FINFO(dir)->dirEntNum; + int name_space; + + name_space = server->name_space[volnum]; +#ifdef CONFIG_NCPFS_NFS_NS + if (name_space == NW_NS_NFS) + { + int result; + + result=ncp_obtain_DOS_dir_base(server, name_space, volnum, dirent, name, &dirent); + if (result) return result; + name = NULL; + name_space = NW_NS_DOS; + } +#endif /* CONFIG_NCPFS_NFS_NS */ + return ncp_DeleteNSEntry(server, 1, volnum, dirent, name, name_space, cpu_to_le16(0x8006)); +} + +static inline void ConvertToNWfromDWORD(__u16 v0, __u16 v1, __u8 ret[6]) +{ + __le16 *dest = (__le16 *) ret; + dest[1] = cpu_to_le16(v0); + dest[2] = cpu_to_le16(v1); + dest[0] = cpu_to_le16(v0 + 1); + return; +} + +/* If both dir and name are NULL, then in target there's already a + looked-up entry that wants to be opened. */ +int ncp_open_create_file_or_subdir(struct ncp_server *server, + struct inode *dir, const char *name, + int open_create_mode, + __le32 create_attributes, + __le16 desired_acc_rights, + struct ncp_entry_info *target) +{ + __le16 search_attribs = cpu_to_le16(0x0006); + __u8 volnum; + __le32 dirent; + int result; + + volnum = NCP_FINFO(dir)->volNumber; + dirent = NCP_FINFO(dir)->dirEntNum; + + if ((create_attributes & aDIR) != 0) { + search_attribs |= cpu_to_le16(0x8000); + } + ncp_init_request(server); + ncp_add_byte(server, 1); /* subfunction */ + ncp_add_byte(server, server->name_space[volnum]); + ncp_add_byte(server, open_create_mode); + ncp_add_word(server, search_attribs); + ncp_add_dword(server, RIM_ALL); + ncp_add_dword(server, create_attributes); + /* The desired acc rights seem to be the inherited rights mask + for directories */ + ncp_add_word(server, desired_acc_rights); + ncp_add_handle_path(server, volnum, dirent, 1, name); + + if ((result = ncp_request(server, 87)) != 0) + goto out; + if (!(create_attributes & aDIR)) + target->opened = 1; + + /* in target there's a new finfo to fill */ + ncp_extract_file_info(ncp_reply_data(server, 6), &(target->i)); + target->volume = target->i.volNumber; + ConvertToNWfromDWORD(ncp_reply_le16(server, 0), + ncp_reply_le16(server, 2), + target->file_handle); + + ncp_unlock_server(server); + + (void)ncp_obtain_nfs_info(server, &(target->i)); + return 0; + +out: + ncp_unlock_server(server); + return result; +} + +int +ncp_initialize_search(struct ncp_server *server, struct inode *dir, + struct nw_search_sequence *target) +{ + __u8 volnum = NCP_FINFO(dir)->volNumber; + __le32 dirent = NCP_FINFO(dir)->dirEntNum; + int result; + + ncp_init_request(server); + ncp_add_byte(server, 2); /* subfunction */ + ncp_add_byte(server, server->name_space[volnum]); + ncp_add_byte(server, 0); /* reserved */ + ncp_add_handle_path(server, volnum, dirent, 1, NULL); + + result = ncp_request(server, 87); + if (result) + goto out; + memcpy(target, ncp_reply_data(server, 0), sizeof(*target)); + +out: + ncp_unlock_server(server); + return result; +} + +int ncp_search_for_fileset(struct ncp_server *server, + struct nw_search_sequence *seq, + int* more, + int* cnt, + char* buffer, + size_t bufsize, + char** rbuf, + size_t* rsize) +{ + int result; + + ncp_init_request(server); + ncp_add_byte(server, 20); + ncp_add_byte(server, server->name_space[seq->volNumber]); + ncp_add_byte(server, 0); /* datastream */ + ncp_add_word(server, cpu_to_le16(0x8006)); + ncp_add_dword(server, RIM_ALL); + ncp_add_word(server, cpu_to_le16(32767)); /* max returned items */ + ncp_add_mem(server, seq, 9); +#ifdef CONFIG_NCPFS_NFS_NS + if (server->name_space[seq->volNumber] == NW_NS_NFS) { + ncp_add_byte(server, 0); /* 0 byte pattern */ + } else +#endif + { + ncp_add_byte(server, 2); /* 2 byte pattern */ + ncp_add_byte(server, 0xff); /* following is a wildcard */ + ncp_add_byte(server, '*'); + } + result = ncp_request2(server, 87, buffer, bufsize); + if (result) { + ncp_unlock_server(server); + return result; + } + if (server->ncp_reply_size < 12) { + ncp_unlock_server(server); + return 0xFF; + } + *rsize = server->ncp_reply_size - 12; + ncp_unlock_server(server); + buffer = buffer + sizeof(struct ncp_reply_header); + *rbuf = buffer + 12; + *cnt = WVAL_LH(buffer + 10); + *more = BVAL(buffer + 9); + memcpy(seq, buffer, 9); + return 0; +} + +static int +ncp_RenameNSEntry(struct ncp_server *server, + struct inode *old_dir, const char *old_name, __le16 old_type, + struct inode *new_dir, const char *new_name) +{ + int result = -EINVAL; + + if ((old_dir == NULL) || (old_name == NULL) || + (new_dir == NULL) || (new_name == NULL)) + goto out; + + ncp_init_request(server); + ncp_add_byte(server, 4); /* subfunction */ + ncp_add_byte(server, server->name_space[NCP_FINFO(old_dir)->volNumber]); + ncp_add_byte(server, 1); /* rename flag */ + ncp_add_word(server, old_type); /* search attributes */ + + /* source Handle Path */ + ncp_add_byte(server, NCP_FINFO(old_dir)->volNumber); + ncp_add_dword(server, NCP_FINFO(old_dir)->dirEntNum); + ncp_add_byte(server, 1); + ncp_add_byte(server, 1); /* 1 source component */ + + /* dest Handle Path */ + ncp_add_byte(server, NCP_FINFO(new_dir)->volNumber); + ncp_add_dword(server, NCP_FINFO(new_dir)->dirEntNum); + ncp_add_byte(server, 1); + ncp_add_byte(server, 1); /* 1 destination component */ + + /* source path string */ + ncp_add_pstring(server, old_name); + /* dest path string */ + ncp_add_pstring(server, new_name); + + result = ncp_request(server, 87); + ncp_unlock_server(server); +out: + return result; +} + +int ncp_ren_or_mov_file_or_subdir(struct ncp_server *server, + struct inode *old_dir, const char *old_name, + struct inode *new_dir, const char *new_name) +{ + int result; + __le16 old_type = cpu_to_le16(0x06); + +/* If somebody can do it atomic, call me... vandrove@vc.cvut.cz */ + result = ncp_RenameNSEntry(server, old_dir, old_name, old_type, + new_dir, new_name); + if (result == 0xFF) /* File Not Found, try directory */ + { + old_type = cpu_to_le16(0x16); + result = ncp_RenameNSEntry(server, old_dir, old_name, old_type, + new_dir, new_name); + } + if (result != 0x92) return result; /* All except NO_FILES_RENAMED */ + result = ncp_del_file_or_subdir(server, new_dir, new_name); + if (result != 0) return -EACCES; + result = ncp_RenameNSEntry(server, old_dir, old_name, old_type, + new_dir, new_name); + return result; +} + + +/* We have to transfer to/from user space */ +int +ncp_read_kernel(struct ncp_server *server, const char *file_id, + __u32 offset, __u16 to_read, char *target, int *bytes_read) +{ + const char *source; + int result; + + ncp_init_request(server); + ncp_add_byte(server, 0); + ncp_add_mem(server, file_id, 6); + ncp_add_be32(server, offset); + ncp_add_be16(server, to_read); + + if ((result = ncp_request(server, 72)) != 0) { + goto out; + } + *bytes_read = ncp_reply_be16(server, 0); + source = ncp_reply_data(server, 2 + (offset & 1)); + + memcpy(target, source, *bytes_read); +out: + ncp_unlock_server(server); + return result; +} + +/* There is a problem... egrep and some other silly tools do: + x = mmap(NULL, MAP_PRIVATE, PROT_READ|PROT_WRITE, <ncpfs fd>, 32768); + read(<ncpfs fd>, x, 32768); + Now copying read result by copy_to_user causes pagefault. This pagefault + could not be handled because of server was locked due to read. So we have + to use temporary buffer. So ncp_unlock_server must be done before + copy_to_user (and for write, copy_from_user must be done before + ncp_init_request... same applies for send raw packet ioctl). Because of + file is normally read in bigger chunks, caller provides kmalloced + (vmalloced) chunk of memory with size >= to_read... + */ +int +ncp_read_bounce(struct ncp_server *server, const char *file_id, + __u32 offset, __u16 to_read, struct iov_iter *to, + int *bytes_read, void *bounce, __u32 bufsize) +{ + int result; + + ncp_init_request(server); + ncp_add_byte(server, 0); + ncp_add_mem(server, file_id, 6); + ncp_add_be32(server, offset); + ncp_add_be16(server, to_read); + result = ncp_request2(server, 72, bounce, bufsize); + ncp_unlock_server(server); + if (!result) { + int len = get_unaligned_be16((char *)bounce + + sizeof(struct ncp_reply_header)); + result = -EIO; + if (len <= to_read) { + char* source; + + source = (char*)bounce + + sizeof(struct ncp_reply_header) + 2 + + (offset & 1); + *bytes_read = len; + result = 0; + if (copy_to_iter(source, len, to) != len) + result = -EFAULT; + } + } + return result; +} + +int +ncp_write_kernel(struct ncp_server *server, const char *file_id, + __u32 offset, __u16 to_write, + const char *source, int *bytes_written) +{ + int result; + + ncp_init_request(server); + ncp_add_byte(server, 0); + ncp_add_mem(server, file_id, 6); + ncp_add_be32(server, offset); + ncp_add_be16(server, to_write); + ncp_add_mem(server, source, to_write); + + if ((result = ncp_request(server, 73)) == 0) + *bytes_written = to_write; + ncp_unlock_server(server); + return result; +} + +#ifdef CONFIG_NCPFS_IOCTL_LOCKING +int +ncp_LogPhysicalRecord(struct ncp_server *server, const char *file_id, + __u8 locktype, __u32 offset, __u32 length, __u16 timeout) +{ + int result; + + ncp_init_request(server); + ncp_add_byte(server, locktype); + ncp_add_mem(server, file_id, 6); + ncp_add_be32(server, offset); + ncp_add_be32(server, length); + ncp_add_be16(server, timeout); + + if ((result = ncp_request(server, 0x1A)) != 0) + { + ncp_unlock_server(server); + return result; + } + ncp_unlock_server(server); + return 0; +} + +int +ncp_ClearPhysicalRecord(struct ncp_server *server, const char *file_id, + __u32 offset, __u32 length) +{ + int result; + + ncp_init_request(server); + ncp_add_byte(server, 0); /* who knows... lanalyzer says that */ + ncp_add_mem(server, file_id, 6); + ncp_add_be32(server, offset); + ncp_add_be32(server, length); + + if ((result = ncp_request(server, 0x1E)) != 0) + { + ncp_unlock_server(server); + return result; + } + ncp_unlock_server(server); + return 0; +} +#endif /* CONFIG_NCPFS_IOCTL_LOCKING */ + +#ifdef CONFIG_NCPFS_NLS +/* This are the NLS conversion routines with inspirations and code parts + * from the vfat file system and hints from Petr Vandrovec. + */ + +int +ncp__io2vol(struct ncp_server *server, unsigned char *vname, unsigned int *vlen, + const unsigned char *iname, unsigned int ilen, int cc) +{ + struct nls_table *in = server->nls_io; + struct nls_table *out = server->nls_vol; + unsigned char *vname_start; + unsigned char *vname_end; + const unsigned char *iname_end; + + iname_end = iname + ilen; + vname_start = vname; + vname_end = vname + *vlen - 1; + + while (iname < iname_end) { + int chl; + wchar_t ec; + + if (NCP_IS_FLAG(server, NCP_FLAG_UTF8)) { + int k; + unicode_t u; + + k = utf8_to_utf32(iname, iname_end - iname, &u); + if (k < 0 || u > MAX_WCHAR_T) + return -EINVAL; + iname += k; + ec = u; + } else { + if (*iname == NCP_ESC) { + int k; + + if (iname_end - iname < 5) + goto nospec; + + ec = 0; + for (k = 1; k < 5; k++) { + unsigned char nc; + + nc = iname[k] - '0'; + if (nc >= 10) { + nc -= 'A' - '0' - 10; + if ((nc < 10) || (nc > 15)) { + goto nospec; + } + } + ec = (ec << 4) | nc; + } + iname += 5; + } else { +nospec:; + if ( (chl = in->char2uni(iname, iname_end - iname, &ec)) < 0) + return chl; + iname += chl; + } + } + + /* unitoupper should be here! */ + + chl = out->uni2char(ec, vname, vname_end - vname); + if (chl < 0) + return chl; + + /* this is wrong... */ + if (cc) { + int chi; + + for (chi = 0; chi < chl; chi++){ + vname[chi] = ncp_toupper(out, vname[chi]); + } + } + vname += chl; + } + + *vname = 0; + *vlen = vname - vname_start; + return 0; +} + +int +ncp__vol2io(struct ncp_server *server, unsigned char *iname, unsigned int *ilen, + const unsigned char *vname, unsigned int vlen, int cc) +{ + struct nls_table *in = server->nls_vol; + struct nls_table *out = server->nls_io; + const unsigned char *vname_end; + unsigned char *iname_start; + unsigned char *iname_end; + unsigned char *vname_cc; + int err; + + vname_cc = NULL; + + if (cc) { + int i; + + /* this is wrong! */ + vname_cc = kmalloc(vlen, GFP_KERNEL); + if (!vname_cc) + return -ENOMEM; + for (i = 0; i < vlen; i++) + vname_cc[i] = ncp_tolower(in, vname[i]); + vname = vname_cc; + } + + iname_start = iname; + iname_end = iname + *ilen - 1; + vname_end = vname + vlen; + + while (vname < vname_end) { + wchar_t ec; + int chl; + + if ( (chl = in->char2uni(vname, vname_end - vname, &ec)) < 0) { + err = chl; + goto quit; + } + vname += chl; + + /* unitolower should be here! */ + + if (NCP_IS_FLAG(server, NCP_FLAG_UTF8)) { + int k; + + k = utf32_to_utf8(ec, iname, iname_end - iname); + if (k < 0) { + err = -ENAMETOOLONG; + goto quit; + } + iname += k; + } else { + if ( (chl = out->uni2char(ec, iname, iname_end - iname)) >= 0) { + iname += chl; + } else { + int k; + + if (iname_end - iname < 5) { + err = -ENAMETOOLONG; + goto quit; + } + *iname = NCP_ESC; + for (k = 4; k > 0; k--) { + unsigned char v; + + v = (ec & 0xF) + '0'; + if (v > '9') { + v += 'A' - '9' - 1; + } + iname[k] = v; + ec >>= 4; + } + iname += 5; + } + } + } + + *iname = 0; + *ilen = iname - iname_start; + err = 0; +quit:; + if (cc) + kfree(vname_cc); + return err; +} + +#else + +int +ncp__io2vol(unsigned char *vname, unsigned int *vlen, + const unsigned char *iname, unsigned int ilen, int cc) +{ + int i; + + if (*vlen <= ilen) + return -ENAMETOOLONG; + + if (cc) + for (i = 0; i < ilen; i++) { + *vname = toupper(*iname); + vname++; + iname++; + } + else { + memmove(vname, iname, ilen); + vname += ilen; + } + + *vlen = ilen; + *vname = 0; + return 0; +} + +int +ncp__vol2io(unsigned char *iname, unsigned int *ilen, + const unsigned char *vname, unsigned int vlen, int cc) +{ + int i; + + if (*ilen <= vlen) + return -ENAMETOOLONG; + + if (cc) + for (i = 0; i < vlen; i++) { + *iname = tolower(*vname); + iname++; + vname++; + } + else { + memmove(iname, vname, vlen); + iname += vlen; + } + + *ilen = vlen; + *iname = 0; + return 0; +} + +#endif diff --git a/drivers/staging/ncpfs/ncplib_kernel.h b/drivers/staging/ncpfs/ncplib_kernel.h new file mode 100644 index 000000000000..aaae8aa9bf7d --- /dev/null +++ b/drivers/staging/ncpfs/ncplib_kernel.h @@ -0,0 +1,215 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * ncplib_kernel.h + * + * Copyright (C) 1995, 1996 by Volker Lendecke + * Modified for big endian by J.F. Chadima and David S. Miller + * Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache + * Modified 1998, 1999 Wolfram Pienkoss for NLS + * Modified 1999 Wolfram Pienkoss for directory caching + * + */ + +#ifndef _NCPLIB_H +#define _NCPLIB_H + + +#include <linux/fs.h> +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/slab.h> +#include <linux/stat.h> +#include <linux/fcntl.h> +#include <linux/pagemap.h> + +#include <linux/uaccess.h> +#include <asm/byteorder.h> +#include <asm/unaligned.h> +#include <asm/string.h> + +#ifdef CONFIG_NCPFS_NLS +#include <linux/nls.h> +#else +#include <linux/ctype.h> +#endif /* CONFIG_NCPFS_NLS */ + +#define NCP_MIN_SYMLINK_SIZE 8 +#define NCP_MAX_SYMLINK_SIZE 512 + +#define NCP_BLOCK_SHIFT 9 +#define NCP_BLOCK_SIZE (1 << (NCP_BLOCK_SHIFT)) + +int ncp_negotiate_buffersize(struct ncp_server *, int, int *); +int ncp_negotiate_size_and_options(struct ncp_server *server, int size, + int options, int *ret_size, int *ret_options); + +int ncp_get_volume_info_with_number(struct ncp_server* server, int n, + struct ncp_volume_info *target); + +int ncp_get_directory_info(struct ncp_server* server, __u8 dirhandle, + struct ncp_volume_info* target); + +int ncp_close_file(struct ncp_server *, const char *); +static inline int ncp_read_bounce_size(__u32 size) { + return sizeof(struct ncp_reply_header) + 2 + 2 + size + 8; +}; +int ncp_read_bounce(struct ncp_server *, const char *, __u32, __u16, + struct iov_iter *, int *, void *bounce, __u32 bouncelen); +int ncp_read_kernel(struct ncp_server *, const char *, __u32, __u16, + char *, int *); +int ncp_write_kernel(struct ncp_server *, const char *, __u32, __u16, + const char *, int *); + +static inline void ncp_inode_close(struct inode *inode) { + atomic_dec(&NCP_FINFO(inode)->opened); +} + +void ncp_extract_file_info(const void* src, struct nw_info_struct* target); +int ncp_obtain_info(struct ncp_server *server, struct inode *, const char *, + struct nw_info_struct *target); +int ncp_obtain_nfs_info(struct ncp_server *server, struct nw_info_struct *target); +int ncp_update_known_namespace(struct ncp_server *server, __u8 volume, int *ret_ns); +int ncp_get_volume_root(struct ncp_server *server, const char *volname, + __u32 *volume, __le32 *dirent, __le32 *dosdirent); +int ncp_lookup_volume(struct ncp_server *, const char *, struct nw_info_struct *); +int ncp_modify_file_or_subdir_dos_info(struct ncp_server *, struct inode *, + __le32, const struct nw_modify_dos_info *info); +int ncp_modify_file_or_subdir_dos_info_path(struct ncp_server *, struct inode *, + const char* path, __le32, const struct nw_modify_dos_info *info); +int ncp_modify_nfs_info(struct ncp_server *, __u8 volnum, __le32 dirent, + __u32 mode, __u32 rdev); + +int ncp_del_file_or_subdir2(struct ncp_server *, struct dentry*); +int ncp_del_file_or_subdir(struct ncp_server *, struct inode *, const char *); +int ncp_open_create_file_or_subdir(struct ncp_server *, struct inode *, const char *, + int, __le32, __le16, struct ncp_entry_info *); + +int ncp_initialize_search(struct ncp_server *, struct inode *, + struct nw_search_sequence *target); +int ncp_search_for_fileset(struct ncp_server *server, + struct nw_search_sequence *seq, + int* more, int* cnt, + char* buffer, size_t bufsize, + char** rbuf, size_t* rsize); + +int ncp_ren_or_mov_file_or_subdir(struct ncp_server *server, + struct inode *, const char *, struct inode *, const char *); + + +int +ncp_LogPhysicalRecord(struct ncp_server *server, + const char *file_id, __u8 locktype, + __u32 offset, __u32 length, __u16 timeout); + +#ifdef CONFIG_NCPFS_IOCTL_LOCKING +int +ncp_ClearPhysicalRecord(struct ncp_server *server, + const char *file_id, + __u32 offset, __u32 length); +#endif /* CONFIG_NCPFS_IOCTL_LOCKING */ + +int +ncp_mount_subdir(struct ncp_server *, __u8, __u8, __le32, + __u32* volume, __le32* dirent, __le32* dosdirent); +int ncp_dirhandle_alloc(struct ncp_server *, __u8 vol, __le32 dirent, __u8 *dirhandle); +int ncp_dirhandle_free(struct ncp_server *, __u8 dirhandle); + +int ncp_create_new(struct inode *dir, struct dentry *dentry, + umode_t mode, dev_t rdev, __le32 attributes); + +static inline int ncp_is_nfs_extras(struct ncp_server* server, unsigned int volnum) { +#ifdef CONFIG_NCPFS_NFS_NS + return (server->m.flags & NCP_MOUNT_NFS_EXTRAS) && + (server->name_space[volnum] == NW_NS_NFS); +#else + return 0; +#endif +} + +#ifdef CONFIG_NCPFS_NLS + +int ncp__io2vol(struct ncp_server *, unsigned char *, unsigned int *, + const unsigned char *, unsigned int, int); +int ncp__vol2io(struct ncp_server *, unsigned char *, unsigned int *, + const unsigned char *, unsigned int, int); + +#define NCP_ESC ':' +#define NCP_IO_TABLE(sb) (NCP_SBP(sb)->nls_io) +#define ncp_tolower(t, c) nls_tolower(t, c) +#define ncp_toupper(t, c) nls_toupper(t, c) +#define ncp_strnicmp(t, s1, s2, len) \ + nls_strnicmp(t, s1, s2, len) +#define ncp_io2vol(S,m,i,n,k,U) ncp__io2vol(S,m,i,n,k,U) +#define ncp_vol2io(S,m,i,n,k,U) ncp__vol2io(S,m,i,n,k,U) + +#else + +int ncp__io2vol(unsigned char *, unsigned int *, + const unsigned char *, unsigned int, int); +int ncp__vol2io(unsigned char *, unsigned int *, + const unsigned char *, unsigned int, int); + +#define NCP_IO_TABLE(sb) NULL +#define ncp_tolower(t, c) tolower(c) +#define ncp_toupper(t, c) toupper(c) +#define ncp_io2vol(S,m,i,n,k,U) ncp__io2vol(m,i,n,k,U) +#define ncp_vol2io(S,m,i,n,k,U) ncp__vol2io(m,i,n,k,U) + + +static inline int ncp_strnicmp(const struct nls_table *t, + const unsigned char *s1, const unsigned char *s2, int len) +{ + while (len--) { + if (tolower(*s1++) != tolower(*s2++)) + return 1; + } + + return 0; +} + +#endif /* CONFIG_NCPFS_NLS */ + +#define NCP_GET_AGE(dentry) (jiffies - (dentry)->d_time) +#define NCP_MAX_AGE(server) atomic_read(&(server)->dentry_ttl) +#define NCP_TEST_AGE(server,dentry) (NCP_GET_AGE(dentry) < NCP_MAX_AGE(server)) + +static inline void +ncp_age_dentry(struct ncp_server* server, struct dentry* dentry) +{ + dentry->d_time = jiffies - NCP_MAX_AGE(server); +} + +static inline void +ncp_new_dentry(struct dentry* dentry) +{ + dentry->d_time = jiffies; +} + +struct ncp_cache_head { + time_t mtime; + unsigned long time; /* cache age */ + unsigned long end; /* last valid fpos in cache */ + int eof; +}; + +#define NCP_DIRCACHE_SIZE ((int)(PAGE_SIZE/sizeof(struct dentry *))) +union ncp_dir_cache { + struct ncp_cache_head head; + struct dentry *dentry[NCP_DIRCACHE_SIZE]; +}; + +#define NCP_FIRSTCACHE_SIZE ((int)((NCP_DIRCACHE_SIZE * \ + sizeof(struct dentry *) - sizeof(struct ncp_cache_head)) / \ + sizeof(struct dentry *))) + +#define NCP_DIRCACHE_START (NCP_DIRCACHE_SIZE - NCP_FIRSTCACHE_SIZE) + +struct ncp_cache_control { + struct ncp_cache_head head; + struct page *page; + union ncp_dir_cache *cache; + unsigned long fpos, ofs; + int filled, valid, idx; +}; + +#endif /* _NCPLIB_H */ diff --git a/drivers/staging/ncpfs/ncpsign_kernel.c b/drivers/staging/ncpfs/ncpsign_kernel.c new file mode 100644 index 000000000000..8085b1a3ba47 --- /dev/null +++ b/drivers/staging/ncpfs/ncpsign_kernel.c @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ncpsign_kernel.c + * + * Arne de Bruijn (arne@knoware.nl), 1997 + * + */ + + +#ifdef CONFIG_NCPFS_PACKET_SIGNING + +#include <linux/string.h> +#include <linux/ncp.h> +#include <linux/bitops.h> +#include "ncp_fs.h" +#include "ncpsign_kernel.h" + +/* i386: 32-bit, little endian, handles mis-alignment */ +#ifdef __i386__ +#define GET_LE32(p) (*(const int *)(p)) +#define PUT_LE32(p,v) { *(int *)(p)=v; } +#else +/* from include/ncplib.h */ +#define BVAL(buf,pos) (((const __u8 *)(buf))[pos]) +#define PVAL(buf,pos) ((unsigned)BVAL(buf,pos)) +#define BSET(buf,pos,val) (((__u8 *)(buf))[pos] = (val)) + +static inline __u16 +WVAL_LH(const __u8 * buf, int pos) +{ + return PVAL(buf, pos) | PVAL(buf, pos + 1) << 8; +} +static inline __u32 +DVAL_LH(const __u8 * buf, int pos) +{ + return WVAL_LH(buf, pos) | WVAL_LH(buf, pos + 2) << 16; +} +static inline void +WSET_LH(__u8 * buf, int pos, __u16 val) +{ + BSET(buf, pos, val & 0xff); + BSET(buf, pos + 1, val >> 8); +} +static inline void +DSET_LH(__u8 * buf, int pos, __u32 val) +{ + WSET_LH(buf, pos, val & 0xffff); + WSET_LH(buf, pos + 2, val >> 16); +} + +#define GET_LE32(p) DVAL_LH(p,0) +#define PUT_LE32(p,v) DSET_LH(p,0,v) +#endif + +static void nwsign(char *r_data1, char *r_data2, char *outdata) { + int i; + unsigned int w0,w1,w2,w3; + static int rbit[4]={0, 2, 1, 3}; +#ifdef __i386__ + unsigned int *data2=(unsigned int *)r_data2; +#else + unsigned int data2[16]; + for (i=0;i<16;i++) + data2[i]=GET_LE32(r_data2+(i<<2)); +#endif + w0=GET_LE32(r_data1); + w1=GET_LE32(r_data1+4); + w2=GET_LE32(r_data1+8); + w3=GET_LE32(r_data1+12); + for (i=0;i<16;i+=4) { + w0=rol32(w0 + ((w1 & w2) | ((~w1) & w3)) + data2[i+0],3); + w3=rol32(w3 + ((w0 & w1) | ((~w0) & w2)) + data2[i+1],7); + w2=rol32(w2 + ((w3 & w0) | ((~w3) & w1)) + data2[i+2],11); + w1=rol32(w1 + ((w2 & w3) | ((~w2) & w0)) + data2[i+3],19); + } + for (i=0;i<4;i++) { + w0=rol32(w0 + (((w2 | w3) & w1) | (w2 & w3)) + 0x5a827999 + data2[i+0],3); + w3=rol32(w3 + (((w1 | w2) & w0) | (w1 & w2)) + 0x5a827999 + data2[i+4],5); + w2=rol32(w2 + (((w0 | w1) & w3) | (w0 & w1)) + 0x5a827999 + data2[i+8],9); + w1=rol32(w1 + (((w3 | w0) & w2) | (w3 & w0)) + 0x5a827999 + data2[i+12],13); + } + for (i=0;i<4;i++) { + w0=rol32(w0 + ((w1 ^ w2) ^ w3) + 0x6ed9eba1 + data2[rbit[i]+0],3); + w3=rol32(w3 + ((w0 ^ w1) ^ w2) + 0x6ed9eba1 + data2[rbit[i]+8],9); + w2=rol32(w2 + ((w3 ^ w0) ^ w1) + 0x6ed9eba1 + data2[rbit[i]+4],11); + w1=rol32(w1 + ((w2 ^ w3) ^ w0) + 0x6ed9eba1 + data2[rbit[i]+12],15); + } + PUT_LE32(outdata,(w0+GET_LE32(r_data1)) & 0xffffffff); + PUT_LE32(outdata+4,(w1+GET_LE32(r_data1+4)) & 0xffffffff); + PUT_LE32(outdata+8,(w2+GET_LE32(r_data1+8)) & 0xffffffff); + PUT_LE32(outdata+12,(w3+GET_LE32(r_data1+12)) & 0xffffffff); +} + +/* Make a signature for the current packet and add it at the end of the */ +/* packet. */ +void __sign_packet(struct ncp_server *server, const char *packet, size_t size, __u32 totalsize, void *sign_buff) { + unsigned char data[64]; + + memcpy(data, server->sign_root, 8); + *(__u32*)(data + 8) = totalsize; + if (size < 52) { + memcpy(data + 12, packet, size); + memset(data + 12 + size, 0, 52 - size); + } else { + memcpy(data + 12, packet, 52); + } + nwsign(server->sign_last, data, server->sign_last); + memcpy(sign_buff, server->sign_last, 8); +} + +int sign_verify_reply(struct ncp_server *server, const char *packet, size_t size, __u32 totalsize, const void *sign_buff) { + unsigned char data[64]; + unsigned char hash[16]; + + memcpy(data, server->sign_root, 8); + *(__u32*)(data + 8) = totalsize; + if (size < 52) { + memcpy(data + 12, packet, size); + memset(data + 12 + size, 0, 52 - size); + } else { + memcpy(data + 12, packet, 52); + } + nwsign(server->sign_last, data, hash); + return memcmp(sign_buff, hash, 8); +} + +#endif /* CONFIG_NCPFS_PACKET_SIGNING */ + diff --git a/drivers/staging/ncpfs/ncpsign_kernel.h b/drivers/staging/ncpfs/ncpsign_kernel.h new file mode 100644 index 000000000000..57ff0a0650b8 --- /dev/null +++ b/drivers/staging/ncpfs/ncpsign_kernel.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * ncpsign_kernel.h + * + * Arne de Bruijn (arne@knoware.nl), 1997 + * + */ + +#ifndef _NCPSIGN_KERNEL_H +#define _NCPSIGN_KERNEL_H + +#ifdef CONFIG_NCPFS_PACKET_SIGNING +void __sign_packet(struct ncp_server *server, const char *data, size_t size, __u32 totalsize, void *sign_buff); +int sign_verify_reply(struct ncp_server *server, const char *data, size_t size, __u32 totalsize, const void *sign_buff); +#endif + +static inline size_t sign_packet(struct ncp_server *server, const char *data, size_t size, __u32 totalsize, void *sign_buff) { +#ifdef CONFIG_NCPFS_PACKET_SIGNING + if (server->sign_active) { + __sign_packet(server, data, size, totalsize, sign_buff); + return 8; + } +#endif + return 0; +} + +#endif diff --git a/drivers/staging/ncpfs/sock.c b/drivers/staging/ncpfs/sock.c new file mode 100644 index 000000000000..4c13174d85b7 --- /dev/null +++ b/drivers/staging/ncpfs/sock.c @@ -0,0 +1,855 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * linux/fs/ncpfs/sock.c + * + * Copyright (C) 1992, 1993 Rick Sladkey + * + * Modified 1995, 1996 by Volker Lendecke to be usable for ncp + * Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache + * + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include <linux/time.h> +#include <linux/errno.h> +#include <linux/socket.h> +#include <linux/fcntl.h> +#include <linux/stat.h> +#include <linux/string.h> +#include <linux/sched/signal.h> +#include <linux/uaccess.h> +#include <linux/in.h> +#include <linux/net.h> +#include <linux/mm.h> +#include <linux/netdevice.h> +#include <linux/signal.h> +#include <linux/slab.h> +#include <net/scm.h> +#include <net/sock.h> +#include <linux/ipx.h> +#include <linux/poll.h> +#include <linux/file.h> + +#include "ncp_fs.h" + +#include "ncpsign_kernel.h" + +static int _recv(struct socket *sock, void *buf, int size, unsigned flags) +{ + struct msghdr msg = {NULL, }; + struct kvec iov = {buf, size}; + iov_iter_kvec(&msg.msg_iter, READ | ITER_KVEC, &iov, 1, size); + return sock_recvmsg(sock, &msg, flags); +} + +static int _send(struct socket *sock, const void *buff, int len) +{ + struct msghdr msg = { .msg_flags = 0 }; + struct kvec vec = {.iov_base = (void *)buff, .iov_len = len}; + iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, &vec, 1, len); + return sock_sendmsg(sock, &msg); +} + +struct ncp_request_reply { + struct list_head req; + wait_queue_head_t wq; + atomic_t refs; + unsigned char* reply_buf; + size_t datalen; + int result; + enum { RQ_DONE, RQ_INPROGRESS, RQ_QUEUED, RQ_IDLE, RQ_ABANDONED } status; + struct iov_iter from; + struct kvec tx_iov[3]; + u_int16_t tx_type; + u_int32_t sign[6]; +}; + +static inline struct ncp_request_reply* ncp_alloc_req(void) +{ + struct ncp_request_reply *req; + + req = kmalloc(sizeof(struct ncp_request_reply), GFP_KERNEL); + if (!req) + return NULL; + + init_waitqueue_head(&req->wq); + atomic_set(&req->refs, (1)); + req->status = RQ_IDLE; + + return req; +} + +static void ncp_req_get(struct ncp_request_reply *req) +{ + atomic_inc(&req->refs); +} + +static void ncp_req_put(struct ncp_request_reply *req) +{ + if (atomic_dec_and_test(&req->refs)) + kfree(req); +} + +void ncp_tcp_data_ready(struct sock *sk) +{ + struct ncp_server *server = sk->sk_user_data; + + server->data_ready(sk); + schedule_work(&server->rcv.tq); +} + +void ncp_tcp_error_report(struct sock *sk) +{ + struct ncp_server *server = sk->sk_user_data; + + server->error_report(sk); + schedule_work(&server->rcv.tq); +} + +void ncp_tcp_write_space(struct sock *sk) +{ + struct ncp_server *server = sk->sk_user_data; + + /* We do not need any locking: we first set tx.creq, and then we do sendmsg, + not vice versa... */ + server->write_space(sk); + if (server->tx.creq) + schedule_work(&server->tx.tq); +} + +void ncpdgram_timeout_call(struct timer_list *t) +{ + struct ncp_server *server = from_timer(server, t, timeout_tm); + + schedule_work(&server->timeout_tq); +} + +static inline void ncp_finish_request(struct ncp_server *server, struct ncp_request_reply *req, int result) +{ + req->result = result; + if (req->status != RQ_ABANDONED) + memcpy(req->reply_buf, server->rxbuf, req->datalen); + req->status = RQ_DONE; + wake_up_all(&req->wq); + ncp_req_put(req); +} + +static void __abort_ncp_connection(struct ncp_server *server) +{ + struct ncp_request_reply *req; + + ncp_invalidate_conn(server); + del_timer(&server->timeout_tm); + while (!list_empty(&server->tx.requests)) { + req = list_entry(server->tx.requests.next, struct ncp_request_reply, req); + + list_del_init(&req->req); + ncp_finish_request(server, req, -EIO); + } + req = server->rcv.creq; + if (req) { + server->rcv.creq = NULL; + ncp_finish_request(server, req, -EIO); + server->rcv.ptr = NULL; + server->rcv.state = 0; + } + req = server->tx.creq; + if (req) { + server->tx.creq = NULL; + ncp_finish_request(server, req, -EIO); + } +} + +static inline int get_conn_number(struct ncp_reply_header *rp) +{ + return rp->conn_low | (rp->conn_high << 8); +} + +static inline void __ncp_abort_request(struct ncp_server *server, struct ncp_request_reply *req, int err) +{ + /* If req is done, we got signal, but we also received answer... */ + switch (req->status) { + case RQ_IDLE: + case RQ_DONE: + break; + case RQ_QUEUED: + list_del_init(&req->req); + ncp_finish_request(server, req, err); + break; + case RQ_INPROGRESS: + req->status = RQ_ABANDONED; + break; + case RQ_ABANDONED: + break; + } +} + +static inline void ncp_abort_request(struct ncp_server *server, struct ncp_request_reply *req, int err) +{ + mutex_lock(&server->rcv.creq_mutex); + __ncp_abort_request(server, req, err); + mutex_unlock(&server->rcv.creq_mutex); +} + +static inline void __ncptcp_abort(struct ncp_server *server) +{ + __abort_ncp_connection(server); +} + +static int ncpdgram_send(struct socket *sock, struct ncp_request_reply *req) +{ + struct msghdr msg = { .msg_iter = req->from, .msg_flags = MSG_DONTWAIT }; + return sock_sendmsg(sock, &msg); +} + +static void __ncptcp_try_send(struct ncp_server *server) +{ + struct ncp_request_reply *rq; + struct msghdr msg = { .msg_flags = MSG_NOSIGNAL | MSG_DONTWAIT }; + int result; + + rq = server->tx.creq; + if (!rq) + return; + + msg.msg_iter = rq->from; + result = sock_sendmsg(server->ncp_sock, &msg); + + if (result == -EAGAIN) + return; + + if (result < 0) { + pr_err("tcp: Send failed: %d\n", result); + __ncp_abort_request(server, rq, result); + return; + } + if (!msg_data_left(&msg)) { + server->rcv.creq = rq; + server->tx.creq = NULL; + return; + } + rq->from = msg.msg_iter; +} + +static inline void ncp_init_header(struct ncp_server *server, struct ncp_request_reply *req, struct ncp_request_header *h) +{ + req->status = RQ_INPROGRESS; + h->conn_low = server->connection; + h->conn_high = server->connection >> 8; + h->sequence = ++server->sequence; +} + +static void ncpdgram_start_request(struct ncp_server *server, struct ncp_request_reply *req) +{ + size_t signlen, len = req->tx_iov[1].iov_len; + struct ncp_request_header *h = req->tx_iov[1].iov_base; + + ncp_init_header(server, req, h); + signlen = sign_packet(server, + req->tx_iov[1].iov_base + sizeof(struct ncp_request_header) - 1, + len - sizeof(struct ncp_request_header) + 1, + cpu_to_le32(len), req->sign); + if (signlen) { + /* NCP over UDP appends signature */ + req->tx_iov[2].iov_base = req->sign; + req->tx_iov[2].iov_len = signlen; + } + iov_iter_kvec(&req->from, WRITE | ITER_KVEC, + req->tx_iov + 1, signlen ? 2 : 1, len + signlen); + server->rcv.creq = req; + server->timeout_last = server->m.time_out; + server->timeout_retries = server->m.retry_count; + ncpdgram_send(server->ncp_sock, req); + mod_timer(&server->timeout_tm, jiffies + server->m.time_out); +} + +#define NCP_TCP_XMIT_MAGIC (0x446D6454) +#define NCP_TCP_XMIT_VERSION (1) +#define NCP_TCP_RCVD_MAGIC (0x744E6350) + +static void ncptcp_start_request(struct ncp_server *server, struct ncp_request_reply *req) +{ + size_t signlen, len = req->tx_iov[1].iov_len; + struct ncp_request_header *h = req->tx_iov[1].iov_base; + + ncp_init_header(server, req, h); + signlen = sign_packet(server, req->tx_iov[1].iov_base + sizeof(struct ncp_request_header) - 1, + len - sizeof(struct ncp_request_header) + 1, + cpu_to_be32(len + 24), req->sign + 4) + 16; + + req->sign[0] = htonl(NCP_TCP_XMIT_MAGIC); + req->sign[1] = htonl(len + signlen); + req->sign[2] = htonl(NCP_TCP_XMIT_VERSION); + req->sign[3] = htonl(req->datalen + 8); + /* NCP over TCP prepends signature */ + req->tx_iov[0].iov_base = req->sign; + req->tx_iov[0].iov_len = signlen; + iov_iter_kvec(&req->from, WRITE | ITER_KVEC, + req->tx_iov, 2, len + signlen); + + server->tx.creq = req; + __ncptcp_try_send(server); +} + +static inline void __ncp_start_request(struct ncp_server *server, struct ncp_request_reply *req) +{ + /* we copy the data so that we do not depend on the caller + staying alive */ + memcpy(server->txbuf, req->tx_iov[1].iov_base, req->tx_iov[1].iov_len); + req->tx_iov[1].iov_base = server->txbuf; + + if (server->ncp_sock->type == SOCK_STREAM) + ncptcp_start_request(server, req); + else + ncpdgram_start_request(server, req); +} + +static int ncp_add_request(struct ncp_server *server, struct ncp_request_reply *req) +{ + mutex_lock(&server->rcv.creq_mutex); + if (!ncp_conn_valid(server)) { + mutex_unlock(&server->rcv.creq_mutex); + pr_err("tcp: Server died\n"); + return -EIO; + } + ncp_req_get(req); + if (server->tx.creq || server->rcv.creq) { + req->status = RQ_QUEUED; + list_add_tail(&req->req, &server->tx.requests); + mutex_unlock(&server->rcv.creq_mutex); + return 0; + } + __ncp_start_request(server, req); + mutex_unlock(&server->rcv.creq_mutex); + return 0; +} + +static void __ncp_next_request(struct ncp_server *server) +{ + struct ncp_request_reply *req; + + server->rcv.creq = NULL; + if (list_empty(&server->tx.requests)) { + return; + } + req = list_entry(server->tx.requests.next, struct ncp_request_reply, req); + list_del_init(&req->req); + __ncp_start_request(server, req); +} + +static void info_server(struct ncp_server *server, unsigned int id, const void * data, size_t len) +{ + if (server->info_sock) { + struct msghdr msg = { .msg_flags = MSG_NOSIGNAL }; + __be32 hdr[2] = {cpu_to_be32(len + 8), cpu_to_be32(id)}; + struct kvec iov[2] = { + {.iov_base = hdr, .iov_len = 8}, + {.iov_base = (void *)data, .iov_len = len}, + }; + + iov_iter_kvec(&msg.msg_iter, ITER_KVEC | WRITE, + iov, 2, len + 8); + + sock_sendmsg(server->info_sock, &msg); + } +} + +void ncpdgram_rcv_proc(struct work_struct *work) +{ + struct ncp_server *server = + container_of(work, struct ncp_server, rcv.tq); + struct socket* sock; + + sock = server->ncp_sock; + + while (1) { + struct ncp_reply_header reply; + int result; + + result = _recv(sock, &reply, sizeof(reply), MSG_PEEK | MSG_DONTWAIT); + if (result < 0) { + break; + } + if (result >= sizeof(reply)) { + struct ncp_request_reply *req; + + if (reply.type == NCP_WATCHDOG) { + unsigned char buf[10]; + + if (server->connection != get_conn_number(&reply)) { + goto drop; + } + result = _recv(sock, buf, sizeof(buf), MSG_DONTWAIT); + if (result < 0) { + ncp_dbg(1, "recv failed with %d\n", result); + continue; + } + if (result < 10) { + ncp_dbg(1, "too short (%u) watchdog packet\n", result); + continue; + } + if (buf[9] != '?') { + ncp_dbg(1, "bad signature (%02X) in watchdog packet\n", buf[9]); + continue; + } + buf[9] = 'Y'; + _send(sock, buf, sizeof(buf)); + continue; + } + if (reply.type != NCP_POSITIVE_ACK && reply.type != NCP_REPLY) { + result = _recv(sock, server->unexpected_packet.data, sizeof(server->unexpected_packet.data), MSG_DONTWAIT); + if (result < 0) { + continue; + } + info_server(server, 0, server->unexpected_packet.data, result); + continue; + } + mutex_lock(&server->rcv.creq_mutex); + req = server->rcv.creq; + if (req && (req->tx_type == NCP_ALLOC_SLOT_REQUEST || (server->sequence == reply.sequence && + server->connection == get_conn_number(&reply)))) { + if (reply.type == NCP_POSITIVE_ACK) { + server->timeout_retries = server->m.retry_count; + server->timeout_last = NCP_MAX_RPC_TIMEOUT; + mod_timer(&server->timeout_tm, jiffies + NCP_MAX_RPC_TIMEOUT); + } else if (reply.type == NCP_REPLY) { + result = _recv(sock, server->rxbuf, req->datalen, MSG_DONTWAIT); +#ifdef CONFIG_NCPFS_PACKET_SIGNING + if (result >= 0 && server->sign_active && req->tx_type != NCP_DEALLOC_SLOT_REQUEST) { + if (result < 8 + 8) { + result = -EIO; + } else { + unsigned int hdrl; + + result -= 8; + hdrl = sock->sk->sk_family == AF_INET ? 8 : 6; + if (sign_verify_reply(server, server->rxbuf + hdrl, result - hdrl, cpu_to_le32(result), server->rxbuf + result)) { + pr_info("Signature violation\n"); + result = -EIO; + } + } + } +#endif + del_timer(&server->timeout_tm); + server->rcv.creq = NULL; + ncp_finish_request(server, req, result); + __ncp_next_request(server); + mutex_unlock(&server->rcv.creq_mutex); + continue; + } + } + mutex_unlock(&server->rcv.creq_mutex); + } +drop:; + _recv(sock, &reply, sizeof(reply), MSG_DONTWAIT); + } +} + +static void __ncpdgram_timeout_proc(struct ncp_server *server) +{ + /* If timer is pending, we are processing another request... */ + if (!timer_pending(&server->timeout_tm)) { + struct ncp_request_reply* req; + + req = server->rcv.creq; + if (req) { + int timeout; + + if (server->m.flags & NCP_MOUNT_SOFT) { + if (server->timeout_retries-- == 0) { + __ncp_abort_request(server, req, -ETIMEDOUT); + return; + } + } + /* Ignore errors */ + ncpdgram_send(server->ncp_sock, req); + timeout = server->timeout_last << 1; + if (timeout > NCP_MAX_RPC_TIMEOUT) { + timeout = NCP_MAX_RPC_TIMEOUT; + } + server->timeout_last = timeout; + mod_timer(&server->timeout_tm, jiffies + timeout); + } + } +} + +void ncpdgram_timeout_proc(struct work_struct *work) +{ + struct ncp_server *server = + container_of(work, struct ncp_server, timeout_tq); + mutex_lock(&server->rcv.creq_mutex); + __ncpdgram_timeout_proc(server); + mutex_unlock(&server->rcv.creq_mutex); +} + +static int do_tcp_rcv(struct ncp_server *server, void *buffer, size_t len) +{ + int result; + + if (buffer) { + result = _recv(server->ncp_sock, buffer, len, MSG_DONTWAIT); + } else { + static unsigned char dummy[1024]; + + if (len > sizeof(dummy)) { + len = sizeof(dummy); + } + result = _recv(server->ncp_sock, dummy, len, MSG_DONTWAIT); + } + if (result < 0) { + return result; + } + if (result > len) { + pr_err("tcp: bug in recvmsg (%u > %zu)\n", result, len); + return -EIO; + } + return result; +} + +static int __ncptcp_rcv_proc(struct ncp_server *server) +{ + /* We have to check the result, so store the complete header */ + while (1) { + int result; + struct ncp_request_reply *req; + int datalen; + int type; + + while (server->rcv.len) { + result = do_tcp_rcv(server, server->rcv.ptr, server->rcv.len); + if (result == -EAGAIN) { + return 0; + } + if (result <= 0) { + req = server->rcv.creq; + if (req) { + __ncp_abort_request(server, req, -EIO); + } else { + __ncptcp_abort(server); + } + if (result < 0) { + pr_err("tcp: error in recvmsg: %d\n", result); + } else { + ncp_dbg(1, "tcp: EOF\n"); + } + return -EIO; + } + if (server->rcv.ptr) { + server->rcv.ptr += result; + } + server->rcv.len -= result; + } + switch (server->rcv.state) { + case 0: + if (server->rcv.buf.magic != htonl(NCP_TCP_RCVD_MAGIC)) { + pr_err("tcp: Unexpected reply type %08X\n", ntohl(server->rcv.buf.magic)); + __ncptcp_abort(server); + return -EIO; + } + datalen = ntohl(server->rcv.buf.len) & 0x0FFFFFFF; + if (datalen < 10) { + pr_err("tcp: Unexpected reply len %d\n", datalen); + __ncptcp_abort(server); + return -EIO; + } +#ifdef CONFIG_NCPFS_PACKET_SIGNING + if (server->sign_active) { + if (datalen < 18) { + pr_err("tcp: Unexpected reply len %d\n", datalen); + __ncptcp_abort(server); + return -EIO; + } + server->rcv.buf.len = datalen - 8; + server->rcv.ptr = (unsigned char*)&server->rcv.buf.p1; + server->rcv.len = 8; + server->rcv.state = 4; + break; + } +#endif + type = ntohs(server->rcv.buf.type); +#ifdef CONFIG_NCPFS_PACKET_SIGNING +cont:; +#endif + if (type != NCP_REPLY) { + if (datalen - 8 <= sizeof(server->unexpected_packet.data)) { + *(__u16*)(server->unexpected_packet.data) = htons(type); + server->unexpected_packet.len = datalen - 8; + + server->rcv.state = 5; + server->rcv.ptr = server->unexpected_packet.data + 2; + server->rcv.len = datalen - 10; + break; + } + ncp_dbg(1, "tcp: Unexpected NCP type %02X\n", type); +skipdata2:; + server->rcv.state = 2; +skipdata:; + server->rcv.ptr = NULL; + server->rcv.len = datalen - 10; + break; + } + req = server->rcv.creq; + if (!req) { + ncp_dbg(1, "Reply without appropriate request\n"); + goto skipdata2; + } + if (datalen > req->datalen + 8) { + pr_err("tcp: Unexpected reply len %d (expected at most %zd)\n", datalen, req->datalen + 8); + server->rcv.state = 3; + goto skipdata; + } + req->datalen = datalen - 8; + ((struct ncp_reply_header*)server->rxbuf)->type = NCP_REPLY; + server->rcv.ptr = server->rxbuf + 2; + server->rcv.len = datalen - 10; + server->rcv.state = 1; + break; +#ifdef CONFIG_NCPFS_PACKET_SIGNING + case 4: + datalen = server->rcv.buf.len; + type = ntohs(server->rcv.buf.type2); + goto cont; +#endif + case 1: + req = server->rcv.creq; + if (req->tx_type != NCP_ALLOC_SLOT_REQUEST) { + if (((struct ncp_reply_header*)server->rxbuf)->sequence != server->sequence) { + pr_err("tcp: Bad sequence number\n"); + __ncp_abort_request(server, req, -EIO); + return -EIO; + } + if ((((struct ncp_reply_header*)server->rxbuf)->conn_low | (((struct ncp_reply_header*)server->rxbuf)->conn_high << 8)) != server->connection) { + pr_err("tcp: Connection number mismatch\n"); + __ncp_abort_request(server, req, -EIO); + return -EIO; + } + } +#ifdef CONFIG_NCPFS_PACKET_SIGNING + if (server->sign_active && req->tx_type != NCP_DEALLOC_SLOT_REQUEST) { + if (sign_verify_reply(server, server->rxbuf + 6, req->datalen - 6, cpu_to_be32(req->datalen + 16), &server->rcv.buf.type)) { + pr_err("tcp: Signature violation\n"); + __ncp_abort_request(server, req, -EIO); + return -EIO; + } + } +#endif + ncp_finish_request(server, req, req->datalen); + nextreq:; + __ncp_next_request(server); + case 2: + next:; + server->rcv.ptr = (unsigned char*)&server->rcv.buf; + server->rcv.len = 10; + server->rcv.state = 0; + break; + case 3: + ncp_finish_request(server, server->rcv.creq, -EIO); + goto nextreq; + case 5: + info_server(server, 0, server->unexpected_packet.data, server->unexpected_packet.len); + goto next; + } + } +} + +void ncp_tcp_rcv_proc(struct work_struct *work) +{ + struct ncp_server *server = + container_of(work, struct ncp_server, rcv.tq); + + mutex_lock(&server->rcv.creq_mutex); + __ncptcp_rcv_proc(server); + mutex_unlock(&server->rcv.creq_mutex); +} + +void ncp_tcp_tx_proc(struct work_struct *work) +{ + struct ncp_server *server = + container_of(work, struct ncp_server, tx.tq); + + mutex_lock(&server->rcv.creq_mutex); + __ncptcp_try_send(server); + mutex_unlock(&server->rcv.creq_mutex); +} + +static int do_ncp_rpc_call(struct ncp_server *server, int size, + unsigned char* reply_buf, int max_reply_size) +{ + int result; + struct ncp_request_reply *req; + + req = ncp_alloc_req(); + if (!req) + return -ENOMEM; + + req->reply_buf = reply_buf; + req->datalen = max_reply_size; + req->tx_iov[1].iov_base = server->packet; + req->tx_iov[1].iov_len = size; + req->tx_type = *(u_int16_t*)server->packet; + + result = ncp_add_request(server, req); + if (result < 0) + goto out; + + if (wait_event_interruptible(req->wq, req->status == RQ_DONE)) { + ncp_abort_request(server, req, -EINTR); + result = -EINTR; + goto out; + } + + result = req->result; + +out: + ncp_req_put(req); + + return result; +} + +/* + * We need the server to be locked here, so check! + */ + +static int ncp_do_request(struct ncp_server *server, int size, + void* reply, int max_reply_size) +{ + int result; + + if (server->lock == 0) { + pr_err("Server not locked!\n"); + return -EIO; + } + if (!ncp_conn_valid(server)) { + return -EIO; + } + { + sigset_t old_set; + unsigned long mask, flags; + + spin_lock_irqsave(¤t->sighand->siglock, flags); + old_set = current->blocked; + if (current->flags & PF_EXITING) + mask = 0; + else + mask = sigmask(SIGKILL); + if (server->m.flags & NCP_MOUNT_INTR) { + /* FIXME: This doesn't seem right at all. So, like, + we can't handle SIGINT and get whatever to stop? + What if we've blocked it ourselves? What about + alarms? Why, in fact, are we mucking with the + sigmask at all? -- r~ */ + if (current->sighand->action[SIGINT - 1].sa.sa_handler == SIG_DFL) + mask |= sigmask(SIGINT); + if (current->sighand->action[SIGQUIT - 1].sa.sa_handler == SIG_DFL) + mask |= sigmask(SIGQUIT); + } + siginitsetinv(¤t->blocked, mask); + recalc_sigpending(); + spin_unlock_irqrestore(¤t->sighand->siglock, flags); + + result = do_ncp_rpc_call(server, size, reply, max_reply_size); + + spin_lock_irqsave(¤t->sighand->siglock, flags); + current->blocked = old_set; + recalc_sigpending(); + spin_unlock_irqrestore(¤t->sighand->siglock, flags); + } + + ncp_dbg(2, "do_ncp_rpc_call returned %d\n", result); + + return result; +} + +/* ncp_do_request assures that at least a complete reply header is + * received. It assumes that server->current_size contains the ncp + * request size + */ +int ncp_request2(struct ncp_server *server, int function, + void* rpl, int size) +{ + struct ncp_request_header *h; + struct ncp_reply_header* reply = rpl; + int result; + + h = (struct ncp_request_header *) (server->packet); + if (server->has_subfunction != 0) { + *(__u16 *) & (h->data[0]) = htons(server->current_size - sizeof(*h) - 2); + } + h->type = NCP_REQUEST; + /* + * The server shouldn't know or care what task is making a + * request, so we always use the same task number. + */ + h->task = 2; /* (current->pid) & 0xff; */ + h->function = function; + + result = ncp_do_request(server, server->current_size, reply, size); + if (result < 0) { + ncp_dbg(1, "ncp_request_error: %d\n", result); + goto out; + } + server->completion = reply->completion_code; + server->conn_status = reply->connection_state; + server->reply_size = result; + server->ncp_reply_size = result - sizeof(struct ncp_reply_header); + + result = reply->completion_code; + + if (result != 0) + ncp_vdbg("completion code=%x\n", result); +out: + return result; +} + +int ncp_connect(struct ncp_server *server) +{ + struct ncp_request_header *h; + int result; + + server->connection = 0xFFFF; + server->sequence = 255; + + h = (struct ncp_request_header *) (server->packet); + h->type = NCP_ALLOC_SLOT_REQUEST; + h->task = 2; /* see above */ + h->function = 0; + + result = ncp_do_request(server, sizeof(*h), server->packet, server->packet_size); + if (result < 0) + goto out; + server->connection = h->conn_low + (h->conn_high * 256); + result = 0; +out: + return result; +} + +int ncp_disconnect(struct ncp_server *server) +{ + struct ncp_request_header *h; + + h = (struct ncp_request_header *) (server->packet); + h->type = NCP_DEALLOC_SLOT_REQUEST; + h->task = 2; /* see above */ + h->function = 0; + + return ncp_do_request(server, sizeof(*h), server->packet, server->packet_size); +} + +void ncp_lock_server(struct ncp_server *server) +{ + mutex_lock(&server->mutex); + if (server->lock) + pr_warn("%s: was locked!\n", __func__); + server->lock = 1; +} + +void ncp_unlock_server(struct ncp_server *server) +{ + if (!server->lock) { + pr_warn("%s: was not locked!\n", __func__); + return; + } + server->lock = 0; + mutex_unlock(&server->mutex); +} diff --git a/drivers/staging/ncpfs/symlink.c b/drivers/staging/ncpfs/symlink.c new file mode 100644 index 000000000000..b6e16da4837a --- /dev/null +++ b/drivers/staging/ncpfs/symlink.c @@ -0,0 +1,182 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * linux/fs/ncpfs/symlink.c + * + * Code for allowing symbolic links on NCPFS (i.e. NetWare) + * Symbolic links are not supported on native NetWare, so we use an + * infrequently-used flag (Sh) and store a two-word magic header in + * the file to make sure we don't accidentally use a non-link file + * as a link. + * + * When using the NFS namespace, we set the mode to indicate a symlink and + * don't bother with the magic numbers. + * + * from linux/fs/ext2/symlink.c + * + * Copyright (C) 1998-99, Frank A. Vorstenbosch + * + * ncpfs symlink handling code + * NLS support (c) 1999 Petr Vandrovec + * Modified 2000 Ben Harris, University of Cambridge for NFS NS meta-info + * + */ + + +#include <linux/uaccess.h> + +#include <linux/errno.h> +#include <linux/fs.h> +#include <linux/time.h> +#include <linux/slab.h> +#include <linux/mm.h> +#include <linux/stat.h> +#include "ncp_fs.h" + +/* these magic numbers must appear in the symlink file -- this makes it a bit + more resilient against the magic attributes being set on random files. */ + +#define NCP_SYMLINK_MAGIC0 cpu_to_le32(0x6c6d7973) /* "symlnk->" */ +#define NCP_SYMLINK_MAGIC1 cpu_to_le32(0x3e2d6b6e) + +/* ----- read a symbolic link ------------------------------------------ */ + +static int ncp_symlink_readpage(struct file *file, struct page *page) +{ + struct inode *inode = page->mapping->host; + int error, length, len; + char *link, *rawlink; + char *buf = kmap(page); + + error = -ENOMEM; + rawlink = kmalloc(NCP_MAX_SYMLINK_SIZE, GFP_KERNEL); + if (!rawlink) + goto fail; + + if (ncp_make_open(inode,O_RDONLY)) + goto failEIO; + + error=ncp_read_kernel(NCP_SERVER(inode),NCP_FINFO(inode)->file_handle, + 0,NCP_MAX_SYMLINK_SIZE,rawlink,&length); + + ncp_inode_close(inode); + /* Close file handle if no other users... */ + ncp_make_closed(inode); + if (error) + goto failEIO; + + if (NCP_FINFO(inode)->flags & NCPI_KLUDGE_SYMLINK) { + if (length<NCP_MIN_SYMLINK_SIZE || + ((__le32 *)rawlink)[0]!=NCP_SYMLINK_MAGIC0 || + ((__le32 *)rawlink)[1]!=NCP_SYMLINK_MAGIC1) + goto failEIO; + link = rawlink + 8; + length -= 8; + } else { + link = rawlink; + } + + len = NCP_MAX_SYMLINK_SIZE; + error = ncp_vol2io(NCP_SERVER(inode), buf, &len, link, length, 0); + kfree(rawlink); + if (error) + goto fail; + SetPageUptodate(page); + kunmap(page); + unlock_page(page); + return 0; + +failEIO: + error = -EIO; + kfree(rawlink); +fail: + SetPageError(page); + kunmap(page); + unlock_page(page); + return error; +} + +/* + * symlinks can't do much... + */ +const struct address_space_operations ncp_symlink_aops = { + .readpage = ncp_symlink_readpage, +}; + +/* ----- create a new symbolic link -------------------------------------- */ + +int ncp_symlink(struct inode *dir, struct dentry *dentry, const char *symname) { + struct inode *inode; + char *rawlink; + int length, err, i, outlen; + int kludge; + umode_t mode; + __le32 attr; + unsigned int hdr; + + ncp_dbg(1, "dir=%p, dentry=%p, symname=%s\n", dir, dentry, symname); + + if (ncp_is_nfs_extras(NCP_SERVER(dir), NCP_FINFO(dir)->volNumber)) + kludge = 0; + else +#ifdef CONFIG_NCPFS_EXTRAS + if (NCP_SERVER(dir)->m.flags & NCP_MOUNT_SYMLINKS) + kludge = 1; + else +#endif + /* EPERM is returned by VFS if symlink procedure does not exist */ + return -EPERM; + + rawlink = kmalloc(NCP_MAX_SYMLINK_SIZE, GFP_KERNEL); + if (!rawlink) + return -ENOMEM; + + if (kludge) { + mode = 0; + attr = aSHARED | aHIDDEN; + ((__le32 *)rawlink)[0]=NCP_SYMLINK_MAGIC0; + ((__le32 *)rawlink)[1]=NCP_SYMLINK_MAGIC1; + hdr = 8; + } else { + mode = S_IFLNK | S_IRWXUGO; + attr = 0; + hdr = 0; + } + + length = strlen(symname); + /* map to/from server charset, do not touch upper/lower case as + symlink can point out of ncp filesystem */ + outlen = NCP_MAX_SYMLINK_SIZE - hdr; + err = ncp_io2vol(NCP_SERVER(dir), rawlink + hdr, &outlen, symname, length, 0); + if (err) + goto failfree; + + outlen += hdr; + + err = -EIO; + if (ncp_create_new(dir,dentry,mode,0,attr)) { + goto failfree; + } + + inode=d_inode(dentry); + + if (ncp_make_open(inode, O_WRONLY)) + goto failfree; + + if (ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle, + 0, outlen, rawlink, &i) || i!=outlen) { + goto fail; + } + + ncp_inode_close(inode); + ncp_make_closed(inode); + kfree(rawlink); + return 0; +fail:; + ncp_inode_close(inode); + ncp_make_closed(inode); +failfree:; + kfree(rawlink); + return err; +} + +/* ----- EOF ----- */ diff --git a/drivers/staging/nvec/nvec-keytable.h b/drivers/staging/nvec/nvec-keytable.h index 7008c96bdbbe..ac58e87e6a4e 100644 --- a/drivers/staging/nvec/nvec-keytable.h +++ b/drivers/staging/nvec/nvec-keytable.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * drivers/input/keyboard/tegra-nvec.c * @@ -5,19 +6,6 @@ * embedded controller * * Copyright (c) 2009, NVIDIA Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see http://www.gnu.org/licenses */ static unsigned short code_tab_102us[] = { diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 4ff8f47385da..52054a528723 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * NVEC: NVIDIA compliant embedded controller interface * @@ -7,11 +8,6 @@ * Ilya Petrov <ilya.muromec@gmail.com> * Marc Dietrich <marvin24@gmx.de> * Julian Andres Klode <jak@jak-linux.org> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * */ #include <linux/kernel.h> diff --git a/drivers/staging/nvec/nvec.h b/drivers/staging/nvec/nvec.h index aa7c70ef94f5..25efcdfa4f20 100644 --- a/drivers/staging/nvec/nvec.h +++ b/drivers/staging/nvec/nvec.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * NVEC: NVIDIA compliant embedded controller interface * @@ -7,11 +8,6 @@ * Ilya Petrov <ilya.muromec@gmail.com> * Marc Dietrich <marvin24@gmx.de> * Julian Andres Klode <jak@jak-linux.org> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * */ #ifndef __LINUX_MFD_NVEC diff --git a/drivers/staging/nvec/nvec_kbd.c b/drivers/staging/nvec/nvec_kbd.c index a01f486621eb..01dbb66f7e9a 100644 --- a/drivers/staging/nvec/nvec_kbd.c +++ b/drivers/staging/nvec/nvec_kbd.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * nvec_kbd: keyboard driver for a NVIDIA compliant embedded controller * @@ -5,11 +6,6 @@ * * Authors: Pierre-Hugues Husson <phhusson@free.fr> * Marc Dietrich <marvin24@gmx.de> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * */ #include <linux/module.h> diff --git a/drivers/staging/nvec/nvec_paz00.c b/drivers/staging/nvec/nvec_paz00.c index 51dbeeb3320e..8b4da95081c8 100644 --- a/drivers/staging/nvec/nvec_paz00.c +++ b/drivers/staging/nvec/nvec_paz00.c @@ -1,14 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * nvec_paz00: OEM specific driver for Compal PAZ00 based devices * * Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.launchpad.net> * * Authors: Ilya Petrov <ilya.muromec@gmail.com> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * */ #include <linux/module.h> diff --git a/drivers/staging/nvec/nvec_power.c b/drivers/staging/nvec/nvec_power.c index 3b144a9ea055..0e861c4bfcbf 100644 --- a/drivers/staging/nvec/nvec_power.c +++ b/drivers/staging/nvec/nvec_power.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * nvec_power: power supply driver for a NVIDIA compliant embedded controller * @@ -5,11 +6,6 @@ * * Authors: Ilya Petrov <ilya.muromec@gmail.com> * Marc Dietrich <marvin24@gmx.de> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * */ #include <linux/module.h> diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c index 3b7bce3ffd19..45db29262a9c 100644 --- a/drivers/staging/nvec/nvec_ps2.c +++ b/drivers/staging/nvec/nvec_ps2.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * nvec_ps2: mouse driver for a NVIDIA compliant embedded controller * @@ -6,11 +7,6 @@ * Authors: Pierre-Hugues Husson <phhusson@free.fr> * Ilya Petrov <ilya.muromec@gmail.com> * Marc Dietrich <marvin24@gmx.de> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * */ #include <linux/module.h> diff --git a/drivers/staging/octeon/Makefile b/drivers/staging/octeon/Makefile index 8ca17210d917..3887cf5f1e84 100644 --- a/drivers/staging/octeon/Makefile +++ b/drivers/staging/octeon/Makefile @@ -1,6 +1,4 @@ -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. +# SPDX-License-Identifier: GPL-2.0 # # Copyright (C) 2005-2009 Cavium Networks # diff --git a/drivers/staging/octeon/ethernet-defines.h b/drivers/staging/octeon/ethernet-defines.h index 07bd2b87f6a0..1e114422993a 100644 --- a/drivers/staging/octeon/ethernet-defines.h +++ b/drivers/staging/octeon/ethernet-defines.h @@ -1,11 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This file is based on code from OCTEON SDK by Cavium Networks. * * Copyright (c) 2003-2007 Cavium Networks - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, Version 2, as - * published by the Free Software Foundation. */ /* diff --git a/drivers/staging/octeon/ethernet-mdio.c b/drivers/staging/octeon/ethernet-mdio.c index 691e4a51ace4..f67f95043887 100644 --- a/drivers/staging/octeon/ethernet-mdio.c +++ b/drivers/staging/octeon/ethernet-mdio.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This file is based on code from OCTEON SDK by Cavium Networks. * * Copyright (c) 2003-2007 Cavium Networks - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, Version 2, as - * published by the Free Software Foundation. */ #include <linux/kernel.h> diff --git a/drivers/staging/octeon/ethernet-mdio.h b/drivers/staging/octeon/ethernet-mdio.h index 5ed8483fc24d..e3771d48c49b 100644 --- a/drivers/staging/octeon/ethernet-mdio.h +++ b/drivers/staging/octeon/ethernet-mdio.h @@ -1,11 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This file is based on code from OCTEON SDK by Cavium Networks. * * Copyright (c) 2003-2007 Cavium Networks - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, Version 2, as - * published by the Free Software Foundation. */ #include <linux/module.h> diff --git a/drivers/staging/octeon/ethernet-mem.c b/drivers/staging/octeon/ethernet-mem.c index d6172e4dace5..0d26c4a93ec1 100644 --- a/drivers/staging/octeon/ethernet-mem.c +++ b/drivers/staging/octeon/ethernet-mem.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This file is based on code from OCTEON SDK by Cavium Networks. * * Copyright (c) 2003-2010 Cavium Networks - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, Version 2, as - * published by the Free Software Foundation. */ #include <linux/kernel.h> diff --git a/drivers/staging/octeon/ethernet-mem.h b/drivers/staging/octeon/ethernet-mem.h index 62d07c426f89..692dcdb7154d 100644 --- a/drivers/staging/octeon/ethernet-mem.h +++ b/drivers/staging/octeon/ethernet-mem.h @@ -1,11 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This file is based on code from OCTEON SDK by Cavium Networks. * * Copyright (c) 2003-2007 Cavium Networks - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, Version 2, as - * published by the Free Software Foundation. */ int cvm_oct_mem_fill_fpa(int pool, int size, int elements); diff --git a/drivers/staging/octeon/ethernet-rgmii.c b/drivers/staging/octeon/ethernet-rgmii.c index 4e7304210bb9..c15376d33891 100644 --- a/drivers/staging/octeon/ethernet-rgmii.c +++ b/drivers/staging/octeon/ethernet-rgmii.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This file is based on code from OCTEON SDK by Cavium Networks. * * Copyright (c) 2003-2007 Cavium Networks - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, Version 2, as - * published by the Free Software Foundation. */ #include <linux/kernel.h> diff --git a/drivers/staging/octeon/ethernet-rx.c b/drivers/staging/octeon/ethernet-rx.c index 1a44291318ee..5e271245273c 100644 --- a/drivers/staging/octeon/ethernet-rx.c +++ b/drivers/staging/octeon/ethernet-rx.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This file is based on code from OCTEON SDK by Cavium Networks. * * Copyright (c) 2003-2010 Cavium Networks - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, Version 2, as - * published by the Free Software Foundation. */ #include <linux/module.h> diff --git a/drivers/staging/octeon/ethernet-rx.h b/drivers/staging/octeon/ethernet-rx.h index 315a63d7094f..096553d8fc99 100644 --- a/drivers/staging/octeon/ethernet-rx.h +++ b/drivers/staging/octeon/ethernet-rx.h @@ -1,11 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This file is based on code from OCTEON SDK by Cavium Networks. * * Copyright (c) 2003-2007 Cavium Networks - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, Version 2, as - * published by the Free Software Foundation. */ #include <asm/octeon/cvmx-fau.h> diff --git a/drivers/staging/octeon/ethernet-sgmii.c b/drivers/staging/octeon/ethernet-sgmii.c index 7424dc45ad39..a4a8f094e2b4 100644 --- a/drivers/staging/octeon/ethernet-sgmii.c +++ b/drivers/staging/octeon/ethernet-sgmii.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This file is based on code from OCTEON SDK by Cavium Networks. * * Copyright (c) 2003-2007 Cavium Networks - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, Version 2, as - * published by the Free Software Foundation. */ #include <linux/phy.h> diff --git a/drivers/staging/octeon/ethernet-spi.c b/drivers/staging/octeon/ethernet-spi.c index 063dcd07557b..01efdf2a2c20 100644 --- a/drivers/staging/octeon/ethernet-spi.c +++ b/drivers/staging/octeon/ethernet-spi.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This file is based on code from OCTEON SDK by Cavium Networks. * * Copyright (c) 2003-2007 Cavium Networks - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, Version 2, as - * published by the Free Software Foundation. */ #include <linux/kernel.h> diff --git a/drivers/staging/octeon/ethernet-tx.c b/drivers/staging/octeon/ethernet-tx.c index 31f35025d19e..df3441b815bb 100644 --- a/drivers/staging/octeon/ethernet-tx.c +++ b/drivers/staging/octeon/ethernet-tx.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This file is based on code from OCTEON SDK by Cavium Networks. * * Copyright (c) 2003-2010 Cavium Networks - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, Version 2, as - * published by the Free Software Foundation. */ #include <linux/module.h> diff --git a/drivers/staging/octeon/ethernet-tx.h b/drivers/staging/octeon/ethernet-tx.h index 84848e4c1664..78936e9b33b0 100644 --- a/drivers/staging/octeon/ethernet-tx.h +++ b/drivers/staging/octeon/ethernet-tx.h @@ -1,11 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This file is based on code from OCTEON SDK by Cavium Networks. * * Copyright (c) 2003-2007 Cavium Networks - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, Version 2, as - * published by the Free Software Foundation. */ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev); diff --git a/drivers/staging/octeon/ethernet-util.h b/drivers/staging/octeon/ethernet-util.h index cb5540dc0e9d..31a82873e15c 100644 --- a/drivers/staging/octeon/ethernet-util.h +++ b/drivers/staging/octeon/ethernet-util.h @@ -1,11 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This file is based on code from OCTEON SDK by Cavium Networks. * * Copyright (c) 2003-2007 Cavium Networks - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, Version 2, as - * published by the Free Software Foundation. */ #include <asm/octeon/cvmx-pip.h> diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c index 429e24adfcf5..9b15c9ed844b 100644 --- a/drivers/staging/octeon/ethernet.c +++ b/drivers/staging/octeon/ethernet.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * This file is based on code from OCTEON SDK by Cavium Networks. * * Copyright (c) 2003-2007 Cavium Networks - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, Version 2, as - * published by the Free Software Foundation. */ #include <linux/platform_device.h> diff --git a/drivers/staging/octeon/octeon-ethernet.h b/drivers/staging/octeon/octeon-ethernet.h index 9c3f453adaa0..4a07e7f43d12 100644 --- a/drivers/staging/octeon/octeon-ethernet.h +++ b/drivers/staging/octeon/octeon-ethernet.h @@ -1,11 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This file is based on code from OCTEON SDK by Cavium Networks. * * Copyright (c) 2003-2010 Cavium Networks - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, Version 2, as - * published by the Free Software Foundation. */ /* diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index 82bffd911435..2744c9f0920e 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -393,7 +393,8 @@ static void dcon_set_source_sync(struct dcon_priv *dcon, int arg) } static ssize_t dcon_mode_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { struct dcon_priv *dcon = dev_get_drvdata(dev); @@ -401,7 +402,8 @@ static ssize_t dcon_mode_show(struct device *dev, } static ssize_t dcon_sleep_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { struct dcon_priv *dcon = dev_get_drvdata(dev); @@ -409,7 +411,8 @@ static ssize_t dcon_sleep_show(struct device *dev, } static ssize_t dcon_freeze_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { struct dcon_priv *dcon = dev_get_drvdata(dev); @@ -417,7 +420,8 @@ static ssize_t dcon_freeze_show(struct device *dev, } static ssize_t dcon_mono_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { struct dcon_priv *dcon = dev_get_drvdata(dev); @@ -425,13 +429,15 @@ static ssize_t dcon_mono_show(struct device *dev, } static ssize_t dcon_resumeline_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, + char *buf) { return sprintf(buf, "%d\n", resumeline); } static ssize_t dcon_mono_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) + struct device_attribute *attr, + const char *buf, size_t count) { unsigned long enable_mono; int rc; @@ -446,7 +452,8 @@ static ssize_t dcon_mono_store(struct device *dev, } static ssize_t dcon_freeze_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) + struct device_attribute *attr, + const char *buf, size_t count) { struct dcon_priv *dcon = dev_get_drvdata(dev); unsigned long output; @@ -474,7 +481,8 @@ static ssize_t dcon_freeze_store(struct device *dev, } static ssize_t dcon_resumeline_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) + struct device_attribute *attr, + const char *buf, size_t count) { unsigned short rl; int rc; @@ -490,7 +498,8 @@ static ssize_t dcon_resumeline_store(struct device *dev, } static ssize_t dcon_sleep_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) + struct device_attribute *attr, + const char *buf, size_t count) { unsigned long output; int ret; @@ -641,7 +650,8 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id) /* Add the backlight device for the DCON */ dcon_bl_props.brightness = dcon->bl_val; dcon->bl_dev = backlight_device_register("dcon-bl", &dcon_device->dev, - dcon, &dcon_bl_ops, &dcon_bl_props); + dcon, &dcon_bl_ops, + &dcon_bl_props); if (IS_ERR(dcon->bl_dev)) { dev_err(&client->dev, "cannot register backlight dev (%ld)\n", PTR_ERR(dcon->bl_dev)); diff --git a/drivers/staging/olpc_dcon/olpc_dcon.h b/drivers/staging/olpc_dcon/olpc_dcon.h index 8fbde5d3b4a6..fa89bb97c7b0 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.h +++ b/drivers/staging/olpc_dcon/olpc_dcon.h @@ -10,18 +10,18 @@ #define DCON_REG_ID 0 #define DCON_REG_MODE 1 -#define MODE_PASSTHRU (1<<0) -#define MODE_SLEEP (1<<1) -#define MODE_SLEEP_AUTO (1<<2) -#define MODE_BL_ENABLE (1<<3) -#define MODE_BLANK (1<<4) -#define MODE_CSWIZZLE (1<<5) -#define MODE_COL_AA (1<<6) -#define MODE_MONO_LUMA (1<<7) -#define MODE_SCAN_INT (1<<8) -#define MODE_CLOCKDIV (1<<9) -#define MODE_DEBUG (1<<14) -#define MODE_SELFTEST (1<<15) +#define MODE_PASSTHRU BIT(0) +#define MODE_SLEEP BIT(1) +#define MODE_SLEEP_AUTO BIT(2) +#define MODE_BL_ENABLE BIT(3) +#define MODE_BLANK BIT(4) +#define MODE_CSWIZZLE BIT(5) +#define MODE_COL_AA BIT(6) +#define MODE_MONO_LUMA BIT(7) +#define MODE_SCAN_INT BIT(8) +#define MODE_CLOCKDIV BIT(9) +#define MODE_DEBUG BIT(14) +#define MODE_SELFTEST BIT(15) #define DCON_REG_HRES 0x2 #define DCON_REG_HTOTAL 0x3 @@ -36,11 +36,11 @@ #define DCON_REG_MEM_OPT_B 0x42 /* Load Delay Locked Loop (DLL) settings for clock delay */ -#define MEM_DLL_CLOCK_DELAY (1<<0) +#define MEM_DLL_CLOCK_DELAY BIT(0) /* Memory controller power down function */ -#define MEM_POWER_DOWN (1<<8) +#define MEM_POWER_DOWN BIT(8) /* Memory controller software reset */ -#define MEM_SOFT_RESET (1<<0) +#define MEM_SOFT_RESET BIT(0) /* Status values */ diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c index 0c5a10c69401..633c58ce24ee 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c +++ b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c @@ -69,7 +69,7 @@ static int dcon_init_xo_1(struct dcon_priv *dcon) gpio_direction_input(OLPC_GPIO_DCON_IRQ); gpio_direction_input(OLPC_GPIO_DCON_BLANK); gpio_direction_output(OLPC_GPIO_DCON_LOAD, - dcon->curr_src == DCON_SOURCE_CPU); + dcon->curr_src == DCON_SOURCE_CPU); /* Set up the interrupt mappings */ diff --git a/drivers/staging/pi433/Documentation/devicetree/pi433-overlay.dts b/drivers/staging/pi433/Documentation/devicetree/pi433-overlay.dts index 004b5027a934..61fad96818c2 100644 --- a/drivers/staging/pi433/Documentation/devicetree/pi433-overlay.dts +++ b/drivers/staging/pi433/Documentation/devicetree/pi433-overlay.dts @@ -3,22 +3,22 @@ /plugin/; / { - compatible = "bcm,bcm2835", "bcm,bcm2708", "bcm,bcm2709"; - - fragment@0 { - target = <&spi0>; - __overlay__ { - status = "okay"; - - spidev@0{ - status = "disabled"; - }; - - spidev@1{ - status = "disabled"; - }; - }; - }; + compatible = "bcm,bcm2835", "bcm,bcm2708", "bcm,bcm2709"; + + fragment@0 { + target = <&spi0>; + __overlay__ { + status = "okay"; + + spidev@0{ + status = "disabled"; + }; + + spidev@1{ + status = "disabled"; + }; + }; + }; fragment@1 { target = <&gpio>; diff --git a/drivers/staging/pi433/Documentation/pi433.txt b/drivers/staging/pi433/Documentation/pi433.txt index 245fef33d688..7d9dc2244848 100644 --- a/drivers/staging/pi433/Documentation/pi433.txt +++ b/drivers/staging/pi433/Documentation/pi433.txt @@ -69,8 +69,8 @@ PI433_IOC_WR_TX_CFG - set the transmission parameters PI433_IOC_RD_RX_CFG - get the receiving parameters from the driver PI433_IOC_WR_RX_CFG - set the receiving parameters -The tx configuration is transfered via struct pi433_tx_cfg, the parameterset for transmission. -It is devided into two sections: rf parameters and packet format. +The tx configuration is transferred via struct pi433_tx_cfg, the parameterset for transmission. +It is divided into two sections: rf parameters and packet format. rf params: frequency @@ -110,9 +110,9 @@ rf params: ramp12 - amp ramps up in 12us ramp10 - amp ramps up in 10us tx_start_condition - fifoLevel - transmission starts, if fifo is filled to + fifo_level - transmission starts, if fifo is filled to threshold level - fifoNotEmpty - transmission starts, as soon as there is one + fifo_not_empty - transmission starts, as soon as there is one byte in internal fifo repetitions This gives the option, to send a telegram multiple times. Default: 1 @@ -200,11 +200,11 @@ rf params: sets the gain of the low noise amp automatic - lna gain is determined by an agc max - lna gain is set to maximum - maxMinus6 - lna gain is set to 6db below max - maxMinus12 - lna gain is set to 12db below max - maxMinus24 - lna gain is set to 24db below max - maxMinus36 - lna gain is set to 36db below max - maxMinus48 - lna gain is set to 48db below max + max_minus_6 - lna gain is set to 6db below max + max_minus_12 - lna gain is set to 12db below max + max_minus_24 - lna gain is set to 24db below max + max_minus_36 - lna gain is set to 36db below max + max_minus_48 - lna gain is set to 48db below max bw_mantisse sets the bandwidth of the channel filter - part one: mantisse. mantisse16 - mantisse is set to 16 diff --git a/drivers/staging/pi433/pi433_if.c b/drivers/staging/pi433/pi433_if.c index 2a205c6173dc..edcd7e798f99 100644 --- a/drivers/staging/pi433/pi433_if.c +++ b/drivers/staging/pi433/pi433_if.c @@ -48,14 +48,13 @@ #include <linux/wait.h> #include <linux/spi/spi.h> #ifdef CONFIG_COMPAT -#include <asm/compat.h> +#include <linux/compat.h> #endif #include "pi433_if.h" #include "rf69.h" - -#define N_PI433_MINORS (1U << MINORBITS) /*32*/ /* ... up to 256 */ +#define N_PI433_MINORS BIT(MINORBITS) /*32*/ /* ... up to 256 */ #define MAX_MSG_SIZE 900 /* min: FIFO_SIZE! */ #define MSG_FIFO_SIZE 65536 /* 65536 = 2^16 */ #define NUM_DIO 2 @@ -79,7 +78,7 @@ struct pi433_device { struct device *dev; struct cdev *cdev; struct spi_device *spi; - unsigned users; + unsigned int users; /* irq related values */ struct gpio_desc *gpiod[NUM_DIO]; @@ -121,32 +120,20 @@ struct pi433_instance { /*-------------------------------------------------------------------------*/ -/* macro for checked access of registers of radio module */ -#define SET_CHECKED(retval) \ - if (retval < 0) \ - return retval; - -/*-------------------------------------------------------------------------*/ - /* GPIO interrupt handlers */ static irqreturn_t DIO0_irq_handler(int irq, void *dev_id) { struct pi433_device *device = dev_id; - if (device->irq_state[DIO0] == DIO_PacketSent) - { + if (device->irq_state[DIO0] == DIO_PACKET_SENT) { device->free_in_fifo = FIFO_SIZE; dev_dbg(device->dev, "DIO0 irq: Packet sent\n"); wake_up_interruptible(&device->fifo_wait_queue); - } - else if (device->irq_state[DIO0] == DIO_Rssi_DIO0) - { + } else if (device->irq_state[DIO0] == DIO_RSSI_DIO0) { dev_dbg(device->dev, "DIO0 irq: RSSI level over threshold\n"); wake_up_interruptible(&device->rx_wait_queue); - } - else if (device->irq_state[DIO0] == DIO_PayloadReady) - { - dev_dbg(device->dev, "DIO0 irq: PayloadReady\n"); + } else if (device->irq_state[DIO0] == DIO_PAYLOAD_READY) { + dev_dbg(device->dev, "DIO0 irq: Payload ready\n"); device->free_in_fifo = 0; wake_up_interruptible(&device->fifo_wait_queue); } @@ -158,14 +145,13 @@ static irqreturn_t DIO1_irq_handler(int irq, void *dev_id) { struct pi433_device *device = dev_id; - if (device->irq_state[DIO1] == DIO_FifoNotEmpty_DIO1) - { + if (device->irq_state[DIO1] == DIO_FIFO_NOT_EMPTY_DIO1) { device->free_in_fifo = FIFO_SIZE; - } - else if (device->irq_state[DIO1] == DIO_FifoLevel) - { - if (device->rx_active) device->free_in_fifo = FIFO_THRESHOLD - 1; - else device->free_in_fifo = FIFO_SIZE - FIFO_THRESHOLD - 1; + } else if (device->irq_state[DIO1] == DIO_FIFO_LEVEL) { + if (device->rx_active) + device->free_in_fifo = FIFO_THRESHOLD - 1; + else + device->free_in_fifo = FIFO_SIZE - FIFO_THRESHOLD - 1; } dev_dbg(device->dev, "DIO1 irq: %d bytes free in fifo\n", device->free_in_fifo); @@ -183,30 +169,56 @@ rf69_set_rx_cfg(struct pi433_device *dev, struct pi433_rx_cfg *rx_cfg) int payload_length; /* receiver config */ - SET_CHECKED(rf69_set_frequency (dev->spi, rx_cfg->frequency)); - SET_CHECKED(rf69_set_bit_rate (dev->spi, rx_cfg->bit_rate)); - SET_CHECKED(rf69_set_modulation (dev->spi, rx_cfg->modulation)); - SET_CHECKED(rf69_set_antenna_impedance (dev->spi, rx_cfg->antenna_impedance)); - SET_CHECKED(rf69_set_rssi_threshold (dev->spi, rx_cfg->rssi_threshold)); - SET_CHECKED(rf69_set_ook_threshold_dec (dev->spi, rx_cfg->thresholdDecrement)); - SET_CHECKED(rf69_set_bandwidth (dev->spi, rx_cfg->bw_mantisse, rx_cfg->bw_exponent)); - SET_CHECKED(rf69_set_bandwidth_during_afc(dev->spi, rx_cfg->bw_mantisse, rx_cfg->bw_exponent)); - SET_CHECKED(rf69_set_dagc (dev->spi, rx_cfg->dagc)); + ret = rf69_set_frequency(dev->spi, rx_cfg->frequency); + if (ret < 0) + return ret; + ret = rf69_set_bit_rate(dev->spi, rx_cfg->bit_rate); + if (ret < 0) + return ret; + ret = rf69_set_modulation(dev->spi, rx_cfg->modulation); + if (ret < 0) + return ret; + ret = rf69_set_antenna_impedance(dev->spi, rx_cfg->antenna_impedance); + if (ret < 0) + return ret; + ret = rf69_set_rssi_threshold(dev->spi, rx_cfg->rssi_threshold); + if (ret < 0) + return ret; + ret = rf69_set_ook_threshold_dec(dev->spi, rx_cfg->threshold_decrement); + if (ret < 0) + return ret; + ret = rf69_set_bandwidth(dev->spi, rx_cfg->bw_mantisse, rx_cfg->bw_exponent); + if (ret < 0) + return ret; + ret = rf69_set_bandwidth_during_afc(dev->spi, rx_cfg->bw_mantisse, rx_cfg->bw_exponent); + if (ret < 0) + return ret; + ret = rf69_set_dagc(dev->spi, rx_cfg->dagc); + if (ret < 0) + return ret; dev->rx_bytes_to_drop = rx_cfg->bytes_to_drop; /* packet config */ /* enable */ - SET_CHECKED(rf69_set_sync_enable(dev->spi, rx_cfg->enable_sync)); - if (rx_cfg->enable_sync == optionOn) - { - SET_CHECKED(rf69_set_fifo_fill_condition(dev->spi, afterSyncInterrupt)); - } - else - { - SET_CHECKED(rf69_set_fifo_fill_condition(dev->spi, always)); + if (rx_cfg->enable_sync == OPTION_ON) { + ret = rf69_enable_sync(dev->spi); + if (ret < 0) + return ret; + + ret = rf69_set_fifo_fill_condition(dev->spi, afterSyncInterrupt); + if (ret < 0) + return ret; + } else { + ret = rf69_disable_sync(dev->spi); + if (ret < 0) + return ret; + + ret = rf69_set_fifo_fill_condition(dev->spi, always); + if (ret < 0) + return ret; } - if (rx_cfg->enable_length_byte == optionOn) { + if (rx_cfg->enable_length_byte == OPTION_ON) { ret = rf69_set_packet_format(dev->spi, packetLengthVar); if (ret < 0) return ret; @@ -215,36 +227,56 @@ rf69_set_rx_cfg(struct pi433_device *dev, struct pi433_rx_cfg *rx_cfg) if (ret < 0) return ret; } - SET_CHECKED(rf69_set_adressFiltering(dev->spi, rx_cfg->enable_address_filtering)); - SET_CHECKED(rf69_set_crc_enable (dev->spi, rx_cfg->enable_crc)); + ret = rf69_set_adressFiltering(dev->spi, rx_cfg->enable_address_filtering); + if (ret < 0) + return ret; - /* lengths */ - SET_CHECKED(rf69_set_sync_size(dev->spi, rx_cfg->sync_length)); - if (rx_cfg->enable_length_byte == optionOn) - { - SET_CHECKED(rf69_set_payload_length(dev->spi, 0xff)); + if (rx_cfg->enable_crc == OPTION_ON) { + ret = rf69_enable_crc(dev->spi); + if (ret < 0) + return ret; + } else { + ret = rf69_disable_crc(dev->spi); + if (ret < 0) + return ret; } - else if (rx_cfg->fixed_message_length != 0) - { + + /* lengths */ + ret = rf69_set_sync_size(dev->spi, rx_cfg->sync_length); + if (ret < 0) + return ret; + if (rx_cfg->enable_length_byte == OPTION_ON) { + ret = rf69_set_payload_length(dev->spi, 0xff); + if (ret < 0) + return ret; + } else if (rx_cfg->fixed_message_length != 0) { payload_length = rx_cfg->fixed_message_length; - if (rx_cfg->enable_length_byte == optionOn) payload_length++; - if (rx_cfg->enable_address_filtering != filteringOff) payload_length++; - SET_CHECKED(rf69_set_payload_length(dev->spi, payload_length)); - } - else - { - SET_CHECKED(rf69_set_payload_length(dev->spi, 0)); + if (rx_cfg->enable_length_byte == OPTION_ON) + payload_length++; + if (rx_cfg->enable_address_filtering != filteringOff) + payload_length++; + ret = rf69_set_payload_length(dev->spi, payload_length); + if (ret < 0) + return ret; + } else { + ret = rf69_set_payload_length(dev->spi, 0); + if (ret < 0) + return ret; } /* values */ - if (rx_cfg->enable_sync == optionOn) - { - SET_CHECKED(rf69_set_sync_values(dev->spi, rx_cfg->sync_pattern)); + if (rx_cfg->enable_sync == OPTION_ON) { + ret = rf69_set_sync_values(dev->spi, rx_cfg->sync_pattern); + if (ret < 0) + return ret; } - if (rx_cfg->enable_address_filtering != filteringOff) - { - SET_CHECKED(rf69_set_node_address (dev->spi, rx_cfg->node_address)); - SET_CHECKED(rf69_set_broadcast_address(dev->spi, rx_cfg->broadcast_address)); + if (rx_cfg->enable_address_filtering != filteringOff) { + ret = rf69_set_node_address(dev->spi, rx_cfg->node_address); + if (ret < 0) + return ret; + ret = rf69_set_broadcast_address(dev->spi, rx_cfg->broadcast_address); + if (ret < 0) + return ret; } return 0; @@ -255,25 +287,50 @@ rf69_set_tx_cfg(struct pi433_device *dev, struct pi433_tx_cfg *tx_cfg) { int ret; - SET_CHECKED(rf69_set_frequency (dev->spi, tx_cfg->frequency)); - SET_CHECKED(rf69_set_bit_rate (dev->spi, tx_cfg->bit_rate)); - SET_CHECKED(rf69_set_modulation (dev->spi, tx_cfg->modulation)); - SET_CHECKED(rf69_set_deviation (dev->spi, tx_cfg->dev_frequency)); - SET_CHECKED(rf69_set_pa_ramp (dev->spi, tx_cfg->pa_ramp)); - SET_CHECKED(rf69_set_modulation_shaping(dev->spi, tx_cfg->modShaping)); - SET_CHECKED(rf69_set_tx_start_condition(dev->spi, tx_cfg->tx_start_condition)); + ret = rf69_set_frequency(dev->spi, tx_cfg->frequency); + if (ret < 0) + return ret; + ret = rf69_set_bit_rate(dev->spi, tx_cfg->bit_rate); + if (ret < 0) + return ret; + ret = rf69_set_modulation(dev->spi, tx_cfg->modulation); + if (ret < 0) + return ret; + ret = rf69_set_deviation(dev->spi, tx_cfg->dev_frequency); + if (ret < 0) + return ret; + ret = rf69_set_pa_ramp(dev->spi, tx_cfg->pa_ramp); + if (ret < 0) + return ret; + ret = rf69_set_modulation_shaping(dev->spi, tx_cfg->mod_shaping); + if (ret < 0) + return ret; + ret = rf69_set_tx_start_condition(dev->spi, tx_cfg->tx_start_condition); + if (ret < 0) + return ret; /* packet format enable */ - if (tx_cfg->enable_preamble == optionOn) - { - SET_CHECKED(rf69_set_preamble_length(dev->spi, tx_cfg->preamble_length)); + if (tx_cfg->enable_preamble == OPTION_ON) { + ret = rf69_set_preamble_length(dev->spi, tx_cfg->preamble_length); + if (ret < 0) + return ret; + } else { + ret = rf69_set_preamble_length(dev->spi, 0); + if (ret < 0) + return ret; } - else - { - SET_CHECKED(rf69_set_preamble_length(dev->spi, 0)); + + if (tx_cfg->enable_sync == OPTION_ON) { + ret = rf69_enable_sync(dev->spi); + if (ret < 0) + return ret; + } else { + ret = rf69_disable_sync(dev->spi); + if (ret < 0) + return ret; } - SET_CHECKED(rf69_set_sync_enable (dev->spi, tx_cfg->enable_sync)); - if (tx_cfg->enable_length_byte == optionOn) { + + if (tx_cfg->enable_length_byte == OPTION_ON) { ret = rf69_set_packet_format(dev->spi, packetLengthVar); if (ret < 0) return ret; @@ -282,12 +339,25 @@ rf69_set_tx_cfg(struct pi433_device *dev, struct pi433_tx_cfg *tx_cfg) if (ret < 0) return ret; } - SET_CHECKED(rf69_set_crc_enable (dev->spi, tx_cfg->enable_crc)); + + if (tx_cfg->enable_crc == OPTION_ON) { + ret = rf69_enable_crc(dev->spi); + if (ret < 0) + return ret; + } else { + ret = rf69_disable_crc(dev->spi); + if (ret < 0) + return ret; + } /* configure sync, if enabled */ - if (tx_cfg->enable_sync == optionOn) { - SET_CHECKED(rf69_set_sync_size(dev->spi, tx_cfg->sync_length)); - SET_CHECKED(rf69_set_sync_values(dev->spi, tx_cfg->sync_pattern)); + if (tx_cfg->enable_sync == OPTION_ON) { + ret = rf69_set_sync_size(dev->spi, tx_cfg->sync_length); + if (ret < 0) + return ret; + ret = rf69_set_sync_values(dev->spi, tx_cfg->sync_pattern); + if (ret < 0) + return ret; } return 0; @@ -306,43 +376,51 @@ pi433_start_rx(struct pi433_device *dev) /* setup for receiving */ retval = rf69_set_rx_cfg(dev, &dev->rx_cfg); - if (retval) return retval; + if (retval) + return retval; /* setup rssi irq */ - SET_CHECKED(rf69_set_dio_mapping(dev->spi, DIO0, DIO_Rssi_DIO0)); - dev->irq_state[DIO0] = DIO_Rssi_DIO0; + retval = rf69_set_dio_mapping(dev->spi, DIO0, DIO_RSSI_DIO0); + if (retval < 0) + return retval; + dev->irq_state[DIO0] = DIO_RSSI_DIO0; irq_set_irq_type(dev->irq_num[DIO0], IRQ_TYPE_EDGE_RISING); /* setup fifo level interrupt */ - SET_CHECKED(rf69_set_fifo_threshold(dev->spi, FIFO_SIZE - FIFO_THRESHOLD)); - SET_CHECKED(rf69_set_dio_mapping(dev->spi, DIO1, DIO_FifoLevel)); - dev->irq_state[DIO1] = DIO_FifoLevel; + retval = rf69_set_fifo_threshold(dev->spi, FIFO_SIZE - FIFO_THRESHOLD); + if (retval < 0) + return retval; + retval = rf69_set_dio_mapping(dev->spi, DIO1, DIO_FIFO_LEVEL); + if (retval < 0) + return retval; + dev->irq_state[DIO1] = DIO_FIFO_LEVEL; irq_set_irq_type(dev->irq_num[DIO1], IRQ_TYPE_EDGE_RISING); /* set module to receiving mode */ - SET_CHECKED(rf69_set_mode(dev->spi, receive)); + retval = rf69_set_mode(dev->spi, receive); + if (retval < 0) + return retval; return 0; } - /*-------------------------------------------------------------------------*/ static int pi433_receive(void *data) { struct pi433_device *dev = data; - struct spi_device *spi = dev->spi; /* needed for SET_CHECKED */ + struct spi_device *spi = dev->spi; int bytes_to_read, bytes_total; int retval; dev->interrupt_rx_allowed = false; /* wait for any tx to finish */ - dev_dbg(dev->dev,"rx: going to wait for any tx to finish"); + dev_dbg(dev->dev, "rx: going to wait for any tx to finish"); retval = wait_event_interruptible(dev->rx_wait_queue, !dev->tx_active); - if(retval) /* wait was interrupted */ - { + if (retval) { + /* wait was interrupted */ dev->interrupt_rx_allowed = true; wake_up_interruptible(&dev->tx_wait_queue); return retval; @@ -359,8 +437,7 @@ pi433_receive(void *data) return retval; /* now check RSSI, if low wait for getting high (RSSI interrupt) */ - while ( !rf69_get_flag(dev->spi, rssiExceededThreshold) ) - { + while (!rf69_get_flag(dev->spi, rssiExceededThreshold)) { /* allow tx to interrupt us while waiting for high RSSI */ dev->interrupt_rx_allowed = true; wake_up_interruptible(&dev->tx_wait_queue); @@ -368,43 +445,43 @@ pi433_receive(void *data) /* wait for RSSI level to become high */ dev_dbg(dev->dev, "rx: going to wait for high RSSI level"); retval = wait_event_interruptible(dev->rx_wait_queue, - rf69_get_flag(dev->spi, - rssiExceededThreshold)); - if (retval) goto abort; /* wait was interrupted */ + rf69_get_flag(dev->spi, + rssiExceededThreshold)); + if (retval) /* wait was interrupted */ + goto abort; dev->interrupt_rx_allowed = false; /* cross check for ongoing tx */ - if (!dev->tx_active) break; + if (!dev->tx_active) + break; } /* configure payload ready irq */ - SET_CHECKED(rf69_set_dio_mapping(spi, DIO0, DIO_PayloadReady)); - dev->irq_state[DIO0] = DIO_PayloadReady; + retval = rf69_set_dio_mapping(spi, DIO0, DIO_PAYLOAD_READY); + if (retval < 0) + goto abort; + dev->irq_state[DIO0] = DIO_PAYLOAD_READY; irq_set_irq_type(dev->irq_num[DIO0], IRQ_TYPE_EDGE_RISING); /* fixed or unlimited length? */ - if (dev->rx_cfg.fixed_message_length != 0) - { - if (dev->rx_cfg.fixed_message_length > dev->rx_buffer_size) - { + if (dev->rx_cfg.fixed_message_length != 0) { + if (dev->rx_cfg.fixed_message_length > dev->rx_buffer_size) { retval = -1; goto abort; } bytes_total = dev->rx_cfg.fixed_message_length; - dev_dbg(dev->dev,"rx: msg len set to %d by fixed length", bytes_total); - } - else - { + dev_dbg(dev->dev, "rx: msg len set to %d by fixed length", bytes_total); + } else { bytes_total = dev->rx_buffer_size; dev_dbg(dev->dev, "rx: msg len set to %d as requested by read", bytes_total); } /* length byte enabled? */ - if (dev->rx_cfg.enable_length_byte == optionOn) - { + if (dev->rx_cfg.enable_length_byte == OPTION_ON) { retval = wait_event_interruptible(dev->fifo_wait_queue, dev->free_in_fifo < FIFO_SIZE); - if (retval) goto abort; /* wait was interrupted */ + if (retval) /* wait was interrupted */ + goto abort; rf69_read_fifo(spi, (u8 *)&bytes_total, 1); if (bytes_total > dev->rx_buffer_size) { @@ -416,15 +493,15 @@ pi433_receive(void *data) } /* address byte enabled? */ - if (dev->rx_cfg.enable_address_filtering != filteringOff) - { + if (dev->rx_cfg.enable_address_filtering != filteringOff) { u8 dummy; bytes_total--; retval = wait_event_interruptible(dev->fifo_wait_queue, dev->free_in_fifo < FIFO_SIZE); - if (retval) goto abort; /* wait was interrupted */ + if (retval) /* wait was interrupted */ + goto abort; rf69_read_fifo(spi, &dummy, 1); dev->free_in_fifo++; @@ -432,13 +509,12 @@ pi433_receive(void *data) } /* get payload */ - while (dev->rx_position < bytes_total) - { - if ( !rf69_get_flag(dev->spi, payloadReady) ) - { + while (dev->rx_position < bytes_total) { + if (!rf69_get_flag(dev->spi, payload_ready)) { retval = wait_event_interruptible(dev->fifo_wait_queue, dev->free_in_fifo < FIFO_SIZE); - if (retval) goto abort; /* wait was interrupted */ + if (retval) /* wait was interrupted */ + goto abort; } /* need to drop bytes or acquire? */ @@ -447,14 +523,15 @@ pi433_receive(void *data) else bytes_to_read = bytes_total - dev->rx_position; - /* access the fifo */ if (bytes_to_read > FIFO_SIZE - dev->free_in_fifo) bytes_to_read = FIFO_SIZE - dev->free_in_fifo; retval = rf69_read_fifo(spi, &dev->rx_buffer[dev->rx_position], bytes_to_read); - if (retval) goto abort; /* read failed */ + if (retval) /* read failed */ + goto abort; + dev->free_in_fifo += bytes_to_read; /* adjust status vars */ @@ -464,11 +541,11 @@ pi433_receive(void *data) dev->rx_position += bytes_to_read; } - /* rx done, wait was interrupted or error occurred */ abort: dev->interrupt_rx_allowed = true; - SET_CHECKED(rf69_set_mode(dev->spi, standby)); + if (rf69_set_mode(dev->spi, standby)) + pr_err("rf69_set_mode(): radio module failed to go standby\n"); wake_up_interruptible(&dev->tx_wait_queue); if (retval) @@ -481,22 +558,20 @@ static int pi433_tx_thread(void *data) { struct pi433_device *device = data; - struct spi_device *spi = device->spi; /* needed for SET_CHECKED */ + struct spi_device *spi = device->spi; struct pi433_tx_cfg tx_cfg; - u8 *buffer = device->buffer; size_t size; bool rx_interrupted = false; int position, repetitions; int retval; - while (1) - { + while (1) { /* wait for fifo to be populated or for request to terminate*/ dev_dbg(device->dev, "thread: going to wait for new messages"); wait_event_interruptible(device->tx_wait_queue, - ( !kfifo_is_empty(&device->tx_fifo) || - kthread_should_stop() )); - if ( kthread_should_stop() ) + (!kfifo_is_empty(&device->tx_fifo) || + kthread_should_stop())); + if (kthread_should_stop()) return 0; /* get data from fifo in the following order: @@ -508,14 +583,14 @@ pi433_tx_thread(void *data) retval = kfifo_out(&device->tx_fifo, &tx_cfg, sizeof(tx_cfg)); if (retval != sizeof(tx_cfg)) { - dev_dbg(device->dev, "reading tx_cfg from fifo failed: got %d byte(s), expected %d", retval, (unsigned int)sizeof(tx_cfg) ); + dev_dbg(device->dev, "reading tx_cfg from fifo failed: got %d byte(s), expected %d", retval, (unsigned int)sizeof(tx_cfg)); mutex_unlock(&device->tx_fifo_lock); continue; } retval = kfifo_out(&device->tx_fifo, &size, sizeof(size_t)); if (retval != sizeof(size_t)) { - dev_dbg(device->dev, "reading msg size from fifo failed: got %d, expected %d", retval, (unsigned int)sizeof(size_t) ); + dev_dbg(device->dev, "reading msg size from fifo failed: got %d, expected %d", retval, (unsigned int)sizeof(size_t)); mutex_unlock(&device->tx_fifo_lock); continue; } @@ -525,27 +600,27 @@ pi433_tx_thread(void *data) size = tx_cfg.fixed_message_length; /* increase size, if len byte is requested */ - if (tx_cfg.enable_length_byte == optionOn) + if (tx_cfg.enable_length_byte == OPTION_ON) size++; /* increase size, if adr byte is requested */ - if (tx_cfg.enable_address_byte == optionOn) + if (tx_cfg.enable_address_byte == OPTION_ON) size++; /* prime buffer */ - memset(buffer, 0, size); + memset(device->buffer, 0, size); position = 0; /* add length byte, if requested */ - if (tx_cfg.enable_length_byte == optionOn) - buffer[position++] = size-1; /* according to spec length byte itself must be excluded from the length calculation */ + if (tx_cfg.enable_length_byte == OPTION_ON) + device->buffer[position++] = size - 1; /* according to spec length byte itself must be excluded from the length calculation */ /* add adr byte, if requested */ - if (tx_cfg.enable_address_byte == optionOn) - buffer[position++] = tx_cfg.address_byte; + if (tx_cfg.enable_address_byte == OPTION_ON) + device->buffer[position++] = tx_cfg.address_byte; /* finally get message data from fifo */ - retval = kfifo_out(&device->tx_fifo, &buffer[position], sizeof(buffer)-position ); + retval = kfifo_out(&device->tx_fifo, &device->buffer[position], sizeof(device->buffer) - position); dev_dbg(device->dev, "read %d message byte(s) from fifo queue.", retval); mutex_unlock(&device->tx_fifo_lock); @@ -557,7 +632,7 @@ pi433_tx_thread(void *data) */ wait_event_interruptible(device->tx_wait_queue, !device->rx_active || - device->interrupt_rx_allowed == true); + device->interrupt_rx_allowed); /* prevent race conditions * irq will be reenabled after tx config is set @@ -565,91 +640,107 @@ pi433_tx_thread(void *data) disable_irq(device->irq_num[DIO0]); device->tx_active = true; - if (device->rx_active && rx_interrupted == false) - { + if (device->rx_active && !rx_interrupted) { /* rx is currently waiting for a telegram; * we need to set the radio module to standby */ - SET_CHECKED(rf69_set_mode(device->spi, standby)); + retval = rf69_set_mode(device->spi, standby); + if (retval < 0) + return retval; rx_interrupted = true; } /* clear fifo, set fifo threshold, set payload length */ - SET_CHECKED(rf69_set_mode(spi, standby)); /* this clears the fifo */ - SET_CHECKED(rf69_set_fifo_threshold(spi, FIFO_THRESHOLD)); - if (tx_cfg.enable_length_byte == optionOn) - { - SET_CHECKED(rf69_set_payload_length(spi, size * tx_cfg.repetitions)); - } - else - { - SET_CHECKED(rf69_set_payload_length(spi, 0)); + retval = rf69_set_mode(spi, standby); /* this clears the fifo */ + if (retval < 0) + return retval; + retval = rf69_set_fifo_threshold(spi, FIFO_THRESHOLD); + if (retval < 0) + return retval; + if (tx_cfg.enable_length_byte == OPTION_ON) { + retval = rf69_set_payload_length(spi, size * tx_cfg.repetitions); + if (retval < 0) + return retval; + } else { + retval = rf69_set_payload_length(spi, 0); + if (retval < 0) + return retval; } /* configure the rf chip */ - rf69_set_tx_cfg(device, &tx_cfg); + retval = rf69_set_tx_cfg(device, &tx_cfg); + if (retval < 0) + return retval; /* enable fifo level interrupt */ - SET_CHECKED(rf69_set_dio_mapping(spi, DIO1, DIO_FifoLevel)); - device->irq_state[DIO1] = DIO_FifoLevel; + retval = rf69_set_dio_mapping(spi, DIO1, DIO_FIFO_LEVEL); + if (retval < 0) + return retval; + device->irq_state[DIO1] = DIO_FIFO_LEVEL; irq_set_irq_type(device->irq_num[DIO1], IRQ_TYPE_EDGE_FALLING); /* enable packet sent interrupt */ - SET_CHECKED(rf69_set_dio_mapping(spi, DIO0, DIO_PacketSent)); - device->irq_state[DIO0] = DIO_PacketSent; + retval = rf69_set_dio_mapping(spi, DIO0, DIO_PACKET_SENT); + if (retval < 0) + return retval; + device->irq_state[DIO0] = DIO_PACKET_SENT; irq_set_irq_type(device->irq_num[DIO0], IRQ_TYPE_EDGE_RISING); enable_irq(device->irq_num[DIO0]); /* was disabled by rx active check */ /* enable transmission */ - SET_CHECKED(rf69_set_mode(spi, transmit)); + retval = rf69_set_mode(spi, transmit); + if (retval < 0) + return retval; /* transfer this msg (and repetitions) to chip fifo */ device->free_in_fifo = FIFO_SIZE; position = 0; repetitions = tx_cfg.repetitions; - while( (repetitions > 0) && (size > position) ) - { - if ( (size - position) > device->free_in_fifo) - { /* msg to big for fifo - take a part */ + while ((repetitions > 0) && (size > position)) { + if ((size - position) > device->free_in_fifo) { + /* msg to big for fifo - take a part */ int temp = device->free_in_fifo; device->free_in_fifo = 0; rf69_write_fifo(spi, - &buffer[position], - temp); - position +=temp; - } - else - { /* msg fits into fifo - take all */ + &device->buffer[position], + temp); + position += temp; + } else { + /* msg fits into fifo - take all */ device->free_in_fifo -= size; repetitions--; rf69_write_fifo(spi, - &buffer[position], - (size - position) ); + &device->buffer[position], + (size - position)); position = 0; /* reset for next repetition */ } retval = wait_event_interruptible(device->fifo_wait_queue, device->free_in_fifo > 0); - if (retval) { printk("ABORT\n"); goto abort; } + if (retval) { + dev_dbg(device->dev, "ABORT\n"); + goto abort; + } } /* we are done. Wait for packet to get sent */ dev_dbg(device->dev, "thread: wait for packet to get sent/fifo to be empty"); wait_event_interruptible(device->fifo_wait_queue, device->free_in_fifo == FIFO_SIZE || - kthread_should_stop() ); - if ( kthread_should_stop() ) printk("ABORT\n"); - + kthread_should_stop()); + if (kthread_should_stop()) + dev_dbg(device->dev, "ABORT\n"); /* STOP_TRANSMISSION */ dev_dbg(device->dev, "thread: Packet sent. Set mode to stby."); - SET_CHECKED(rf69_set_mode(spi, standby)); + retval = rf69_set_mode(spi, standby); + if (retval < 0) + return retval; /* everything sent? */ if (kfifo_is_empty(&device->tx_fifo)) { abort: - if (rx_interrupted) - { + if (rx_interrupted) { rx_interrupted = false; pi433_start_rx(device); } @@ -678,16 +769,13 @@ pi433_read(struct file *filp, char __user *buf, size_t size, loff_t *f_pos) /* just one read request at a time */ mutex_lock(&device->rx_lock); - if (device->rx_active) - { + if (device->rx_active) { mutex_unlock(&device->rx_lock); return -EAGAIN; } - else - { - device->rx_active = true; - mutex_unlock(&device->rx_lock); - } + + device->rx_active = true; + mutex_unlock(&device->rx_lock); /* start receiving */ /* will block until something was received*/ @@ -709,14 +797,14 @@ pi433_read(struct file *filp, char __user *buf, size_t size, loff_t *f_pos) return bytes_received; } - static ssize_t pi433_write(struct file *filp, const char __user *buf, - size_t count, loff_t *f_pos) + size_t count, loff_t *f_pos) { struct pi433_instance *instance; struct pi433_device *device; - int copied, retval; + int retval; + unsigned int copied; instance = filp->private_data; device = instance->device; @@ -732,11 +820,11 @@ pi433_write(struct file *filp, const char __user *buf, */ mutex_lock(&device->tx_fifo_lock); retval = kfifo_in(&device->tx_fifo, &instance->tx_cfg, sizeof(instance->tx_cfg)); - if ( retval != sizeof(instance->tx_cfg) ) + if (retval != sizeof(instance->tx_cfg)) goto abort; - retval = kfifo_in (&device->tx_fifo, &count, sizeof(size_t)); - if ( retval != sizeof(size_t) ) + retval = kfifo_in(&device->tx_fifo, &count, sizeof(size_t)); + if (retval != sizeof(size_t)) goto abort; retval = kfifo_from_user(&device->tx_fifo, buf, count, &copied); @@ -749,7 +837,7 @@ pi433_write(struct file *filp, const char __user *buf, wake_up_interruptible(&device->tx_wait_queue); dev_dbg(device->dev, "write: generated new msg with %d bytes.", copied); - return 0; + return copied; abort: dev_dbg(device->dev, "write to fifo failed: 0x%x", retval); @@ -758,7 +846,6 @@ abort: return -EAGAIN; } - static long pi433_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { @@ -777,23 +864,23 @@ pi433_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) instance = filp->private_data; device = instance->device; - if (device == NULL) + if (!device) return -ESHUTDOWN; switch (cmd) { case PI433_IOC_RD_TX_CFG: if (copy_to_user(argp, &instance->tx_cfg, - sizeof(struct pi433_tx_cfg))) + sizeof(struct pi433_tx_cfg))) return -EFAULT; break; case PI433_IOC_WR_TX_CFG: if (copy_from_user(&instance->tx_cfg, argp, - sizeof(struct pi433_tx_cfg))) + sizeof(struct pi433_tx_cfg))) return -EFAULT; break; case PI433_IOC_RD_RX_CFG: if (copy_to_user(argp, &device->rx_cfg, - sizeof(struct pi433_rx_cfg))) + sizeof(struct pi433_rx_cfg))) return -EFAULT; break; case PI433_IOC_WR_RX_CFG: @@ -806,7 +893,7 @@ pi433_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } if (copy_from_user(&device->rx_cfg, argp, - sizeof(struct pi433_rx_cfg))) { + sizeof(struct pi433_rx_cfg))) { mutex_unlock(&device->rx_lock); return -EFAULT; } @@ -847,10 +934,8 @@ static int pi433_open(struct inode *inode, struct file *filp) if (!device->rx_buffer) { device->rx_buffer = kmalloc(MAX_MSG_SIZE, GFP_KERNEL); - if (!device->rx_buffer) { - dev_dbg(device->dev, "open/ENOMEM\n"); + if (!device->rx_buffer) return -ENOMEM; - } } device->users++; @@ -889,19 +974,18 @@ static int pi433_release(struct inode *inode, struct file *filp) if (!device->users) { kfree(device->rx_buffer); device->rx_buffer = NULL; - if (device->spi == NULL) + if (!device->spi) kfree(device); } return 0; } - /*-------------------------------------------------------------------------*/ static int setup_GPIOs(struct pi433_device *device) { - char name[5]; + char name[5]; int retval; int i; const irq_handler_t DIO_irq_handler[NUM_DIO] = { @@ -909,8 +993,7 @@ static int setup_GPIOs(struct pi433_device *device) DIO1_irq_handler }; - for (i=0; i<NUM_DIO; i++) - { + for (i = 0; i < NUM_DIO; i++) { /* "construct" name and get the gpio descriptor */ snprintf(name, sizeof(name), "DIO%d", i); device->gpiod[i] = gpiod_get(&device->spi->dev, name, 0 /*GPIOD_IN*/); @@ -923,24 +1006,21 @@ static int setup_GPIOs(struct pi433_device *device) if (device->gpiod[i] == ERR_PTR(-EBUSY)) dev_dbg(&device->spi->dev, "%s is busy.", name); - if ( IS_ERR(device->gpiod[i]) ) - { + if (IS_ERR(device->gpiod[i])) { retval = PTR_ERR(device->gpiod[i]); /* release already allocated gpios */ - for (i--; i>=0; i--) - { + for (i--; i >= 0; i--) { free_irq(device->irq_num[i], device); gpiod_put(device->gpiod[i]); } return retval; } - /* configure the pin */ gpiod_unexport(device->gpiod[i]); retval = gpiod_direction_input(device->gpiod[i]); - if (retval) return retval; - + if (retval) + return retval; /* configure irq */ device->irq_num[i] = gpiod_to_irq(device->gpiod[i]); @@ -967,16 +1047,14 @@ static void free_GPIOs(struct pi433_device *device) { int i; - for (i=0; i<NUM_DIO; i++) - { + for (i = 0; i < NUM_DIO; i++) { /* check if gpiod is valid */ - if ( IS_ERR(device->gpiod[i]) ) + if (IS_ERR(device->gpiod[i])) continue; free_irq(device->irq_num[i], device); gpiod_put(device->gpiod[i]); } - return; } static int pi433_get_minor(struct pi433_device *device) @@ -989,7 +1067,7 @@ static int pi433_get_minor(struct pi433_device *device) device->minor = retval; retval = 0; } else if (retval == -ENOSPC) { - dev_err(device->dev, "too many pi433 devices\n"); + dev_err(&device->spi->dev, "too many pi433 devices\n"); retval = -EINVAL; } mutex_unlock(&minor_lock); @@ -1002,6 +1080,7 @@ static void pi433_free_minor(struct pi433_device *dev) idr_remove(&pi433_idr, dev->minor); mutex_unlock(&minor_lock); } + /*-------------------------------------------------------------------------*/ static const struct file_operations pi433_fops = { @@ -1032,17 +1111,14 @@ static int pi433_probe(struct spi_device *spi) /* spi->max_speed_hz = 10000000; 1MHz already set by device tree overlay */ retval = spi_setup(spi); - if (retval) - { + if (retval) { dev_dbg(&spi->dev, "configuration of SPI interface failed!\n"); return retval; } - else - { - dev_dbg(&spi->dev, - "spi interface setup: mode 0x%2x, %d bits per word, %dhz max speed", - spi->mode, spi->bits_per_word, spi->max_speed_hz); - } + + dev_dbg(&spi->dev, + "spi interface setup: mode 0x%2x, %d bits per word, %dhz max speed", + spi->mode, spi->bits_per_word, spi->max_speed_hz); /* Ping the chip by reading the version register */ retval = spi_w8r8(spi, 0x10); @@ -1089,27 +1165,32 @@ static int pi433_probe(struct spi_device *spi) } /* setup the radio module */ - SET_CHECKED(rf69_set_mode (spi, standby)); - SET_CHECKED(rf69_set_data_mode (spi, packet)); - SET_CHECKED(rf69_set_amplifier_0 (spi, optionOn)); - SET_CHECKED(rf69_set_amplifier_1 (spi, optionOff)); - SET_CHECKED(rf69_set_amplifier_2 (spi, optionOff)); - SET_CHECKED(rf69_set_output_power_level (spi, 13)); - SET_CHECKED(rf69_set_antenna_impedance (spi, fiftyOhm)); - - /* start tx thread */ - device->tx_task_struct = kthread_run(pi433_tx_thread, - device, - "pi433_tx_task"); - if (IS_ERR(device->tx_task_struct)) { - dev_dbg(device->dev, "start of send thread failed"); - goto send_thread_failed; - } + retval = rf69_set_mode(spi, standby); + if (retval < 0) + goto minor_failed; + retval = rf69_set_data_mode(spi, DATAMODUL_MODE_PACKET); + if (retval < 0) + goto minor_failed; + retval = rf69_enable_amplifier(spi, MASK_PALEVEL_PA0); + if (retval < 0) + goto minor_failed; + retval = rf69_disable_amplifier(spi, MASK_PALEVEL_PA1); + if (retval < 0) + goto minor_failed; + retval = rf69_disable_amplifier(spi, MASK_PALEVEL_PA2); + if (retval < 0) + goto minor_failed; + retval = rf69_set_output_power_level(spi, 13); + if (retval < 0) + goto minor_failed; + retval = rf69_set_antenna_impedance(spi, fiftyOhm); + if (retval < 0) + goto minor_failed; /* determ minor number */ retval = pi433_get_minor(device); if (retval) { - dev_dbg(device->dev, "get of minor number failed"); + dev_dbg(&spi->dev, "get of minor number failed"); goto minor_failed; } @@ -1119,19 +1200,29 @@ static int pi433_probe(struct spi_device *spi) &spi->dev, device->devt, device, - "pi433"); + "pi433.%d", + device->minor); if (IS_ERR(device->dev)) { pr_err("pi433: device register failed\n"); retval = PTR_ERR(device->dev); goto device_create_failed; - } - else { + } else { dev_dbg(device->dev, "created device for major %d, minor %d\n", MAJOR(pi433_dev), device->minor); } + /* start tx thread */ + device->tx_task_struct = kthread_run(pi433_tx_thread, + device, + "pi433.%d_tx_task", + device->minor); + if (IS_ERR(device->tx_task_struct)) { + dev_dbg(device->dev, "start of send thread failed"); + goto send_thread_failed; + } + /* create cdev */ device->cdev = cdev_alloc(); device->cdev->owner = THIS_MODULE; @@ -1148,12 +1239,12 @@ static int pi433_probe(struct spi_device *spi) return 0; cdev_failed: + kthread_stop(device->tx_task_struct); +send_thread_failed: device_destroy(pi433_class, device->devt); device_create_failed: pi433_free_minor(device); minor_failed: - kthread_stop(device->tx_task_struct); -send_thread_failed: free_GPIOs(device); GPIO_failed: kfree(device); @@ -1230,14 +1321,16 @@ static int __init pi433_init(void) pi433_class = class_create(THIS_MODULE, "pi433"); if (IS_ERR(pi433_class)) { - unregister_chrdev(MAJOR(pi433_dev), pi433_spi_driver.driver.name); + unregister_chrdev(MAJOR(pi433_dev), + pi433_spi_driver.driver.name); return PTR_ERR(pi433_class); } status = spi_register_driver(&pi433_spi_driver); if (status < 0) { class_destroy(pi433_class); - unregister_chrdev(MAJOR(pi433_dev), pi433_spi_driver.driver.name); + unregister_chrdev(MAJOR(pi433_dev), + pi433_spi_driver.driver.name); } return status; diff --git a/drivers/staging/pi433/pi433_if.h b/drivers/staging/pi433/pi433_if.h index e6ed3cd9b2e2..7314f69af198 100644 --- a/drivers/staging/pi433/pi433_if.h +++ b/drivers/staging/pi433/pi433_if.h @@ -34,8 +34,10 @@ /*---------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------*/ +enum option_on_off { + OPTION_OFF, + OPTION_ON +}; /* IOCTL structs and commands */ @@ -57,14 +59,13 @@ * * NOTE: struct layout is the same in 64bit and 32bit userspace. */ -#define PI433_TX_CFG_IOCTL_NR 0 -struct pi433_tx_cfg -{ +#define PI433_TX_CFG_IOCTL_NR 0 +struct pi433_tx_cfg { __u32 frequency; __u16 bit_rate; __u32 dev_frequency; enum modulation modulation; - enum modShaping modShaping; + enum mod_shaping mod_shaping; enum paRamp pa_ramp; @@ -72,13 +73,12 @@ struct pi433_tx_cfg __u16 repetitions; - /* packet format */ - enum optionOnOff enable_preamble; - enum optionOnOff enable_sync; - enum optionOnOff enable_length_byte; - enum optionOnOff enable_address_byte; - enum optionOnOff enable_crc; + enum option_on_off enable_preamble; + enum option_on_off enable_sync; + enum option_on_off enable_length_byte; + enum option_on_off enable_address_byte; + enum option_on_off enable_crc; __u16 preamble_length; __u8 sync_length; @@ -88,7 +88,6 @@ struct pi433_tx_cfg __u8 address_byte; }; - /** * struct pi433_rx_config - describes the configuration of the radio module for sending * @frequency: @@ -107,7 +106,7 @@ struct pi433_tx_cfg * * NOTE: struct layout is the same in 64bit and 32bit userspace. */ -#define PI433_RX_CFG_IOCTL_NR 1 +#define PI433_RX_CFG_IOCTL_NR 1 struct pi433_rx_cfg { __u32 frequency; __u16 bit_rate; @@ -116,20 +115,18 @@ struct pi433_rx_cfg { enum modulation modulation; __u8 rssi_threshold; - enum thresholdDecrement thresholdDecrement; + enum thresholdDecrement threshold_decrement; enum antennaImpedance antenna_impedance; enum lnaGain lna_gain; enum mantisse bw_mantisse; /* normal: 0x50 */ __u8 bw_exponent; /* during AFC: 0x8b */ enum dagc dagc; - - /* packet format */ - enum optionOnOff enable_sync; - enum optionOnOff enable_length_byte; /* should be used in combination with sync, only */ + enum option_on_off enable_sync; + enum option_on_off enable_length_byte; /* should be used in combination with sync, only */ enum addressFiltering enable_address_filtering; /* operational with sync, only */ - enum optionOnOff enable_crc; /* only operational, if sync on and fixed length or length byte is used */ + enum option_on_off enable_crc; /* only operational, if sync on and fixed length or length byte is used */ __u8 sync_length; __u8 fixed_message_length; @@ -140,7 +137,6 @@ struct pi433_rx_cfg { __u8 broadcast_address; }; - #define PI433_IOC_MAGIC 'r' #define PI433_IOC_RD_TX_CFG _IOR(PI433_IOC_MAGIC, PI433_TX_CFG_IOCTL_NR, char[sizeof(struct pi433_tx_cfg)]) diff --git a/drivers/staging/pi433/rf69.c b/drivers/staging/pi433/rf69.c index 12c9df9cddde..7ccdff6ae213 100644 --- a/drivers/staging/pi433/rf69.c +++ b/drivers/staging/pi433/rf69.c @@ -29,27 +29,98 @@ #include "rf69_registers.h" #define F_OSC 32000000 /* in Hz */ -#define FIFO_SIZE 66 /* in byte */ +#define FIFO_SIZE 66 /* in byte */ /*-------------------------------------------------------------------------*/ -#define READ_REG(x) rf69_read_reg (spi, x) -#define WRITE_REG(x, y) rf69_write_reg(spi, x, y) +static u8 rf69_read_reg(struct spi_device *spi, u8 addr) +{ + int retval; + + retval = spi_w8r8(spi, addr); + +#ifdef DEBUG_VALUES + if (retval < 0) + /* should never happen, since we already checked, + * that module is connected. Therefore no error + * handling, just an optional error message... + */ + dev_dbg(&spi->dev, "read 0x%x FAILED\n", addr); + else + dev_dbg(&spi->dev, "read 0x%x from reg 0x%x\n", retval, addr); +#endif + + return retval; +} + +static int rf69_write_reg(struct spi_device *spi, u8 addr, u8 value) +{ + int retval; + char buffer[2]; + + buffer[0] = addr | WRITE_BIT; + buffer[1] = value; + + retval = spi_write(spi, &buffer, 2); + +#ifdef DEBUG_VALUES + if (retval < 0) + /* should never happen, since we already checked, + * that module is connected. Therefore no error + * handling, just an optional error message... + */ + dev_dbg(&spi->dev, "write 0x%x to 0x%x FAILED\n", value, addr); + else + dev_dbg(&spi->dev, "wrote 0x%x to reg 0x%x\n", value, addr); +#endif + + return retval; +} /*-------------------------------------------------------------------------*/ -int rf69_set_mode(struct spi_device *spi, enum mode mode) +static int rf69_set_bit(struct spi_device *spi, u8 reg, u8 mask) +{ + u8 tmp; + + tmp = rf69_read_reg(spi, reg); + tmp = tmp | mask; + return rf69_write_reg(spi, reg, tmp); +} + +static int rf69_clear_bit(struct spi_device *spi, u8 reg, u8 mask) { - #ifdef DEBUG - dev_dbg(&spi->dev, "set: mode"); - #endif + u8 tmp; + tmp = rf69_read_reg(spi, reg); + tmp = tmp & ~mask; + return rf69_write_reg(spi, reg, tmp); +} + +static inline int rf69_read_mod_write(struct spi_device *spi, u8 reg, u8 mask, u8 value) +{ + u8 tmp; + + tmp = rf69_read_reg(spi, reg); + tmp = (tmp & ~mask) | value; + return rf69_write_reg(spi, reg, tmp); +} + +/*-------------------------------------------------------------------------*/ + +int rf69_set_mode(struct spi_device *spi, enum mode mode) +{ switch (mode) { - case transmit: return WRITE_REG(REG_OPMODE, (READ_REG(REG_OPMODE) & ~MASK_OPMODE_MODE) | OPMODE_MODE_TRANSMIT); - case receive: return WRITE_REG(REG_OPMODE, (READ_REG(REG_OPMODE) & ~MASK_OPMODE_MODE) | OPMODE_MODE_RECEIVE); - case synthesizer: return WRITE_REG(REG_OPMODE, (READ_REG(REG_OPMODE) & ~MASK_OPMODE_MODE) | OPMODE_MODE_SYNTHESIZER); - case standby: return WRITE_REG(REG_OPMODE, (READ_REG(REG_OPMODE) & ~MASK_OPMODE_MODE) | OPMODE_MODE_STANDBY); - case mode_sleep: return WRITE_REG(REG_OPMODE, (READ_REG(REG_OPMODE) & ~MASK_OPMODE_MODE) | OPMODE_MODE_SLEEP); + case transmit: + return rf69_read_mod_write(spi, REG_OPMODE, MASK_OPMODE_MODE, OPMODE_MODE_TRANSMIT); + case receive: + return rf69_read_mod_write(spi, REG_OPMODE, MASK_OPMODE_MODE, OPMODE_MODE_RECEIVE); + case synthesizer: + return rf69_read_mod_write(spi, REG_OPMODE, MASK_OPMODE_MODE, OPMODE_MODE_SYNTHESIZER); + case standby: + return rf69_read_mod_write(spi, REG_OPMODE, MASK_OPMODE_MODE, OPMODE_MODE_STANDBY); + case mode_sleep: + return rf69_read_mod_write(spi, REG_OPMODE, MASK_OPMODE_MODE, OPMODE_MODE_SLEEP); default: dev_dbg(&spi->dev, "set: illegal input param"); return -EINVAL; @@ -58,82 +129,75 @@ int rf69_set_mode(struct spi_device *spi, enum mode mode) // we are using packet mode, so this check is not really needed // but waiting for mode ready is necessary when going from sleep because the FIFO may not be immediately available from previous mode //while (_mode == RF69_MODE_SLEEP && (READ_REG(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00); // Wait for ModeReady - } -int rf69_set_data_mode(struct spi_device *spi, enum dataMode dataMode) +int rf69_set_data_mode(struct spi_device *spi, u8 data_mode) { - #ifdef DEBUG - dev_dbg(&spi->dev, "set: data mode"); - #endif - - switch (dataMode) { - case packet: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODE) | DATAMODUL_MODE_PACKET); - case continuous: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODE) | DATAMODUL_MODE_CONTINUOUS); - case continuousNoSync: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODE) | DATAMODUL_MODE_CONTINUOUS_NOSYNC); - default: - dev_dbg(&spi->dev, "set: illegal input param"); - return -EINVAL; - } + return rf69_read_mod_write(spi, REG_DATAMODUL, MASK_DATAMODUL_MODE, data_mode); } int rf69_set_modulation(struct spi_device *spi, enum modulation modulation) { - #ifdef DEBUG - dev_dbg(&spi->dev, "set: modulation"); - #endif - switch (modulation) { - case OOK: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_TYPE) | DATAMODUL_MODULATION_TYPE_OOK); - case FSK: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_TYPE) | DATAMODUL_MODULATION_TYPE_FSK); + case OOK: + return rf69_read_mod_write(spi, REG_DATAMODUL, MASK_DATAMODUL_MODULATION_TYPE, DATAMODUL_MODULATION_TYPE_OOK); + case FSK: + return rf69_read_mod_write(spi, REG_DATAMODUL, MASK_DATAMODUL_MODULATION_TYPE, DATAMODUL_MODULATION_TYPE_FSK); default: dev_dbg(&spi->dev, "set: illegal input param"); return -EINVAL; } } -enum modulation rf69_get_modulation(struct spi_device *spi) +static enum modulation rf69_get_modulation(struct spi_device *spi) { u8 currentValue; - #ifdef DEBUG - dev_dbg(&spi->dev, "get: mode"); - #endif - - currentValue = READ_REG(REG_DATAMODUL); + currentValue = rf69_read_reg(spi, REG_DATAMODUL); switch (currentValue & MASK_DATAMODUL_MODULATION_TYPE) { - case DATAMODUL_MODULATION_TYPE_OOK: return OOK; - case DATAMODUL_MODULATION_TYPE_FSK: return FSK; - default: return undefined; + case DATAMODUL_MODULATION_TYPE_OOK: + return OOK; + case DATAMODUL_MODULATION_TYPE_FSK: + return FSK; + default: + return UNDEF; } } -int rf69_set_modulation_shaping(struct spi_device *spi, enum modShaping modShaping) +int rf69_set_modulation_shaping(struct spi_device *spi, + enum mod_shaping mod_shaping) { - #ifdef DEBUG - dev_dbg(&spi->dev, "set: mod shaping"); - #endif - - if (rf69_get_modulation(spi) == FSK) { - switch (modShaping) { - case shapingOff: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_NONE); - case shaping1_0: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_1_0); - case shaping0_5: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_0_3); - case shaping0_3: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_0_5); + switch (rf69_get_modulation(spi)) { + case FSK: + switch (mod_shaping) { + case SHAPING_OFF: + return rf69_read_mod_write(spi, REG_DATAMODUL, MASK_DATAMODUL_MODULATION_SHAPE, DATAMODUL_MODULATION_SHAPE_NONE); + case SHAPING_1_0: + return rf69_read_mod_write(spi, REG_DATAMODUL, MASK_DATAMODUL_MODULATION_SHAPE, DATAMODUL_MODULATION_SHAPE_1_0); + case SHAPING_0_5: + return rf69_read_mod_write(spi, REG_DATAMODUL, MASK_DATAMODUL_MODULATION_SHAPE, DATAMODUL_MODULATION_SHAPE_0_5); + case SHAPING_0_3: + return rf69_read_mod_write(spi, REG_DATAMODUL, MASK_DATAMODUL_MODULATION_SHAPE, DATAMODUL_MODULATION_SHAPE_0_3); default: dev_dbg(&spi->dev, "set: illegal input param"); return -EINVAL; } - } else { - switch (modShaping) { - case shapingOff: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_NONE); - case shapingBR: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_BR); - case shaping2BR: return WRITE_REG(REG_DATAMODUL, (READ_REG(REG_DATAMODUL) & ~MASK_DATAMODUL_MODULATION_SHAPE) | DATAMODUL_MODULATION_SHAPE_2BR); + case OOK: + switch (mod_shaping) { + case SHAPING_OFF: + return rf69_read_mod_write(spi, REG_DATAMODUL, MASK_DATAMODUL_MODULATION_SHAPE, DATAMODUL_MODULATION_SHAPE_NONE); + case SHAPING_BR: + return rf69_read_mod_write(spi, REG_DATAMODUL, MASK_DATAMODUL_MODULATION_SHAPE, DATAMODUL_MODULATION_SHAPE_BR); + case SHAPING_2BR: + return rf69_read_mod_write(spi, REG_DATAMODUL, MASK_DATAMODUL_MODULATION_SHAPE, DATAMODUL_MODULATION_SHAPE_2BR); default: dev_dbg(&spi->dev, "set: illegal input param"); return -EINVAL; } + default: + dev_dbg(&spi->dev, "set: modulation undefined"); + return -EINVAL; } } @@ -145,10 +209,6 @@ int rf69_set_bit_rate(struct spi_device *spi, u16 bitRate) u8 msb; u8 lsb; - #ifdef DEBUG - dev_dbg(&spi->dev, "set: bit rate"); - #endif - // check input value bitRate_min = F_OSC / 8388608; // 8388608 = 2^23; if (bitRate < bitRate_min) { @@ -159,15 +219,14 @@ int rf69_set_bit_rate(struct spi_device *spi, u16 bitRate) // calculate reg settings bitRate_reg = (F_OSC / bitRate); - msb = (bitRate_reg&0xff00) >> 8; - lsb = (bitRate_reg&0xff); + msb = (bitRate_reg & 0xff00) >> 8; + lsb = (bitRate_reg & 0xff); // transmit to RF 69 - retval = WRITE_REG(REG_BITRATE_MSB, msb); + retval = rf69_write_reg(spi, REG_BITRATE_MSB, msb); if (retval) return retval; - - retval = WRITE_REG(REG_BITRATE_LSB, lsb); + retval = rf69_write_reg(spi, REG_BITRATE_LSB, lsb); if (retval) return retval; @@ -177,18 +236,14 @@ int rf69_set_bit_rate(struct spi_device *spi, u16 bitRate) int rf69_set_deviation(struct spi_device *spi, u32 deviation) { int retval; -// u32 f_max; TODO: Abhängigkeit von Bitrate beachten!! u64 f_reg; u64 f_step; u8 msb; u8 lsb; u64 factor = 1000000; // to improve precision of calculation - #ifdef DEBUG - dev_dbg(&spi->dev, "set: deviation"); - #endif - - if (deviation < 600 || deviation > 500000) { //TODO: Abhängigkeit von Bitrate beachten!! + // TODO: Dependency to bitrate + if (deviation < 600 || deviation > 500000) { dev_dbg(&spi->dev, "set_deviation: illegal input param"); return -EINVAL; } @@ -201,8 +256,8 @@ int rf69_set_deviation(struct spi_device *spi, u32 deviation) f_reg = deviation * factor; do_div(f_reg, f_step); - msb = (f_reg&0xff00) >> 8; - lsb = (f_reg&0xff); + msb = (f_reg & 0xff00) >> 8; + lsb = (f_reg & 0xff); // check msb if (msb & ~FDEVMASB_MASK) { @@ -211,11 +266,10 @@ int rf69_set_deviation(struct spi_device *spi, u32 deviation) } // write to chip - retval = WRITE_REG(REG_FDEV_MSB, msb); + retval = rf69_write_reg(spi, REG_FDEV_MSB, msb); if (retval) return retval; - - retval = WRITE_REG(REG_FDEV_LSB, lsb); + retval = rf69_write_reg(spi, REG_FDEV_LSB, lsb); if (retval) return retval; @@ -233,10 +287,6 @@ int rf69_set_frequency(struct spi_device *spi, u32 frequency) u8 lsb; u64 factor = 1000000; // to improve precision of calculation - #ifdef DEBUG - dev_dbg(&spi->dev, "set: frequency"); - #endif - // calculat f step f_step = F_OSC * factor; do_div(f_step, 524288); // 524288 = 2^19 @@ -252,78 +302,38 @@ int rf69_set_frequency(struct spi_device *spi, u32 frequency) f_reg = frequency * factor; do_div(f_reg, f_step); - msb = (f_reg&0xff0000) >> 16; - mid = (f_reg&0xff00) >> 8; - lsb = (f_reg&0xff); + msb = (f_reg & 0xff0000) >> 16; + mid = (f_reg & 0xff00) >> 8; + lsb = (f_reg & 0xff); // write to chip - retval = WRITE_REG(REG_FRF_MSB, msb); + retval = rf69_write_reg(spi, REG_FRF_MSB, msb); if (retval) return retval; - - retval = WRITE_REG(REG_FRF_MID, mid); + retval = rf69_write_reg(spi, REG_FRF_MID, mid); if (retval) return retval; - - retval = WRITE_REG(REG_FRF_LSB, lsb); + retval = rf69_write_reg(spi, REG_FRF_LSB, lsb); if (retval) return retval; return 0; } -int rf69_set_amplifier_0(struct spi_device *spi, enum optionOnOff optionOnOff) +int rf69_enable_amplifier(struct spi_device *spi, u8 amplifier_mask) { - #ifdef DEBUG - dev_dbg(&spi->dev, "set: amp #0"); - #endif - - switch (optionOnOff) { - case optionOn: return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) | MASK_PALEVEL_PA0)); - case optionOff: return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) & ~MASK_PALEVEL_PA0)); - default: - dev_dbg(&spi->dev, "set: illegal input param"); - return -EINVAL; - } -} - -int rf69_set_amplifier_1(struct spi_device *spi, enum optionOnOff optionOnOff) -{ - #ifdef DEBUG - dev_dbg(&spi->dev, "set: amp #1"); - #endif - - switch (optionOnOff) { - case optionOn: return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) | MASK_PALEVEL_PA1)); - case optionOff: return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) & ~MASK_PALEVEL_PA1)); - default: - dev_dbg(&spi->dev, "set: illegal input param"); - return -EINVAL; - } + return rf69_set_bit(spi, REG_PALEVEL, amplifier_mask); } -int rf69_set_amplifier_2(struct spi_device *spi, enum optionOnOff optionOnOff) +int rf69_disable_amplifier(struct spi_device *spi, u8 amplifier_mask) { - #ifdef DEBUG - dev_dbg(&spi->dev, "set: amp #2"); - #endif - - switch (optionOnOff) { - case optionOn: return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) | MASK_PALEVEL_PA2)); - case optionOff: return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) & ~MASK_PALEVEL_PA2)); - default: - dev_dbg(&spi->dev, "set: illegal input param"); - return -EINVAL; - } + return rf69_clear_bit(spi, REG_PALEVEL, amplifier_mask); } int rf69_set_output_power_level(struct spi_device *spi, u8 powerLevel) { - #ifdef DEBUG - dev_dbg(&spi->dev, "set: power level"); - #endif - - powerLevel += 18; // TODO Abhängigkeit von PA0,1,2 setting + // TODO: Dependency to PA0,1,2 setting + powerLevel += 18; // check input value if (powerLevel > 0x1f) { @@ -332,32 +342,44 @@ int rf69_set_output_power_level(struct spi_device *spi, u8 powerLevel) } // write value - return WRITE_REG(REG_PALEVEL, (READ_REG(REG_PALEVEL) & ~MASK_PALEVEL_OUTPUT_POWER) | powerLevel); + return rf69_read_mod_write(spi, REG_PALEVEL, MASK_PALEVEL_OUTPUT_POWER, powerLevel); } int rf69_set_pa_ramp(struct spi_device *spi, enum paRamp paRamp) { - #ifdef DEBUG - dev_dbg(&spi->dev, "set: pa ramp"); - #endif - switch (paRamp) { - case ramp3400: return WRITE_REG(REG_PARAMP, PARAMP_3400); - case ramp2000: return WRITE_REG(REG_PARAMP, PARAMP_2000); - case ramp1000: return WRITE_REG(REG_PARAMP, PARAMP_1000); - case ramp500: return WRITE_REG(REG_PARAMP, PARAMP_500); - case ramp250: return WRITE_REG(REG_PARAMP, PARAMP_250); - case ramp125: return WRITE_REG(REG_PARAMP, PARAMP_125); - case ramp100: return WRITE_REG(REG_PARAMP, PARAMP_100); - case ramp62: return WRITE_REG(REG_PARAMP, PARAMP_62); - case ramp50: return WRITE_REG(REG_PARAMP, PARAMP_50); - case ramp40: return WRITE_REG(REG_PARAMP, PARAMP_40); - case ramp31: return WRITE_REG(REG_PARAMP, PARAMP_31); - case ramp25: return WRITE_REG(REG_PARAMP, PARAMP_25); - case ramp20: return WRITE_REG(REG_PARAMP, PARAMP_20); - case ramp15: return WRITE_REG(REG_PARAMP, PARAMP_15); - case ramp12: return WRITE_REG(REG_PARAMP, PARAMP_12); - case ramp10: return WRITE_REG(REG_PARAMP, PARAMP_10); + case ramp3400: + return rf69_write_reg(spi, REG_PARAMP, PARAMP_3400); + case ramp2000: + return rf69_write_reg(spi, REG_PARAMP, PARAMP_2000); + case ramp1000: + return rf69_write_reg(spi, REG_PARAMP, PARAMP_1000); + case ramp500: + return rf69_write_reg(spi, REG_PARAMP, PARAMP_500); + case ramp250: + return rf69_write_reg(spi, REG_PARAMP, PARAMP_250); + case ramp125: + return rf69_write_reg(spi, REG_PARAMP, PARAMP_125); + case ramp100: + return rf69_write_reg(spi, REG_PARAMP, PARAMP_100); + case ramp62: + return rf69_write_reg(spi, REG_PARAMP, PARAMP_62); + case ramp50: + return rf69_write_reg(spi, REG_PARAMP, PARAMP_50); + case ramp40: + return rf69_write_reg(spi, REG_PARAMP, PARAMP_40); + case ramp31: + return rf69_write_reg(spi, REG_PARAMP, PARAMP_31); + case ramp25: + return rf69_write_reg(spi, REG_PARAMP, PARAMP_25); + case ramp20: + return rf69_write_reg(spi, REG_PARAMP, PARAMP_20); + case ramp15: + return rf69_write_reg(spi, REG_PARAMP, PARAMP_15); + case ramp12: + return rf69_write_reg(spi, REG_PARAMP, PARAMP_12); + case ramp10: + return rf69_write_reg(spi, REG_PARAMP, PARAMP_10); default: dev_dbg(&spi->dev, "set: illegal input param"); return -EINVAL; @@ -366,13 +388,11 @@ int rf69_set_pa_ramp(struct spi_device *spi, enum paRamp paRamp) int rf69_set_antenna_impedance(struct spi_device *spi, enum antennaImpedance antennaImpedance) { - #ifdef DEBUG - dev_dbg(&spi->dev, "set: antenna impedance"); - #endif - switch (antennaImpedance) { - case fiftyOhm: return WRITE_REG(REG_LNA, (READ_REG(REG_LNA) & ~MASK_LNA_ZIN)); - case twohundretOhm: return WRITE_REG(REG_LNA, (READ_REG(REG_LNA) | MASK_LNA_ZIN)); + case fiftyOhm: + return rf69_clear_bit(spi, REG_LNA, MASK_LNA_ZIN); + case twohundretOhm: + return rf69_set_bit(spi, REG_LNA, MASK_LNA_ZIN); default: dev_dbg(&spi->dev, "set: illegal input param"); return -EINVAL; @@ -381,81 +401,27 @@ int rf69_set_antenna_impedance(struct spi_device *spi, enum antennaImpedance ant int rf69_set_lna_gain(struct spi_device *spi, enum lnaGain lnaGain) { - #ifdef DEBUG - dev_dbg(&spi->dev, "set: lna gain"); - #endif - switch (lnaGain) { - case automatic: return WRITE_REG(REG_LNA, ((READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_AUTO)); - case max: return WRITE_REG(REG_LNA, ((READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_MAX)); - case maxMinus6: return WRITE_REG(REG_LNA, ((READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_MAX_MINUS_6)); - case maxMinus12: return WRITE_REG(REG_LNA, ((READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_MAX_MINUS_12)); - case maxMinus24: return WRITE_REG(REG_LNA, ((READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_MAX_MINUS_24)); - case maxMinus36: return WRITE_REG(REG_LNA, ((READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_MAX_MINUS_36)); - case maxMinus48: return WRITE_REG(REG_LNA, ((READ_REG(REG_LNA) & ~MASK_LNA_GAIN) & LNA_GAIN_MAX_MINUS_48)); + case automatic: + return rf69_read_mod_write(spi, REG_LNA, MASK_LNA_GAIN, LNA_GAIN_AUTO); + case max: + return rf69_read_mod_write(spi, REG_LNA, MASK_LNA_GAIN, LNA_GAIN_MAX); + case max_minus_6: + return rf69_read_mod_write(spi, REG_LNA, MASK_LNA_GAIN, LNA_GAIN_MAX_MINUS_6); + case max_minus_12: + return rf69_read_mod_write(spi, REG_LNA, MASK_LNA_GAIN, LNA_GAIN_MAX_MINUS_12); + case max_minus_24: + return rf69_read_mod_write(spi, REG_LNA, MASK_LNA_GAIN, LNA_GAIN_MAX_MINUS_24); + case max_minus_36: + return rf69_read_mod_write(spi, REG_LNA, MASK_LNA_GAIN, LNA_GAIN_MAX_MINUS_36); + case max_minus_48: + return rf69_read_mod_write(spi, REG_LNA, MASK_LNA_GAIN, LNA_GAIN_MAX_MINUS_48); default: dev_dbg(&spi->dev, "set: illegal input param"); return -EINVAL; } } -enum lnaGain rf69_get_lna_gain(struct spi_device *spi) -{ - u8 currentValue; - - #ifdef DEBUG - dev_dbg(&spi->dev, "get: lna gain"); - #endif - - currentValue = READ_REG(REG_LNA); - - switch (currentValue & MASK_LNA_CURRENT_GAIN >> 3) { // improvement: change 3 to define - case LNA_GAIN_AUTO: return automatic; - case LNA_GAIN_MAX: return max; - case LNA_GAIN_MAX_MINUS_6: return maxMinus6; - case LNA_GAIN_MAX_MINUS_12: return maxMinus12; - case LNA_GAIN_MAX_MINUS_24: return maxMinus24; - case LNA_GAIN_MAX_MINUS_36: return maxMinus36; - case LNA_GAIN_MAX_MINUS_48: return maxMinus48; - default: return undefined; - } -} - -int rf69_set_dc_cut_off_frequency_intern(struct spi_device *spi, u8 reg, enum dccPercent dccPercent) -{ - switch (dccPercent) { - case dcc16Percent: return WRITE_REG(reg, ((READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_16_PERCENT)); - case dcc8Percent: return WRITE_REG(reg, ((READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_8_PERCENT)); - case dcc4Percent: return WRITE_REG(reg, ((READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_4_PERCENT)); - case dcc2Percent: return WRITE_REG(reg, ((READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_2_PERCENT)); - case dcc1Percent: return WRITE_REG(reg, ((READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_1_PERCENT)); - case dcc0_5Percent: return WRITE_REG(reg, ((READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_0_5_PERCENT)); - case dcc0_25Percent: return WRITE_REG(reg, ((READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_0_25_PERCENT)); - case dcc0_125Percent: return WRITE_REG(reg, ((READ_REG(reg) & ~MASK_BW_DCC_FREQ) | BW_DCC_0_125_PERCENT)); - default: - dev_dbg(&spi->dev, "set: illegal input param"); - return -EINVAL; - } -} - -int rf69_set_dc_cut_off_frequency(struct spi_device *spi, enum dccPercent dccPercent) -{ - #ifdef DEBUG - dev_dbg(&spi->dev, "set: cut off freq"); - #endif - - return rf69_set_dc_cut_off_frequency_intern(spi, REG_RXBW, dccPercent); -} - -int rf69_set_dc_cut_off_frequency_during_afc(struct spi_device *spi, enum dccPercent dccPercent) -{ - #ifdef DEBUG - dev_dbg(&spi->dev, "set: cut off freq during afc"); - #endif - - return rf69_set_dc_cut_off_frequency_intern(spi, REG_AFCBW, dccPercent); -} - static int rf69_set_bandwidth_intern(struct spi_device *spi, u8 reg, enum mantisse mantisse, u8 exponent) { @@ -475,7 +441,7 @@ static int rf69_set_bandwidth_intern(struct spi_device *spi, u8 reg, } // read old value - newValue = READ_REG(reg); + newValue = rf69_read_reg(spi, reg); // "delete" mantisse and exponent = just keep the DCC setting newValue = newValue & MASK_BW_DCC_FREQ; @@ -497,79 +463,38 @@ static int rf69_set_bandwidth_intern(struct spi_device *spi, u8 reg, newValue = newValue | exponent; // write back - return WRITE_REG(reg, newValue); + return rf69_write_reg(spi, reg, newValue); } int rf69_set_bandwidth(struct spi_device *spi, enum mantisse mantisse, u8 exponent) { - #ifdef DEBUG - dev_dbg(&spi->dev, "set: band width"); - #endif - return rf69_set_bandwidth_intern(spi, REG_RXBW, mantisse, exponent); } int rf69_set_bandwidth_during_afc(struct spi_device *spi, enum mantisse mantisse, u8 exponent) { - #ifdef DEBUG - dev_dbg(&spi->dev, "set: band width during afc"); - #endif - return rf69_set_bandwidth_intern(spi, REG_AFCBW, mantisse, exponent); } -int rf69_set_ook_threshold_type(struct spi_device *spi, enum thresholdType thresholdType) -{ - #ifdef DEBUG - dev_dbg(&spi->dev, "set: threshold type"); - #endif - - switch (thresholdType) { - case fixed: return WRITE_REG(REG_OOKPEAK, ((READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESTYPE) | OOKPEAK_THRESHTYPE_FIXED)); - case peak: return WRITE_REG(REG_OOKPEAK, ((READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESTYPE) | OOKPEAK_THRESHTYPE_PEAK)); - case average: return WRITE_REG(REG_OOKPEAK, ((READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESTYPE) | OOKPEAK_THRESHTYPE_AVERAGE)); - default: - dev_dbg(&spi->dev, "set: illegal input param"); - return -EINVAL; - } -} - -int rf69_set_ook_threshold_step(struct spi_device *spi, enum thresholdStep thresholdStep) -{ - #ifdef DEBUG - dev_dbg(&spi->dev, "set: threshold step"); - #endif - - switch (thresholdStep) { - case step_0_5db: return WRITE_REG(REG_OOKPEAK, ((READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_0_5_DB)); - case step_1_0db: return WRITE_REG(REG_OOKPEAK, ((READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_1_0_DB)); - case step_1_5db: return WRITE_REG(REG_OOKPEAK, ((READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_1_5_DB)); - case step_2_0db: return WRITE_REG(REG_OOKPEAK, ((READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_2_0_DB)); - case step_3_0db: return WRITE_REG(REG_OOKPEAK, ((READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_3_0_DB)); - case step_4_0db: return WRITE_REG(REG_OOKPEAK, ((READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_4_0_DB)); - case step_5_0db: return WRITE_REG(REG_OOKPEAK, ((READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_5_0_DB)); - case step_6_0db: return WRITE_REG(REG_OOKPEAK, ((READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESSTEP) | OOKPEAK_THRESHSTEP_6_0_DB)); - default: - dev_dbg(&spi->dev, "set: illegal input param"); - return -EINVAL; - } -} - int rf69_set_ook_threshold_dec(struct spi_device *spi, enum thresholdDecrement thresholdDecrement) { - #ifdef DEBUG - dev_dbg(&spi->dev, "set: threshold decrement"); - #endif - switch (thresholdDecrement) { - case dec_every8th: return WRITE_REG(REG_OOKPEAK, ((READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_EVERY_8TH)); - case dec_every4th: return WRITE_REG(REG_OOKPEAK, ((READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_EVERY_4TH)); - case dec_every2nd: return WRITE_REG(REG_OOKPEAK, ((READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_EVERY_2ND)); - case dec_once: return WRITE_REG(REG_OOKPEAK, ((READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_ONCE)); - case dec_twice: return WRITE_REG(REG_OOKPEAK, ((READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_TWICE)); - case dec_4times: return WRITE_REG(REG_OOKPEAK, ((READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_4_TIMES)); - case dec_8times: return WRITE_REG(REG_OOKPEAK, ((READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_8_TIMES)); - case dec_16times: return WRITE_REG(REG_OOKPEAK, ((READ_REG(REG_OOKPEAK) & ~MASK_OOKPEAK_THRESDEC) | OOKPEAK_THRESHDEC_16_TIMES)); + case dec_every8th: + return rf69_read_mod_write(spi, REG_OOKPEAK, MASK_OOKPEAK_THRESDEC, OOKPEAK_THRESHDEC_EVERY_8TH); + case dec_every4th: + return rf69_read_mod_write(spi, REG_OOKPEAK, MASK_OOKPEAK_THRESDEC, OOKPEAK_THRESHDEC_EVERY_4TH); + case dec_every2nd: + return rf69_read_mod_write(spi, REG_OOKPEAK, MASK_OOKPEAK_THRESDEC, OOKPEAK_THRESHDEC_EVERY_2ND); + case dec_once: + return rf69_read_mod_write(spi, REG_OOKPEAK, MASK_OOKPEAK_THRESDEC, OOKPEAK_THRESHDEC_ONCE); + case dec_twice: + return rf69_read_mod_write(spi, REG_OOKPEAK, MASK_OOKPEAK_THRESDEC, OOKPEAK_THRESHDEC_TWICE); + case dec_4times: + return rf69_read_mod_write(spi, REG_OOKPEAK, MASK_OOKPEAK_THRESDEC, OOKPEAK_THRESHDEC_4_TIMES); + case dec_8times: + return rf69_read_mod_write(spi, REG_OOKPEAK, MASK_OOKPEAK_THRESDEC, OOKPEAK_THRESHDEC_8_TIMES); + case dec_16times: + return rf69_read_mod_write(spi, REG_OOKPEAK, MASK_OOKPEAK_THRESDEC, OOKPEAK_THRESHDEC_16_TIMES); default: dev_dbg(&spi->dev, "set: illegal input param"); return -EINVAL; @@ -583,10 +508,6 @@ int rf69_set_dio_mapping(struct spi_device *spi, u8 DIONumber, u8 value) u8 regaddr; u8 regValue; - #ifdef DEBUG - dev_dbg(&spi->dev, "set: DIO mapping"); - #endif - switch (DIONumber) { case 0: mask = MASK_DIO0; shift = SHIFT_DIO0; regaddr = REG_DIOMAPPING1; @@ -607,95 +528,66 @@ int rf69_set_dio_mapping(struct spi_device *spi, u8 DIONumber, u8 value) mask = MASK_DIO5; shift = SHIFT_DIO5; regaddr = REG_DIOMAPPING2; break; default: - dev_dbg(&spi->dev, "set: illegal input param"); + dev_dbg(&spi->dev, "set: illegal input param"); return -EINVAL; } // read reg - regValue = READ_REG(regaddr); + regValue = rf69_read_reg(spi, regaddr); // delete old value regValue = regValue & ~mask; // add new value regValue = regValue | value << shift; // write back - return WRITE_REG(regaddr, regValue); + return rf69_write_reg(spi, regaddr, regValue); } bool rf69_get_flag(struct spi_device *spi, enum flag flag) { - #ifdef DEBUG - dev_dbg(&spi->dev, "get: flag"); - #endif - - switch (flag) { - case modeSwitchCompleted: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_MODE_READY); - case readyToReceive: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_RX_READY); - case readyToSend: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_TX_READY); - case pllLocked: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_PLL_LOCK); - case rssiExceededThreshold: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_RSSI); - case timeout: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_TIMEOUT); - case automode: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_AUTOMODE); - case syncAddressMatch: return (READ_REG(REG_IRQFLAGS1) & MASK_IRQFLAGS1_SYNC_ADDRESS_MATCH); - case fifoFull: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_FIFO_FULL); -/* case fifoNotEmpty: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_FIFO_NOT_EMPTY); */ - case fifoEmpty: return !(READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_FIFO_NOT_EMPTY); - case fifoLevelBelowThreshold: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_FIFO_LEVEL); - case fifoOverrun: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_FIFO_OVERRUN); - case packetSent: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_PACKET_SENT); - case payloadReady: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_PAYLOAD_READY); - case crcOk: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_CRC_OK); - case batteryLow: return (READ_REG(REG_IRQFLAGS2) & MASK_IRQFLAGS2_LOW_BAT); - default: return false; - } -} - -int rf69_reset_flag(struct spi_device *spi, enum flag flag) -{ - #ifdef DEBUG - dev_dbg(&spi->dev, "reset: flag"); - #endif - switch (flag) { - case rssiExceededThreshold: return WRITE_REG(REG_IRQFLAGS1, MASK_IRQFLAGS1_RSSI); - case syncAddressMatch: return WRITE_REG(REG_IRQFLAGS1, MASK_IRQFLAGS1_SYNC_ADDRESS_MATCH); - case fifoOverrun: return WRITE_REG(REG_IRQFLAGS2, MASK_IRQFLAGS2_FIFO_OVERRUN); - default: - dev_dbg(&spi->dev, "set: illegal input param"); - return -EINVAL; + case modeSwitchCompleted: + return (rf69_read_reg(spi, REG_IRQFLAGS1) & MASK_IRQFLAGS1_MODE_READY); + case readyToReceive: + return (rf69_read_reg(spi, REG_IRQFLAGS1) & MASK_IRQFLAGS1_RX_READY); + case readyToSend: + return (rf69_read_reg(spi, REG_IRQFLAGS1) & MASK_IRQFLAGS1_TX_READY); + case pllLocked: + return (rf69_read_reg(spi, REG_IRQFLAGS1) & MASK_IRQFLAGS1_PLL_LOCK); + case rssiExceededThreshold: + return (rf69_read_reg(spi, REG_IRQFLAGS1) & MASK_IRQFLAGS1_RSSI); + case timeout: + return (rf69_read_reg(spi, REG_IRQFLAGS1) & MASK_IRQFLAGS1_TIMEOUT); + case automode: + return (rf69_read_reg(spi, REG_IRQFLAGS1) & MASK_IRQFLAGS1_AUTOMODE); + case syncAddressMatch: + return (rf69_read_reg(spi, REG_IRQFLAGS1) & MASK_IRQFLAGS1_SYNC_ADDRESS_MATCH); + case fifo_full: + return (rf69_read_reg(spi, REG_IRQFLAGS2) & MASK_IRQFLAGS2_FIFO_FULL); +/* case fifo_not_empty: + * return (rf69_read_reg(spi, REG_IRQFLAGS2) & MASK_IRQFLAGS2_FIFO_NOT_EMPTY); */ + case fifo_empty: + return !(rf69_read_reg(spi, REG_IRQFLAGS2) & MASK_IRQFLAGS2_FIFO_NOT_EMPTY); + case fifo_level_below_threshold: + return (rf69_read_reg(spi, REG_IRQFLAGS2) & MASK_IRQFLAGS2_FIFO_LEVEL); + case fifo_overrun: + return (rf69_read_reg(spi, REG_IRQFLAGS2) & MASK_IRQFLAGS2_FIFO_OVERRUN); + case packetSent: + return (rf69_read_reg(spi, REG_IRQFLAGS2) & MASK_IRQFLAGS2_PACKET_SENT); + case payload_ready: + return (rf69_read_reg(spi, REG_IRQFLAGS2) & MASK_IRQFLAGS2_PAYLOAD_READY); + case crcOk: + return (rf69_read_reg(spi, REG_IRQFLAGS2) & MASK_IRQFLAGS2_CRC_OK); + case batteryLow: + return (rf69_read_reg(spi, REG_IRQFLAGS2) & MASK_IRQFLAGS2_LOW_BAT); + default: return false; } } int rf69_set_rssi_threshold(struct spi_device *spi, u8 threshold) { - #ifdef DEBUG - dev_dbg(&spi->dev, "set: rssi threshold"); - #endif - /* no value check needed - u8 exactly matches register size */ - return WRITE_REG(REG_RSSITHRESH, threshold); -} - -int rf69_set_rx_start_timeout(struct spi_device *spi, u8 timeout) -{ - #ifdef DEBUG - dev_dbg(&spi->dev, "set: start timeout"); - #endif - - /* no value check needed - u8 exactly matches register size */ - - return WRITE_REG(REG_RXTIMEOUT1, timeout); -} - -int rf69_set_rssi_timeout(struct spi_device *spi, u8 timeout) -{ - #ifdef DEBUG - dev_dbg(&spi->dev, "set: rssi timeout"); - #endif - - /* no value check needed - u8 exactly matches register size */ - - return WRITE_REG(REG_RXTIMEOUT2, timeout); + return rf69_write_reg(spi, REG_RSSITHRESH, threshold); } int rf69_set_preamble_length(struct spi_device *spi, u16 preambleLength) @@ -703,47 +595,38 @@ int rf69_set_preamble_length(struct spi_device *spi, u16 preambleLength) int retval; u8 msb, lsb; - #ifdef DEBUG - dev_dbg(&spi->dev, "set: preamble length"); - #endif - /* no value check needed - u16 exactly matches register size */ /* calculate reg settings */ - msb = (preambleLength&0xff00) >> 8; - lsb = (preambleLength&0xff); + msb = (preambleLength & 0xff00) >> 8; + lsb = (preambleLength & 0xff); /* transmit to chip */ - retval = WRITE_REG(REG_PREAMBLE_MSB, msb); + retval = rf69_write_reg(spi, REG_PREAMBLE_MSB, msb); if (retval) return retval; - return WRITE_REG(REG_PREAMBLE_LSB, lsb); + retval = rf69_write_reg(spi, REG_PREAMBLE_LSB, lsb); + + return retval; } -int rf69_set_sync_enable(struct spi_device *spi, enum optionOnOff optionOnOff) +int rf69_enable_sync(struct spi_device *spi) { - #ifdef DEBUG - dev_dbg(&spi->dev, "set: sync enable"); - #endif - - switch (optionOnOff) { - case optionOn: return WRITE_REG(REG_SYNC_CONFIG, (READ_REG(REG_SYNC_CONFIG) | MASK_SYNC_CONFIG_SYNC_ON)); - case optionOff: return WRITE_REG(REG_SYNC_CONFIG, (READ_REG(REG_SYNC_CONFIG) & ~MASK_SYNC_CONFIG_SYNC_ON)); - default: - dev_dbg(&spi->dev, "set: illegal input param"); - return -EINVAL; - } + return rf69_set_bit(spi, REG_SYNC_CONFIG, MASK_SYNC_CONFIG_SYNC_ON); } -int rf69_set_fifo_fill_condition(struct spi_device *spi, enum fifoFillCondition fifoFillCondition) +int rf69_disable_sync(struct spi_device *spi) { - #ifdef DEBUG - dev_dbg(&spi->dev, "set: fifo fill condition"); - #endif + return rf69_clear_bit(spi, REG_SYNC_CONFIG, MASK_SYNC_CONFIG_SYNC_ON); +} - switch (fifoFillCondition) { - case always: return WRITE_REG(REG_SYNC_CONFIG, (READ_REG(REG_SYNC_CONFIG) | MASK_SYNC_CONFIG_FIFO_FILL_CONDITION)); - case afterSyncInterrupt: return WRITE_REG(REG_SYNC_CONFIG, (READ_REG(REG_SYNC_CONFIG) & ~MASK_SYNC_CONFIG_FIFO_FILL_CONDITION)); +int rf69_set_fifo_fill_condition(struct spi_device *spi, enum fifo_fill_condition fifo_fill_condition) +{ + switch (fifo_fill_condition) { + case always: + return rf69_set_bit(spi, REG_SYNC_CONFIG, MASK_SYNC_CONFIG_FIFO_FILL_CONDITION); + case afterSyncInterrupt: + return rf69_clear_bit(spi, REG_SYNC_CONFIG, MASK_SYNC_CONFIG_FIFO_FILL_CONDITION); default: dev_dbg(&spi->dev, "set: illegal input param"); return -EINVAL; @@ -752,10 +635,6 @@ int rf69_set_fifo_fill_condition(struct spi_device *spi, enum fifoFillCondition int rf69_set_sync_size(struct spi_device *spi, u8 syncSize) { - #ifdef DEBUG - dev_dbg(&spi->dev, "set: sync size"); - #endif - // check input value if (syncSize > 0x07) { dev_dbg(&spi->dev, "set: illegal input param"); @@ -763,136 +642,85 @@ int rf69_set_sync_size(struct spi_device *spi, u8 syncSize) } // write value - return WRITE_REG(REG_SYNC_CONFIG, (READ_REG(REG_SYNC_CONFIG) & ~MASK_SYNC_CONFIG_SYNC_SIZE) | (syncSize << 3)); -} - -int rf69_set_sync_tolerance(struct spi_device *spi, u8 syncTolerance) -{ - #ifdef DEBUG - dev_dbg(&spi->dev, "set: sync tolerance"); - #endif - - // check input value - if (syncTolerance > 0x07) { - dev_dbg(&spi->dev, "set: illegal input param"); - return -EINVAL; - } - - // write value - return WRITE_REG(REG_SYNC_CONFIG, (READ_REG(REG_SYNC_CONFIG) & ~MASK_SYNC_CONFIG_SYNC_SIZE) | syncTolerance); + return rf69_read_mod_write(spi, REG_SYNC_CONFIG, MASK_SYNC_CONFIG_SYNC_SIZE, (syncSize << 3)); } int rf69_set_sync_values(struct spi_device *spi, u8 syncValues[8]) { int retval = 0; - #ifdef DEBUG - dev_dbg(&spi->dev, "set: sync values"); - #endif - - retval += WRITE_REG(REG_SYNCVALUE1, syncValues[0]); - retval += WRITE_REG(REG_SYNCVALUE2, syncValues[1]); - retval += WRITE_REG(REG_SYNCVALUE3, syncValues[2]); - retval += WRITE_REG(REG_SYNCVALUE4, syncValues[3]); - retval += WRITE_REG(REG_SYNCVALUE5, syncValues[4]); - retval += WRITE_REG(REG_SYNCVALUE6, syncValues[5]); - retval += WRITE_REG(REG_SYNCVALUE7, syncValues[6]); - retval += WRITE_REG(REG_SYNCVALUE8, syncValues[7]); + retval += rf69_write_reg(spi, REG_SYNCVALUE1, syncValues[0]); + retval += rf69_write_reg(spi, REG_SYNCVALUE2, syncValues[1]); + retval += rf69_write_reg(spi, REG_SYNCVALUE3, syncValues[2]); + retval += rf69_write_reg(spi, REG_SYNCVALUE4, syncValues[3]); + retval += rf69_write_reg(spi, REG_SYNCVALUE5, syncValues[4]); + retval += rf69_write_reg(spi, REG_SYNCVALUE6, syncValues[5]); + retval += rf69_write_reg(spi, REG_SYNCVALUE7, syncValues[6]); + retval += rf69_write_reg(spi, REG_SYNCVALUE8, syncValues[7]); return retval; } int rf69_set_packet_format(struct spi_device *spi, enum packetFormat packetFormat) { - #ifdef DEBUG - dev_dbg(&spi->dev, "set: packet format"); - #endif - switch (packetFormat) { - case packetLengthVar: return WRITE_REG(REG_PACKETCONFIG1, (READ_REG(REG_PACKETCONFIG1) | MASK_PACKETCONFIG1_PAKET_FORMAT_VARIABLE)); - case packetLengthFix: return WRITE_REG(REG_PACKETCONFIG1, (READ_REG(REG_PACKETCONFIG1) & ~MASK_PACKETCONFIG1_PAKET_FORMAT_VARIABLE)); + case packetLengthVar: + return rf69_set_bit(spi, REG_PACKETCONFIG1, MASK_PACKETCONFIG1_PAKET_FORMAT_VARIABLE); + case packetLengthFix: + return rf69_clear_bit(spi, REG_PACKETCONFIG1, MASK_PACKETCONFIG1_PAKET_FORMAT_VARIABLE); default: dev_dbg(&spi->dev, "set: illegal input param"); return -EINVAL; } } -int rf69_set_crc_enable(struct spi_device *spi, enum optionOnOff optionOnOff) +int rf69_enable_crc(struct spi_device *spi) { - #ifdef DEBUG - dev_dbg(&spi->dev, "set: crc enable"); - #endif + return rf69_set_bit(spi, REG_PACKETCONFIG1, MASK_PACKETCONFIG1_CRC_ON); +} - switch (optionOnOff) { - case optionOn: return WRITE_REG(REG_PACKETCONFIG1, (READ_REG(REG_PACKETCONFIG1) | MASK_PACKETCONFIG1_CRC_ON)); - case optionOff: return WRITE_REG(REG_PACKETCONFIG1, (READ_REG(REG_PACKETCONFIG1) & ~MASK_PACKETCONFIG1_CRC_ON)); - default: - dev_dbg(&spi->dev, "set: illegal input param"); - return -EINVAL; - } +int rf69_disable_crc(struct spi_device *spi) +{ + return rf69_clear_bit(spi, REG_PACKETCONFIG1, MASK_PACKETCONFIG1_CRC_ON); } int rf69_set_adressFiltering(struct spi_device *spi, enum addressFiltering addressFiltering) { - #ifdef DEBUG - dev_dbg(&spi->dev, "set: address filtering"); - #endif - switch (addressFiltering) { - case filteringOff: return WRITE_REG(REG_PACKETCONFIG1, ((READ_REG(REG_PACKETCONFIG1) & ~MASK_PACKETCONFIG1_ADDRESSFILTERING) | PACKETCONFIG1_ADDRESSFILTERING_OFF)); - case nodeAddress: return WRITE_REG(REG_PACKETCONFIG1, ((READ_REG(REG_PACKETCONFIG1) & ~MASK_PACKETCONFIG1_ADDRESSFILTERING) | PACKETCONFIG1_ADDRESSFILTERING_NODE)); - case nodeOrBroadcastAddress: return WRITE_REG(REG_PACKETCONFIG1, ((READ_REG(REG_PACKETCONFIG1) & ~MASK_PACKETCONFIG1_ADDRESSFILTERING) | PACKETCONFIG1_ADDRESSFILTERING_NODEBROADCAST)); + case filteringOff: + return rf69_read_mod_write(spi, REG_PACKETCONFIG1, MASK_PACKETCONFIG1_ADDRESSFILTERING, PACKETCONFIG1_ADDRESSFILTERING_OFF); + case nodeAddress: + return rf69_read_mod_write(spi, REG_PACKETCONFIG1, MASK_PACKETCONFIG1_ADDRESSFILTERING, PACKETCONFIG1_ADDRESSFILTERING_NODE); + case nodeOrBroadcastAddress: + return rf69_read_mod_write(spi, REG_PACKETCONFIG1, MASK_PACKETCONFIG1_ADDRESSFILTERING, PACKETCONFIG1_ADDRESSFILTERING_NODEBROADCAST); default: dev_dbg(&spi->dev, "set: illegal input param"); return -EINVAL; } } -int rf69_set_payload_length(struct spi_device *spi, u8 payloadLength) +int rf69_set_payload_length(struct spi_device *spi, u8 payload_length) { - #ifdef DEBUG - dev_dbg(&spi->dev, "set: payload length"); - #endif - - return WRITE_REG(REG_PAYLOAD_LENGTH, payloadLength); -} - -u8 rf69_get_payload_length(struct spi_device *spi) -{ - #ifdef DEBUG - dev_dbg(&spi->dev, "get: payload length"); - #endif - - return (u8) READ_REG(REG_PAYLOAD_LENGTH); + return rf69_write_reg(spi, REG_PAYLOAD_LENGTH, payload_length); } int rf69_set_node_address(struct spi_device *spi, u8 nodeAddress) { - #ifdef DEBUG - dev_dbg(&spi->dev, "set: node address"); - #endif - - return WRITE_REG(REG_NODEADRS, nodeAddress); + return rf69_write_reg(spi, REG_NODEADRS, nodeAddress); } int rf69_set_broadcast_address(struct spi_device *spi, u8 broadcastAddress) { - #ifdef DEBUG - dev_dbg(&spi->dev, "set: broadcast address"); - #endif - - return WRITE_REG(REG_BROADCASTADRS, broadcastAddress); + return rf69_write_reg(spi, REG_BROADCASTADRS, broadcastAddress); } int rf69_set_tx_start_condition(struct spi_device *spi, enum txStartCondition txStartCondition) { - #ifdef DEBUG - dev_dbg(&spi->dev, "set: start condition"); - #endif - switch (txStartCondition) { - case fifoLevel: return WRITE_REG(REG_FIFO_THRESH, (READ_REG(REG_FIFO_THRESH) & ~MASK_FIFO_THRESH_TXSTART)); - case fifoNotEmpty: return WRITE_REG(REG_FIFO_THRESH, (READ_REG(REG_FIFO_THRESH) | MASK_FIFO_THRESH_TXSTART)); + case fifo_level: + return rf69_clear_bit(spi, REG_FIFO_THRESH, MASK_FIFO_THRESH_TXSTART); + case fifo_not_empty: + return rf69_set_bit(spi, REG_FIFO_THRESH, MASK_FIFO_THRESH_TXSTART); default: dev_dbg(&spi->dev, "set: illegal input param"); return -EINVAL; @@ -903,35 +731,32 @@ int rf69_set_fifo_threshold(struct spi_device *spi, u8 threshold) { int retval; - #ifdef DEBUG - dev_dbg(&spi->dev, "set: fifo threshold"); - #endif - - // check input value + /* check input value */ if (threshold & 0x80) { dev_dbg(&spi->dev, "set: illegal input param"); return -EINVAL; } - // write value - retval = WRITE_REG(REG_FIFO_THRESH, (READ_REG(REG_FIFO_THRESH) & ~MASK_FIFO_THRESH_VALUE) | threshold); + /* write value */ + retval = rf69_read_mod_write(spi, REG_FIFO_THRESH, MASK_FIFO_THRESH_VALUE, threshold); if (retval) return retval; - // access the fifo to activate new threshold - return rf69_read_fifo(spi, (u8 *)&retval, 1); // retval used as buffer + /* access the fifo to activate new threshold + * retval (mis-) used as buffer here + */ + return rf69_read_fifo(spi, (u8 *)&retval, 1); } int rf69_set_dagc(struct spi_device *spi, enum dagc dagc) { - #ifdef DEBUG - dev_dbg(&spi->dev, "set: dagc"); - #endif - switch (dagc) { - case normalMode: return WRITE_REG(REG_TESTDAGC, DAGC_NORMAL); - case improve: return WRITE_REG(REG_TESTDAGC, DAGC_IMPROVED_LOWBETA0); - case improve4LowModulationIndex: return WRITE_REG(REG_TESTDAGC, DAGC_IMPROVED_LOWBETA1); + case normalMode: + return rf69_write_reg(spi, REG_TESTDAGC, DAGC_NORMAL); + case improve: + return rf69_write_reg(spi, REG_TESTDAGC, DAGC_IMPROVED_LOWBETA0); + case improve4LowModulationIndex: + return rf69_write_reg(spi, REG_TESTDAGC, DAGC_IMPROVED_LOWBETA1); default: dev_dbg(&spi->dev, "set: illegal input param"); return -EINVAL; @@ -940,19 +765,17 @@ int rf69_set_dagc(struct spi_device *spi, enum dagc dagc) /*-------------------------------------------------------------------------*/ -int rf69_read_fifo (struct spi_device *spi, u8 *buffer, unsigned int size) +int rf69_read_fifo(struct spi_device *spi, u8 *buffer, unsigned int size) { - #ifdef DEBUG_FIFO_ACCESS - int i; - #endif +#ifdef DEBUG_FIFO_ACCESS + int i; +#endif struct spi_transfer transfer; u8 local_buffer[FIFO_SIZE + 1]; int retval; if (size > FIFO_SIZE) { - #ifdef DEBUG - dev_dbg(&spi->dev, "read fifo: passed in buffer bigger then internal buffer \n"); - #endif + dev_dbg(&spi->dev, "read fifo: passed in buffer bigger then internal buffer\n"); return -EMSGSIZE; } @@ -961,97 +784,41 @@ int rf69_read_fifo (struct spi_device *spi, u8 *buffer, unsigned int size) memset(&transfer, 0, sizeof(transfer)); transfer.tx_buf = local_buffer; transfer.rx_buf = local_buffer; - transfer.len = size+1; + transfer.len = size + 1; retval = spi_sync_transfer(spi, &transfer, 1); - #ifdef DEBUG_FIFO_ACCESS - for (i = 0; i < size; i++) - dev_dbg(&spi->dev, "%d - 0x%x\n", i, local_buffer[i+1]); - #endif +#ifdef DEBUG_FIFO_ACCESS + for (i = 0; i < size; i++) + dev_dbg(&spi->dev, "%d - 0x%x\n", i, local_buffer[i + 1]); +#endif - memcpy(buffer, &local_buffer[1], size); // TODO: ohne memcopy wäre schöner + memcpy(buffer, &local_buffer[1], size); return retval; } int rf69_write_fifo(struct spi_device *spi, u8 *buffer, unsigned int size) { - #ifdef DEBUG_FIFO_ACCESS - int i; - #endif +#ifdef DEBUG_FIFO_ACCESS + int i; +#endif char spi_address = REG_FIFO | WRITE_BIT; u8 local_buffer[FIFO_SIZE + 1]; if (size > FIFO_SIZE) { - #ifdef DEBUG - dev_dbg(&spi->dev, "read fifo: passed in buffer bigger then internal buffer \n"); - #endif + dev_dbg(&spi->dev, "read fifo: passed in buffer bigger then internal buffer\n"); return -EMSGSIZE; } local_buffer[0] = spi_address; - memcpy(&local_buffer[1], buffer, size); // TODO: ohne memcopy wäre schöner + memcpy(&local_buffer[1], buffer, size); - #ifdef DEBUG_FIFO_ACCESS - for (i = 0; i < size; i++) - dev_dbg(&spi->dev, "0x%x\n", buffer[i]); - #endif +#ifdef DEBUG_FIFO_ACCESS + for (i = 0; i < size; i++) + dev_dbg(&spi->dev, "0x%x\n", buffer[i]); +#endif - return spi_write (spi, local_buffer, size + 1); + return spi_write(spi, local_buffer, size + 1); } -/*-------------------------------------------------------------------------*/ - -u8 rf69_read_reg(struct spi_device *spi, u8 addr) -{ - int retval; - - retval = spi_w8r8(spi, addr); - - #ifdef DEBUG_VALUES - if (retval < 0) - /* should never happen, since we already checked, - * that module is connected. Therefore no error - * handling, just an optional error message... - */ - dev_dbg(&spi->dev, "read 0x%x FAILED\n", - addr); - else - dev_dbg(&spi->dev, "read 0x%x from reg 0x%x\n", - retval, - addr); - #endif - - return retval; -} - -int rf69_write_reg(struct spi_device *spi, u8 addr, u8 value) -{ - int retval; - char buffer[2]; - - buffer[0] = addr | WRITE_BIT; - buffer[1] = value; - - retval = spi_write(spi, &buffer, 2); - - #ifdef DEBUG_VALUES - if (retval < 0) - /* should never happen, since we already checked, - * that module is connected. Therefore no error - * handling, just an optional error message... - */ - dev_dbg(&spi->dev, "write 0x%x to 0x%x FAILED\n", - value, - addr); - else - dev_dbg(&spi->dev, "wrote 0x%x to reg 0x%x\n", - value, - addr); - #endif - - return retval; -} - - diff --git a/drivers/staging/pi433/rf69.h b/drivers/staging/pi433/rf69.h index 5c0c95628f2f..09d221b8b6df 100644 --- a/drivers/staging/pi433/rf69.h +++ b/drivers/staging/pi433/rf69.h @@ -26,57 +26,42 @@ #define FIFO_THRESHOLD 15 /* in byte */ int rf69_set_mode(struct spi_device *spi, enum mode mode); -int rf69_set_data_mode(struct spi_device *spi, enum dataMode dataMode); +int rf69_set_data_mode(struct spi_device *spi, u8 data_mode); int rf69_set_modulation(struct spi_device *spi, enum modulation modulation); -enum modulation rf69_get_modulation(struct spi_device *spi); -int rf69_set_modulation_shaping(struct spi_device *spi, enum modShaping modShaping); +int rf69_set_modulation_shaping(struct spi_device *spi, enum mod_shaping mod_shaping); int rf69_set_bit_rate(struct spi_device *spi, u16 bitRate); int rf69_set_deviation(struct spi_device *spi, u32 deviation); int rf69_set_frequency(struct spi_device *spi, u32 frequency); -int rf69_set_amplifier_0(struct spi_device *spi, enum optionOnOff optionOnOff); -int rf69_set_amplifier_1(struct spi_device *spi, enum optionOnOff optionOnOff); -int rf69_set_amplifier_2(struct spi_device *spi, enum optionOnOff optionOnOff); +int rf69_enable_amplifier(struct spi_device *spi, u8 amplifier_mask); +int rf69_disable_amplifier(struct spi_device *spi, u8 amplifier_mask); int rf69_set_output_power_level(struct spi_device *spi, u8 powerLevel); int rf69_set_pa_ramp(struct spi_device *spi, enum paRamp paRamp); int rf69_set_antenna_impedance(struct spi_device *spi, enum antennaImpedance antennaImpedance); int rf69_set_lna_gain(struct spi_device *spi, enum lnaGain lnaGain); -enum lnaGain rf69_get_lna_gain(struct spi_device *spi); -int rf69_set_dc_cut_off_frequency_intern(struct spi_device *spi, u8 reg, enum dccPercent dccPercent); -int rf69_set_dc_cut_off_frequency(struct spi_device *spi, enum dccPercent dccPercent); -int rf69_set_dc_cut_off_frequency_during_afc(struct spi_device *spi, enum dccPercent dccPercent); int rf69_set_bandwidth(struct spi_device *spi, enum mantisse mantisse, u8 exponent); int rf69_set_bandwidth_during_afc(struct spi_device *spi, enum mantisse mantisse, u8 exponent); -int rf69_set_ook_threshold_type(struct spi_device *spi, enum thresholdType thresholdType); -int rf69_set_ook_threshold_step(struct spi_device *spi, enum thresholdStep thresholdStep); int rf69_set_ook_threshold_dec(struct spi_device *spi, enum thresholdDecrement thresholdDecrement); int rf69_set_dio_mapping(struct spi_device *spi, u8 DIONumber, u8 value); bool rf69_get_flag(struct spi_device *spi, enum flag flag); -int rf69_reset_flag(struct spi_device *spi, enum flag flag); int rf69_set_rssi_threshold(struct spi_device *spi, u8 threshold); -int rf69_set_rx_start_timeout(struct spi_device *spi, u8 timeout); -int rf69_set_rssi_timeout(struct spi_device *spi, u8 timeout); int rf69_set_preamble_length(struct spi_device *spi, u16 preambleLength); -int rf69_set_sync_enable(struct spi_device *spi, enum optionOnOff optionOnOff); -int rf69_set_fifo_fill_condition(struct spi_device *spi, enum fifoFillCondition fifoFillCondition); +int rf69_enable_sync(struct spi_device *spi); +int rf69_disable_sync(struct spi_device *spi); +int rf69_set_fifo_fill_condition(struct spi_device *spi, enum fifo_fill_condition fifo_fill_condition); int rf69_set_sync_size(struct spi_device *spi, u8 sync_size); -int rf69_set_sync_tolerance(struct spi_device *spi, u8 syncTolerance); int rf69_set_sync_values(struct spi_device *spi, u8 syncValues[8]); int rf69_set_packet_format(struct spi_device *spi, enum packetFormat packetFormat); -int rf69_set_crc_enable(struct spi_device *spi, enum optionOnOff optionOnOff); +int rf69_enable_crc(struct spi_device *spi); +int rf69_disable_crc(struct spi_device *spi); int rf69_set_adressFiltering(struct spi_device *spi, enum addressFiltering addressFiltering); -int rf69_set_payload_length(struct spi_device *spi, u8 payloadLength); -u8 rf69_get_payload_length(struct spi_device *spi); +int rf69_set_payload_length(struct spi_device *spi, u8 payload_length); int rf69_set_node_address(struct spi_device *spi, u8 nodeAddress); int rf69_set_broadcast_address(struct spi_device *spi, u8 broadcastAddress); int rf69_set_tx_start_condition(struct spi_device *spi, enum txStartCondition txStartCondition); int rf69_set_fifo_threshold(struct spi_device *spi, u8 threshold); int rf69_set_dagc(struct spi_device *spi, enum dagc dagc); -int rf69_read_fifo (struct spi_device *spi, u8 *buffer, unsigned int size); +int rf69_read_fifo(struct spi_device *spi, u8 *buffer, unsigned int size); int rf69_write_fifo(struct spi_device *spi, u8 *buffer, unsigned int size); -u8 rf69_read_reg (struct spi_device *spi, u8 addr); -int rf69_write_reg(struct spi_device *spi, u8 addr, u8 value); - - #endif diff --git a/drivers/staging/pi433/rf69_enum.h b/drivers/staging/pi433/rf69_enum.h index fbfb59bd3f3d..03440cfa957c 100644 --- a/drivers/staging/pi433/rf69_enum.h +++ b/drivers/staging/pi433/rf69_enum.h @@ -18,184 +18,126 @@ #ifndef RF69_ENUM_H #define RF69_ENUM_H -enum optionOnOff -{ - optionOff, - optionOn +enum mode { + mode_sleep, + standby, + synthesizer, + transmit, + receive +}; + +enum modulation { + OOK, + FSK, + UNDEF +}; + +enum mod_shaping { + SHAPING_OFF, + SHAPING_1_0, + SHAPING_0_5, + SHAPING_0_3, + SHAPING_BR, + SHAPING_2BR +}; + +enum paRamp { + ramp3400, + ramp2000, + ramp1000, + ramp500, + ramp250, + ramp125, + ramp100, + ramp62, + ramp50, + ramp40, + ramp31, + ramp25, + ramp20, + ramp15, + ramp12, + ramp10 +}; + +enum antennaImpedance { + fiftyOhm, + twohundretOhm +}; + +enum lnaGain { + automatic, + max, + max_minus_6, + max_minus_12, + max_minus_24, + max_minus_36, + max_minus_48, + undefined +}; + +enum mantisse { + mantisse16, + mantisse20, + mantisse24 +}; + +enum thresholdDecrement { + dec_every8th, + dec_every4th, + dec_every2nd, + dec_once, + dec_twice, + dec_4times, + dec_8times, + dec_16times +}; + +enum flag { + modeSwitchCompleted, + readyToReceive, + readyToSend, + pllLocked, + rssiExceededThreshold, + timeout, + automode, + syncAddressMatch, + fifo_full, +// fifo_not_empty, collision with next enum; replaced by following enum... + fifo_empty, + fifo_level_below_threshold, + fifo_overrun, + packetSent, + payload_ready, + crcOk, + batteryLow +}; + +enum fifo_fill_condition { + afterSyncInterrupt, + always +}; + +enum packetFormat { + packetLengthFix, + packetLengthVar +}; + +enum txStartCondition { + fifo_level, + fifo_not_empty +}; + +enum addressFiltering { + filteringOff, + nodeAddress, + nodeOrBroadcastAddress +}; + +enum dagc { + normalMode, + improve, + improve4LowModulationIndex }; -enum mode -{ - mode_sleep, - standby, - synthesizer, - transmit, - receive -}; - -enum dataMode -{ - packet, - continuous, - continuousNoSync -}; - -enum modulation -{ - OOK, - FSK -}; - -enum modShaping -{ - shapingOff, - shaping1_0, - shaping0_5, - shaping0_3, - shapingBR, - shaping2BR -}; - -enum paRamp -{ - ramp3400, - ramp2000, - ramp1000, - ramp500, - ramp250, - ramp125, - ramp100, - ramp62, - ramp50, - ramp40, - ramp31, - ramp25, - ramp20, - ramp15, - ramp12, - ramp10 -}; - -enum antennaImpedance -{ - fiftyOhm, - twohundretOhm -}; - -enum lnaGain -{ - automatic, - max, - maxMinus6, - maxMinus12, - maxMinus24, - maxMinus36, - maxMinus48, - undefined -}; - -enum dccPercent -{ - dcc16Percent, - dcc8Percent, - dcc4Percent, - dcc2Percent, - dcc1Percent, - dcc0_5Percent, - dcc0_25Percent, - dcc0_125Percent -}; - -enum mantisse -{ - mantisse16, - mantisse20, - mantisse24 -}; - -enum thresholdType -{ - fixed, - peak, - average -}; - -enum thresholdStep -{ - step_0_5db, - step_1_0db, - step_1_5db, - step_2_0db, - step_3_0db, - step_4_0db, - step_5_0db, - step_6_0db -}; - -enum thresholdDecrement -{ - dec_every8th, - dec_every4th, - dec_every2nd, - dec_once, - dec_twice, - dec_4times, - dec_8times, - dec_16times -}; - -enum flag -{ - modeSwitchCompleted, - readyToReceive, - readyToSend, - pllLocked, - rssiExceededThreshold, - timeout, - automode, - syncAddressMatch, - fifoFull, -// fifoNotEmpty, collision with next enum; replaced by following enum... - fifoEmpty, - fifoLevelBelowThreshold, - fifoOverrun, - packetSent, - payloadReady, - crcOk, - batteryLow -}; - -enum fifoFillCondition -{ - afterSyncInterrupt, - always -}; - -enum packetFormat -{ - packetLengthFix, - packetLengthVar -}; - -enum txStartCondition -{ - fifoLevel, - fifoNotEmpty -}; - -enum addressFiltering -{ - filteringOff, - nodeAddress, - nodeOrBroadcastAddress -}; - -enum dagc -{ - normalMode, - improve, - improve4LowModulationIndex -}; - - #endif diff --git a/drivers/staging/pi433/rf69_registers.h b/drivers/staging/pi433/rf69_registers.h index 6335d42142fe..33fd91518bb0 100644 --- a/drivers/staging/pi433/rf69_registers.h +++ b/drivers/staging/pi433/rf69_registers.h @@ -188,8 +188,6 @@ #define MASK_PALEVEL_PA2 0x20 #define MASK_PALEVEL_OUTPUT_POWER 0x1F - - // RegPaRamp #define PARAMP_3400 0x00 #define PARAMP_2000 0x01 @@ -246,7 +244,6 @@ #define LNA_GAIN_MAX_MINUS_36 0x05 #define LNA_GAIN_MAX_MINUS_48 0x06 - /* RegRxBw (0x19) and RegAfcBw (0x1A) */ #define MASK_BW_DCC_FREQ 0xE0 #define MASK_BW_MANTISSE 0x18 @@ -265,7 +262,6 @@ #define BW_MANT_20 0x08 #define BW_MANT_24 0x10 /* default */ - /* RegOokPeak (0x1B) */ #define MASK_OOKPEAK_THRESTYPE 0xc0 #define MASK_OOKPEAK_THRESSTEP 0x38 @@ -346,28 +342,28 @@ #define DIO5 5 /* DIO Mapping values (packet mode) */ -#define DIO_ModeReady_DIO4 0x00 -#define DIO_ModeReady_DIO5 0x03 -#define DIO_ClkOut 0x00 -#define DIO_Data 0x01 -#define DIO_TimeOut_DIO1 0x03 -#define DIO_TimeOut_DIO4 0x00 -#define DIO_Rssi_DIO0 0x03 -#define DIO_Rssi_DIO3_4 0x01 -#define DIO_RxReady 0x02 -#define DIO_PLLLock 0x03 -#define DIO_TxReady 0x01 -#define DIO_FifoFull_DIO1 0x01 -#define DIO_FifoFull_DIO3 0x00 -#define DIO_SyncAddress 0x02 -#define DIO_FifoNotEmpty_DIO1 0x02 -#define DIO_FifoNotEmpty_FIO2 0x00 -#define DIO_Automode 0x04 -#define DIO_FifoLevel 0x00 -#define DIO_CrcOk 0x00 -#define DIO_PayloadReady 0x01 -#define DIO_PacketSent 0x00 -#define DIO_Dclk 0x00 +#define DIO_MODE_READY_DIO4 0x00 +#define DIO_MODE_READY_DIO5 0x03 +#define DIO_CLK_OUT 0x00 +#define DIO_DATA 0x01 +#define DIO_TIMEOUT_DIO1 0x03 +#define DIO_TIMEOUT_DIO4 0x00 +#define DIO_RSSI_DIO0 0x03 +#define DIO_RSSI_DIO3_4 0x01 +#define DIO_RX_READY 0x02 +#define DIO_PLL_LOCK 0x03 +#define DIO_TX_READY 0x01 +#define DIO_FIFO_FULL_DIO1 0x01 +#define DIO_FIFO_FULL_DIO3 0x00 +#define DIO_SYNC_ADDRESS 0x02 +#define DIO_FIFO_NOT_EMPTY_DIO1 0x02 +#define DIO_FIFO_NOT_EMPTY_FIO2 0x00 +#define DIO_AUTOMODE 0x04 +#define DIO_FIFO_LEVEL 0x00 +#define DIO_CRC_OK 0x00 +#define DIO_PAYLOAD_READY 0x01 +#define DIO_PACKET_SENT 0x00 +#define DIO_DCLK 0x00 /* RegDioMapping2 CLK_OUT part */ #define MASK_DIOMAPPING2_CLK_OUT 0x07 diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c index d73e9bdc80cc..bcb6919bb7d5 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c @@ -5395,14 +5395,14 @@ u8 set_tx_beacon_cmd(struct adapter *padapter) int len_diff = 0; - ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); + ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); if (!ph2c) { res = _FAIL; goto exit; } ptxBeacon_parm = kmemdup(&(pmlmeinfo->network), - sizeof(struct wlan_bssid_ex), GFP_KERNEL); + sizeof(struct wlan_bssid_ex), GFP_ATOMIC); if (ptxBeacon_parm == NULL) { kfree(ph2c); res = _FAIL; diff --git a/drivers/staging/rtl8188eu/hal/pwrseqcmd.c b/drivers/staging/rtl8188eu/hal/pwrseqcmd.c index 2867864bbfbe..e6867eea3530 100644 --- a/drivers/staging/rtl8188eu/hal/pwrseqcmd.c +++ b/drivers/staging/rtl8188eu/hal/pwrseqcmd.c @@ -22,7 +22,7 @@ u8 rtl88eu_pwrseqcmdparsing(struct adapter *padapter, u8 cut_vers, struct wl_pwr_cfg pwrseqcmd[]) { - struct wl_pwr_cfg pwrcfgcmd = {0}; + struct wl_pwr_cfg pwrcfgcmd; u8 poll_bit = false; u32 aryidx = 0; u8 value = 0; diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c index 7bc9cb131bcc..30f72d220af1 100644 --- a/drivers/staging/rtl8192e/rtllib_rx.c +++ b/drivers/staging/rtl8192e/rtllib_rx.c @@ -1317,7 +1317,6 @@ static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, bool bToOtherSTA = false; int ret = 0, i = 0; - hdr = (struct rtllib_hdr_4addr *)skb->data; fc = le16_to_cpu(hdr->frame_ctl); type = WLAN_FC_GET_TYPE(fc); stype = WLAN_FC_GET_STYPE(fc); diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c index c2b9ffba354a..919231fec09c 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac.c +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -1968,7 +1968,7 @@ void rtllib_sta_ps_send_pspoll_frame(struct rtllib_device *ieee) static short rtllib_sta_ps_sleep(struct rtllib_device *ieee, u64 *time) { - int timeout = ieee->ps_timeout; + int timeout; u8 dtim; struct rt_pwr_save_ctrl *pPSC = &(ieee->PowerSaveControl); diff --git a/drivers/staging/rtl8192u/ieee80211/dot11d.c b/drivers/staging/rtl8192u/ieee80211/dot11d.c index 64b13a5da3cb..ba284bfb3b6d 100644 --- a/drivers/staging/rtl8192u/ieee80211/dot11d.c +++ b/drivers/staging/rtl8192u/ieee80211/dot11d.c @@ -11,7 +11,7 @@ void Dot11d_Init(struct ieee80211_device *ieee) pDot11dInfo->State = DOT11D_STATE_NONE; pDot11dInfo->CountryIeLen = 0; - memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1); + memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER + 1); memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1); RESET_CIE_WATCHDOG(ieee); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c index cbf8eb4a049d..37a610d05ad2 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c @@ -110,12 +110,12 @@ ieee80211_frag_cache_get(struct ieee80211_device *ieee, hdr_4addrqos = (struct rtl_80211_hdr_4addrqos *)hdr; tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID; tid = UP2AC(tid); - tid ++; + tid++; } else if (IEEE80211_QOS_HAS_SEQ(fc)) { hdr_3addrqos = (struct rtl_80211_hdr_3addrqos *)hdr; tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_TID; tid = UP2AC(tid); - tid ++; + tid++; } else { tid = 0; } @@ -177,12 +177,12 @@ static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee, hdr_4addrqos = (struct rtl_80211_hdr_4addrqos *)hdr; tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID; tid = UP2AC(tid); - tid ++; + tid++; } else if (IEEE80211_QOS_HAS_SEQ(fc)) { hdr_3addrqos = (struct rtl_80211_hdr_3addrqos *)hdr; tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_TID; tid = UP2AC(tid); - tid ++; + tid++; } else { tid = 0; } @@ -434,12 +434,12 @@ static int is_duplicate_packet(struct ieee80211_device *ieee, hdr_4addrqos = (struct rtl_80211_hdr_4addrqos *)header; tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID; tid = UP2AC(tid); - tid ++; + tid++; } else if(IEEE80211_QOS_HAS_SEQ(fc)) { //QoS hdr_3addrqos = (struct rtl_80211_hdr_3addrqos *)header; tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_TID; tid = UP2AC(tid); - tid ++; + tid++; } else { // no QoS tid = 0; } diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index f56fdc7a4b61..25c186a8bde3 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -1725,7 +1725,7 @@ static void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, static short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l) { - int timeout = ieee->ps_timeout; + int timeout; u8 dtim; /*if(ieee->ps == IEEE80211_PS_DISABLED || ieee->iw_mode != IW_MODE_INFRA || diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index 09f66b386e44..3c300f7b6a62 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -4998,7 +4998,7 @@ fail: kfree(priv->pFirmware); priv->pFirmware = NULL; rtl8192_usb_deleteendpoints(dev); - mdelay(10); + msleep(10); free_ieee80211(dev); RT_TRACE(COMP_ERR, "wlan driver load failed\n"); diff --git a/drivers/staging/rtl8712/hal_init.c b/drivers/staging/rtl8712/hal_init.c index de832b0b5eec..2a3f0746ee2c 100644 --- a/drivers/staging/rtl8712/hal_init.c +++ b/drivers/staging/rtl8712/hal_init.c @@ -336,7 +336,6 @@ uint rtl8712_hal_init(struct _adapter *padapter) r8712_read32(padapter, RCR)); val32 = r8712_read32(padapter, RCR); r8712_write32(padapter, RCR, (val32 | BIT(25))); /* Append PHY status */ - val32 = 0; val32 = r8712_read32(padapter, 0x10250040); r8712_write32(padapter, 0x10250040, (val32 & 0x00FFFFFF)); /* for usb rx aggregation */ diff --git a/drivers/staging/rtl8712/ieee80211.c b/drivers/staging/rtl8712/ieee80211.c index 33e82a9dd462..987270395635 100644 --- a/drivers/staging/rtl8712/ieee80211.c +++ b/drivers/staging/rtl8712/ieee80211.c @@ -169,12 +169,13 @@ int r8712_generate_ie(struct registry_priv *pregistrypriv) int sz = 0, rate_len; struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network; u8 *ie = pdev_network->IEs; + u16 beaconPeriod = (u16)pdev_network->Configuration.BeaconPeriod; /*timestamp will be inserted by hardware*/ sz += 8; ie += sz; /*beacon interval : 2bytes*/ - *(__le16 *)ie = cpu_to_le16((u16)pdev_network->Configuration.BeaconPeriod); + *(__le16 *)ie = cpu_to_le16(beaconPeriod); sz += 2; ie += 2; /*capability info*/ @@ -221,7 +222,8 @@ unsigned char *r8712_get_wpa_ie(unsigned char *pie, int *wpa_ie_len, int limit) pbuf = r8712_get_ie(pbuf, _WPA_IE_ID_, &len, limit); if (pbuf) { /*check if oui matches...*/ - if (memcmp((pbuf + 2), wpa_oui_type, sizeof(wpa_oui_type))) + if (memcmp((pbuf + 2), wpa_oui_type, + sizeof(wpa_oui_type))) goto check_next_ie; /*check version...*/ memcpy((u8 *)&val16, (pbuf + 6), sizeof(val16)); diff --git a/drivers/staging/rtl8712/os_intfs.c b/drivers/staging/rtl8712/os_intfs.c index 95caf8df9a13..e7df5d7986fc 100644 --- a/drivers/staging/rtl8712/os_intfs.c +++ b/drivers/staging/rtl8712/os_intfs.c @@ -238,10 +238,13 @@ static u32 start_drv_threads(struct _adapter *padapter) void r8712_stop_drv_threads(struct _adapter *padapter) { + struct completion *completion = + &padapter->cmdpriv.terminate_cmdthread_comp; + /*Below is to terminate r8712_cmd_thread & event_thread...*/ complete(&padapter->cmdpriv.cmd_queue_comp); if (padapter->cmdThread) - wait_for_completion_interruptible(&padapter->cmdpriv.terminate_cmdthread_comp); + wait_for_completion_interruptible(completion); padapter->cmdpriv.cmd_seq = 1; } diff --git a/drivers/staging/rtl8712/rtl8712_cmd.c b/drivers/staging/rtl8712/rtl8712_cmd.c index 3c88994fdfcd..9c8e0c50a804 100644 --- a/drivers/staging/rtl8712/rtl8712_cmd.c +++ b/drivers/staging/rtl8712/rtl8712_cmd.c @@ -321,10 +321,13 @@ int r8712_cmd_thread(void *context) void (*pcmd_callback)(struct _adapter *dev, struct cmd_obj *pcmd); struct _adapter *padapter = context; struct cmd_priv *pcmdpriv = &(padapter->cmdpriv); + struct completion *cmd_queue_comp = + &pcmdpriv->cmd_queue_comp; + struct mutex *pwctrl_lock = &padapter->pwrctrlpriv.mutex_lock; allow_signal(SIGTERM); while (1) { - if (wait_for_completion_interruptible(&pcmdpriv->cmd_queue_comp)) + if (wait_for_completion_interruptible(cmd_queue_comp)) break; if (padapter->bDriverStopped || padapter->bSurpriseRemoved) break; @@ -343,6 +346,7 @@ _next: if (pcmd) { /* if pcmd != NULL, cmd will be handled by f/w */ struct dvobj_priv *pdvobj = &padapter->dvobjpriv; u8 blnPending = 0; + u16 cmdcode = pcmd->cmdcode; pcmdpriv->cmd_issued_cnt++; cmdsz = round_up(pcmd->cmdsz, 8); @@ -387,20 +391,18 @@ _next: r8712_write_mem(padapter, RTL8712_DMA_H2CCMD, wr_sz, (u8 *)pdesc); pcmdpriv->cmd_seq++; - if (pcmd->cmdcode == GEN_CMD_CODE(_CreateBss)) { + if (cmdcode == GEN_CMD_CODE(_CreateBss)) { pcmd->res = H2C_SUCCESS; - pcmd_callback = cmd_callback[pcmd-> - cmdcode].callback; + pcmd_callback = cmd_callback[cmdcode].callback; if (pcmd_callback) pcmd_callback(padapter, pcmd); continue; } - if (pcmd->cmdcode == GEN_CMD_CODE(_SetPwrMode)) { + if (cmdcode == GEN_CMD_CODE(_SetPwrMode)) { if (padapter->pwrctrlpriv.bSleep) { - mutex_lock(&padapter-> - pwrctrlpriv.mutex_lock); + mutex_lock(pwctrl_lock); r8712_set_rpwm(padapter, PS_STATE_S2); - mutex_unlock(&padapter->pwrctrlpriv.mutex_lock); + mutex_unlock(pwctrl_lock); } } r8712_free_cmd_obj(pcmd); diff --git a/drivers/staging/rtl8712/rtl8712_recv.c b/drivers/staging/rtl8712/rtl8712_recv.c index 8f555e6e1b3f..4264cd341f03 100644 --- a/drivers/staging/rtl8712/rtl8712_recv.c +++ b/drivers/staging/rtl8712/rtl8712_recv.c @@ -899,6 +899,7 @@ static void process_link_qual(struct _adapter *padapter, { u32 last_evm = 0, tmpVal; struct rx_pkt_attrib *pattrib; + struct smooth_rssi_data *sqd = &padapter->recvpriv.signal_qual_data; if (prframe == NULL || padapter == NULL) return; @@ -907,27 +908,18 @@ static void process_link_qual(struct _adapter *padapter, /* * 1. Record the general EVM to the sliding window. */ - if (padapter->recvpriv.signal_qual_data.total_num++ >= - PHY_LINKQUALITY_SLID_WIN_MAX) { - padapter->recvpriv.signal_qual_data.total_num = - PHY_LINKQUALITY_SLID_WIN_MAX; - last_evm = padapter->recvpriv.signal_qual_data.elements - [padapter->recvpriv.signal_qual_data.index]; - padapter->recvpriv.signal_qual_data.total_val -= - last_evm; + if (sqd->total_num++ >= PHY_LINKQUALITY_SLID_WIN_MAX) { + sqd->total_num = PHY_LINKQUALITY_SLID_WIN_MAX; + last_evm = sqd->elements[sqd->index]; + sqd->total_val -= last_evm; } - padapter->recvpriv.signal_qual_data.total_val += - pattrib->signal_qual; - padapter->recvpriv.signal_qual_data.elements[padapter-> - recvpriv.signal_qual_data.index++] = - pattrib->signal_qual; - if (padapter->recvpriv.signal_qual_data.index >= - PHY_LINKQUALITY_SLID_WIN_MAX) - padapter->recvpriv.signal_qual_data.index = 0; + sqd->total_val += pattrib->signal_qual; + sqd->elements[sqd->index++] = pattrib->signal_qual; + if (sqd->index >= PHY_LINKQUALITY_SLID_WIN_MAX) + sqd->index = 0; /* <1> Showed on UI for user, in percentage. */ - tmpVal = padapter->recvpriv.signal_qual_data.total_val / - padapter->recvpriv.signal_qual_data.total_num; + tmpVal = sqd->total_val / sqd->total_num; padapter->recvpriv.signal = (u8)tmpVal; } } @@ -936,25 +928,18 @@ static void process_rssi(struct _adapter *padapter, union recv_frame *prframe) { u32 last_rssi, tmp_val; struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; + struct smooth_rssi_data *ssd = &padapter->recvpriv.signal_strength_data; - if (padapter->recvpriv.signal_strength_data.total_num++ >= - PHY_RSSI_SLID_WIN_MAX) { - padapter->recvpriv.signal_strength_data.total_num = - PHY_RSSI_SLID_WIN_MAX; - last_rssi = padapter->recvpriv.signal_strength_data.elements - [padapter->recvpriv.signal_strength_data.index]; - padapter->recvpriv.signal_strength_data.total_val -= last_rssi; + if (ssd->total_num++ >= PHY_RSSI_SLID_WIN_MAX) { + ssd->total_num = PHY_RSSI_SLID_WIN_MAX; + last_rssi = ssd->elements[ssd->index]; + ssd->total_val -= last_rssi; } - padapter->recvpriv.signal_strength_data.total_val += - pattrib->signal_strength; - padapter->recvpriv.signal_strength_data.elements[padapter->recvpriv. - signal_strength_data.index++] = - pattrib->signal_strength; - if (padapter->recvpriv.signal_strength_data.index >= - PHY_RSSI_SLID_WIN_MAX) - padapter->recvpriv.signal_strength_data.index = 0; - tmp_val = padapter->recvpriv.signal_strength_data.total_val / - padapter->recvpriv.signal_strength_data.total_num; + ssd->total_val += pattrib->signal_strength; + ssd->elements[ssd->index++] = pattrib->signal_strength; + if (ssd->index >= PHY_RSSI_SLID_WIN_MAX) + ssd->index = 0; + tmp_val = ssd->total_val / ssd->total_num; padapter->recvpriv.rssi = (s8)translate2dbm(padapter, (u8)tmp_val); } diff --git a/drivers/staging/rtl8712/rtl8712_xmit.c b/drivers/staging/rtl8712/rtl8712_xmit.c index 42d014007764..fb64c2891e22 100644 --- a/drivers/staging/rtl8712/rtl8712_xmit.c +++ b/drivers/staging/rtl8712/rtl8712_xmit.c @@ -573,7 +573,8 @@ static void update_txdesc(struct xmit_frame *pxmitframe, uint *pmem, int sz) } } else if (pxmitframe->frame_tag == MGNT_FRAMETAG) { /* offset 4 */ - ptxdesc->txdw1 |= cpu_to_le32((0x05) & 0x1f);/*CAM_ID(MAC_ID), default=5;*/ + /* CAM_ID(MAC_ID), default=5; */ + ptxdesc->txdw1 |= cpu_to_le32((0x05) & 0x1f); qsel = (uint)(pattrib->qsel & 0x0000001f); ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00); ptxdesc->txdw1 |= cpu_to_le32(BIT(16));/* Non-QoS */ diff --git a/drivers/staging/rtl8712/rtl871x_cmd.c b/drivers/staging/rtl8712/rtl871x_cmd.c index a424f447a725..620cee8b8514 100644 --- a/drivers/staging/rtl8712/rtl871x_cmd.c +++ b/drivers/staging/rtl8712/rtl871x_cmd.c @@ -455,8 +455,8 @@ u8 r8712_joinbss_cmd(struct _adapter *padapter, struct wlan_network *pnetwork) struct qos_priv *pqospriv = &pmlmepriv->qospriv; struct security_priv *psecuritypriv = &padapter->securitypriv; struct registry_priv *pregistrypriv = &padapter->registrypriv; - enum NDIS_802_11_NETWORK_INFRASTRUCTURE ndis_network_mode = pnetwork-> - network.InfrastructureMode; + enum NDIS_802_11_NETWORK_INFRASTRUCTURE ndis_network_mode = + pnetwork->network.InfrastructureMode; padapter->ledpriv.LedControlHandler(padapter, LED_CTL_START_TO_LINK); pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC); @@ -862,22 +862,22 @@ void r8712_createbss_cmd_callback(struct _adapter *padapter, pnetwork->Privacy = le32_to_cpu(pnetwork->Privacy); pnetwork->Rssi = le32_to_cpu(pnetwork->Rssi); pnetwork->NetworkTypeInUse = le32_to_cpu(pnetwork->NetworkTypeInUse); - pnetwork->Configuration.ATIMWindow = le32_to_cpu(pnetwork-> - Configuration.ATIMWindow); - pnetwork->Configuration.DSConfig = le32_to_cpu(pnetwork-> - Configuration.DSConfig); - pnetwork->Configuration.FHConfig.DwellTime = le32_to_cpu(pnetwork-> - Configuration.FHConfig.DwellTime); - pnetwork->Configuration.FHConfig.HopPattern = le32_to_cpu(pnetwork-> - Configuration.FHConfig.HopPattern); - pnetwork->Configuration.FHConfig.HopSet = le32_to_cpu(pnetwork-> - Configuration.FHConfig.HopSet); - pnetwork->Configuration.FHConfig.Length = le32_to_cpu(pnetwork-> - Configuration.FHConfig.Length); - pnetwork->Configuration.Length = le32_to_cpu(pnetwork-> - Configuration.Length); - pnetwork->InfrastructureMode = le32_to_cpu(pnetwork-> - InfrastructureMode); + pnetwork->Configuration.ATIMWindow = + le32_to_cpu(pnetwork->Configuration.ATIMWindow); + pnetwork->Configuration.DSConfig = + le32_to_cpu(pnetwork->Configuration.DSConfig); + pnetwork->Configuration.FHConfig.DwellTime = + le32_to_cpu(pnetwork->Configuration.FHConfig.DwellTime); + pnetwork->Configuration.FHConfig.HopPattern = + le32_to_cpu(pnetwork->Configuration.FHConfig.HopPattern); + pnetwork->Configuration.FHConfig.HopSet = + le32_to_cpu(pnetwork->Configuration.FHConfig.HopSet); + pnetwork->Configuration.FHConfig.Length = + le32_to_cpu(pnetwork->Configuration.FHConfig.Length); + pnetwork->Configuration.Length = + le32_to_cpu(pnetwork->Configuration.Length); + pnetwork->InfrastructureMode = + le32_to_cpu(pnetwork->InfrastructureMode); pnetwork->IELength = le32_to_cpu(pnetwork->IELength); #endif spin_lock_irqsave(&pmlmepriv->lock, irqL); diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c index e30a5be5f318..c3ff7c3e6681 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c @@ -114,23 +114,27 @@ static inline void handle_pairwise_key(struct sta_info *psta, static inline void handle_group_key(struct ieee_param *param, struct _adapter *padapter) { + union Keytype *gk = padapter->securitypriv.XGrpKey; + union Keytype *gtk = padapter->securitypriv.XGrptxmickey; + union Keytype *grk = padapter->securitypriv.XGrprxmickey; + if (param->u.crypt.idx > 0 && param->u.crypt.idx < 3) { /* group key idx is 1 or 2 */ - memcpy(padapter->securitypriv.XGrpKey[param->u.crypt. - idx - 1].skey, param->u.crypt.key, - (param->u.crypt.key_len > 16 ? 16 : - param->u.crypt.key_len)); - memcpy(padapter->securitypriv.XGrptxmickey[param-> - u.crypt.idx - 1].skey, &(param->u.crypt.key[16]), 8); - memcpy(padapter->securitypriv. XGrprxmickey[param-> - u.crypt.idx - 1].skey, &(param->u.crypt.key[24]), 8); + memcpy(gk[param->u.crypt.idx - 1].skey, + param->u.crypt.key, + (param->u.crypt.key_len > 16 ? 16 : + param->u.crypt.key_len)); + memcpy(gtk[param->u.crypt.idx - 1].skey, + ¶m->u.crypt.key[16], 8); + memcpy(grk[param->u.crypt.idx - 1].skey, + ¶m->u.crypt.key[24], 8); padapter->securitypriv.binstallGrpkey = true; r8712_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx); if (padapter->registrypriv.power_mgnt > PS_MODE_ACTIVE) { - if (padapter->registrypriv.power_mgnt != padapter-> - pwrctrlpriv.pwr_mode) + if (padapter->registrypriv.power_mgnt != + padapter->pwrctrlpriv.pwr_mode) mod_timer(&padapter->mlmepriv.dhcp_timer, jiffies + msecs_to_jiffies(60000)); } @@ -216,9 +220,9 @@ static noinline_for_stack char *translate_scan(struct _adapter *padapter, if (dsconfig >= 1 && dsconfig <= sizeof( ieee80211_wlan_frequencies) / sizeof(long)) - iwe.u.freq.m = (s32)(ieee80211_wlan_frequencies[ - pnetwork->network.Configuration. - DSConfig - 1] * 100000); + iwe.u.freq.m = + (s32)(ieee80211_wlan_frequencies + [dsconfig - 1] * 100000); else iwe.u.freq.m = 0; } @@ -425,9 +429,9 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, ret = -EOPNOTSUPP; goto exit; } - memcpy(&(psecuritypriv->DefKey[wep_key_idx]. - skey[0]), pwep->KeyMaterial, - pwep->KeyLength); + memcpy(&psecuritypriv->DefKey[wep_key_idx].skey[0], + pwep->KeyMaterial, + pwep->KeyLength); psecuritypriv->DefKeylen[wep_key_idx] = pwep->KeyLength; r8712_set_key(padapter, psecuritypriv, wep_key_idx); @@ -437,6 +441,7 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, if (padapter->securitypriv.AuthAlgrthm == 2) { /* 802_1x */ struct sta_info *psta, *pbcmc_sta; struct sta_priv *pstapriv = &padapter->stapriv; + struct security_priv *spriv = &padapter->securitypriv; if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE)) { /* sta mode */ @@ -444,12 +449,11 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, get_bssid(pmlmepriv)); if (psta) { psta->ieee8021x_blocked = false; - if ((padapter->securitypriv.ndisencryptstatus == - Ndis802_11Encryption2Enabled) || - (padapter->securitypriv.ndisencryptstatus == - Ndis802_11Encryption3Enabled)) - psta->XPrivacy = padapter-> - securitypriv.PrivacyAlgrthm; + if (spriv->ndisencryptstatus == + Ndis802_11Encryption2Enabled || + spriv->ndisencryptstatus == + Ndis802_11Encryption3Enabled) + psta->XPrivacy = spriv->PrivacyAlgrthm; if (param->u.crypt.set_tx == 1) handle_pairwise_key(psta, param, padapter); @@ -459,13 +463,12 @@ static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, pbcmc_sta = r8712_get_bcmc_stainfo(padapter); if (pbcmc_sta) { pbcmc_sta->ieee8021x_blocked = false; - if ((padapter->securitypriv.ndisencryptstatus == - Ndis802_11Encryption2Enabled) || - (padapter->securitypriv.ndisencryptstatus == - Ndis802_11Encryption3Enabled)) + if (spriv->ndisencryptstatus == + Ndis802_11Encryption2Enabled || + spriv->ndisencryptstatus == + Ndis802_11Encryption3Enabled) pbcmc_sta->XPrivacy = - padapter->securitypriv. - PrivacyAlgrthm; + spriv->PrivacyAlgrthm; } } } @@ -763,6 +766,7 @@ static int r871x_wx_set_pmkid(struct net_device *dev, struct _adapter *padapter = netdev_priv(dev); struct security_priv *psecuritypriv = &padapter->securitypriv; struct iw_pmksa *pPMK = (struct iw_pmksa *) extra; + struct RT_PMKID_LIST *pl = psecuritypriv->PMKIDList; u8 strZeroMacAddress[ETH_ALEN] = {0x00}; u8 strIssueBssid[ETH_ALEN] = {0x00}; u8 j, blInserted = false; @@ -787,16 +791,14 @@ static int r871x_wx_set_pmkid(struct net_device *dev, blInserted = false; /* overwrite PMKID */ for (j = 0; j < NUM_PMKID_CACHE; j++) { - if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, - strIssueBssid, ETH_ALEN)) { + if (!memcmp(pl[j].Bssid, strIssueBssid, ETH_ALEN)) { /* BSSID is matched, the same AP => rewrite * with new PMKID. */ netdev_info(dev, "r8712u: %s: BSSID exists in the PMKList.\n", __func__); - memcpy(psecuritypriv->PMKIDList[j].PMKID, - pPMK->pmkid, IW_PMKID_LEN); - psecuritypriv->PMKIDList[j].bUsed = true; + memcpy(pl[j].PMKID, pPMK->pmkid, IW_PMKID_LEN); + pl[j].bUsed = true; psecuritypriv->PMKIDIndex = j + 1; blInserted = true; break; @@ -806,12 +808,11 @@ static int r871x_wx_set_pmkid(struct net_device *dev, /* Find a new entry */ netdev_info(dev, "r8712u: %s: Use the new entry index = %d for this PMKID.\n", __func__, psecuritypriv->PMKIDIndex); - memcpy(psecuritypriv->PMKIDList[psecuritypriv-> - PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN); - memcpy(psecuritypriv->PMKIDList[psecuritypriv-> - PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN); - psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex]. - bUsed = true; + memcpy(pl[psecuritypriv->PMKIDIndex].Bssid, + strIssueBssid, ETH_ALEN); + memcpy(pl[psecuritypriv->PMKIDIndex].PMKID, + pPMK->pmkid, IW_PMKID_LEN); + pl[psecuritypriv->PMKIDIndex].bUsed = true; psecuritypriv->PMKIDIndex++; if (psecuritypriv->PMKIDIndex == NUM_PMKID_CACHE) psecuritypriv->PMKIDIndex = 0; @@ -820,13 +821,12 @@ static int r871x_wx_set_pmkid(struct net_device *dev, case IW_PMKSA_REMOVE: intReturn = true; for (j = 0; j < NUM_PMKID_CACHE; j++) { - if (!memcmp(psecuritypriv->PMKIDList[j].Bssid, - strIssueBssid, ETH_ALEN)) { + if (!memcmp(pl[j].Bssid, strIssueBssid, ETH_ALEN)) { /* BSSID is matched, the same AP => Remove * this PMKID information and reset it. */ - eth_zero_addr(psecuritypriv->PMKIDList[j].Bssid); - psecuritypriv->PMKIDList[j].bUsed = false; + eth_zero_addr(pl[j].Bssid); + pl[j].bUsed = false; break; } } @@ -1598,6 +1598,7 @@ static int r8711_wx_get_enc(struct net_device *dev, struct _adapter *padapter = netdev_priv(dev); struct iw_point *erq = &(wrqu->encoding); struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + union Keytype *dk = padapter->securitypriv.DefKey; if (!check_fwstate(pmlmepriv, _FW_LINKED)) { if (!check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { @@ -1624,9 +1625,8 @@ static int r8711_wx_get_enc(struct net_device *dev, case Ndis802_11Encryption1Enabled: erq->length = padapter->securitypriv.DefKeylen[key]; if (erq->length) { - memcpy(keybuf, padapter->securitypriv.DefKey[ - key].skey, padapter->securitypriv. - DefKeylen[key]); + memcpy(keybuf, dk[key].skey, + padapter->securitypriv.DefKeylen[key]); erq->flags |= IW_ENCODE_ENABLED; if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen) @@ -1719,12 +1719,12 @@ static int r871x_wx_set_auth(struct net_device *dev, */ if (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled) { - /* it means init value, or using wep, - * ndisencryptstatus = - * Ndis802_11Encryption1Enabled, - * then it needn't reset it; - */ - break; + /* it means init value, or using wep, + * ndisencryptstatus = + * Ndis802_11Encryption1Enabled, + * then it needn't reset it; + */ + break; } if (paramval) { @@ -1853,7 +1853,7 @@ static int dummy(struct net_device *dev, struct iw_request_info *a, union iwreq_data *wrqu, char *b) { - return -ENOSYS; + return -EINVAL; } static int r8711_drvext_hdl(struct net_device *dev, diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_set.c b/drivers/staging/rtl8712/rtl871x_ioctl_set.c index 8a5ced4fa9d3..f4a53df7f2c1 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_set.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_set.c @@ -55,6 +55,7 @@ static u8 do_join(struct _adapter *padapter) u8 *pibss = NULL; struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); struct __queue *queue = &(pmlmepriv->scanned_queue); + int ret; phead = &queue->queue; plist = phead->next; @@ -74,45 +75,42 @@ static u8 do_join(struct _adapter *padapter) if (!pmlmepriv->sitesurveyctrl.traffic_busy) r8712_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid); return true; - } else { - int ret; + } - ret = r8712_select_and_join_from_scan(pmlmepriv); - if (ret == _SUCCESS) { - mod_timer(&pmlmepriv->assoc_timer, - jiffies + msecs_to_jiffies(MAX_JOIN_TIMEOUT)); + ret = r8712_select_and_join_from_scan(pmlmepriv); + if (ret == _SUCCESS) { + mod_timer(&pmlmepriv->assoc_timer, + jiffies + msecs_to_jiffies(MAX_JOIN_TIMEOUT)); + } else { + if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { + /* submit r8712_createbss_cmd to change to an + * ADHOC_MASTER pmlmepriv->lock has been + * acquired by caller... + */ + struct wlan_bssid_ex *pdev_network = + &(padapter->registrypriv.dev_network); + pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE; + pibss = padapter->registrypriv.dev_network.MacAddress; + memcpy(&pdev_network->Ssid, + &pmlmepriv->assoc_ssid, + sizeof(struct ndis_802_11_ssid)); + r8712_update_registrypriv_dev_network(padapter); + r8712_generate_random_ibss(pibss); + if (r8712_createbss_cmd(padapter) != _SUCCESS) + return false; + pmlmepriv->to_join = false; } else { - if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { - /* submit r8712_createbss_cmd to change to an - * ADHOC_MASTER pmlmepriv->lock has been - * acquired by caller... - */ - struct wlan_bssid_ex *pdev_network = - &(padapter->registrypriv.dev_network); - pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE; - pibss = padapter->registrypriv.dev_network. - MacAddress; - memcpy(&pdev_network->Ssid, - &pmlmepriv->assoc_ssid, - sizeof(struct ndis_802_11_ssid)); - r8712_update_registrypriv_dev_network(padapter); - r8712_generate_random_ibss(pibss); - if (r8712_createbss_cmd(padapter) != _SUCCESS) - return false; - pmlmepriv->to_join = false; - } else { - /* can't associate ; reset under-linking */ - if (pmlmepriv->fw_state & _FW_UNDER_LINKING) - pmlmepriv->fw_state ^= - _FW_UNDER_LINKING; - /* when set_ssid/set_bssid for do_join(), but - * there are no desired bss in scanning queue - * we try to issue sitesurvey first - */ - if (!pmlmepriv->sitesurveyctrl.traffic_busy) - r8712_sitesurvey_cmd(padapter, - &pmlmepriv->assoc_ssid); - } + /* can't associate ; reset under-linking */ + if (pmlmepriv->fw_state & _FW_UNDER_LINKING) + pmlmepriv->fw_state ^= + _FW_UNDER_LINKING; + /* when set_ssid/set_bssid for do_join(), but + * there are no desired bss in scanning queue + * we try to issue sitesurvey first + */ + if (!pmlmepriv->sitesurveyctrl.traffic_busy) + r8712_sitesurvey_cmd(padapter, + &pmlmepriv->assoc_ssid); } } return true; diff --git a/drivers/staging/rtl8712/rtl871x_mlme.c b/drivers/staging/rtl8712/rtl871x_mlme.c index 111c809afc51..78245080e328 100644 --- a/drivers/staging/rtl8712/rtl871x_mlme.c +++ b/drivers/staging/rtl8712/rtl871x_mlme.c @@ -319,6 +319,7 @@ static void update_network(struct wlan_bssid_ex *dst, struct _adapter *padapter) { u32 last_evm = 0, tmpVal; + struct smooth_rssi_data *sqd = &padapter->recvpriv.signal_qual_data; if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && is_same_network(&(padapter->mlmepriv.cur_network.network), src)) { @@ -326,17 +327,13 @@ static void update_network(struct wlan_bssid_ex *dst, PHY_LINKQUALITY_SLID_WIN_MAX) { padapter->recvpriv.signal_qual_data.total_num = PHY_LINKQUALITY_SLID_WIN_MAX; - last_evm = padapter->recvpriv.signal_qual_data. - elements[padapter->recvpriv. - signal_qual_data.index]; + last_evm = sqd->elements[sqd->index]; padapter->recvpriv.signal_qual_data.total_val -= last_evm; } padapter->recvpriv.signal_qual_data.total_val += src->Rssi; - padapter->recvpriv.signal_qual_data. - elements[padapter->recvpriv.signal_qual_data. - index++] = src->Rssi; + sqd->elements[sqd->index++] = src->Rssi; if (padapter->recvpriv.signal_qual_data.index >= PHY_LINKQUALITY_SLID_WIN_MAX) padapter->recvpriv.signal_qual_data.index = 0; diff --git a/drivers/staging/rtl8712/rtl871x_mlme.h b/drivers/staging/rtl8712/rtl871x_mlme.h index b21f28140f53..918947f38151 100644 --- a/drivers/staging/rtl8712/rtl871x_mlme.h +++ b/drivers/staging/rtl8712/rtl871x_mlme.h @@ -55,7 +55,8 @@ * single-tone */ #define WIFI_MP_CTX_BACKGROUND_PENDING 0x00080000 /* pending in cont, tx - * background due to out of skb + * background due + * to out of skb */ #define WIFI_MP_CTX_CCK_HW 0x00100000 /* in continuous tx*/ #define WIFI_MP_CTX_CCK_CS 0x00200000 /* in cont, tx with carrier diff --git a/drivers/staging/rtl8712/rtl871x_mp.c b/drivers/staging/rtl8712/rtl871x_mp.c index 3c10a2c848c8..ba208a2e1e4e 100644 --- a/drivers/staging/rtl8712/rtl871x_mp.c +++ b/drivers/staging/rtl8712/rtl871x_mp.c @@ -541,7 +541,7 @@ void r8712_SetSingleCarrierTx(struct _adapter *pAdapter, u8 bStart) void r8712_SetSingleToneTx(struct _adapter *pAdapter, u8 bStart) { - u8 rfPath = pAdapter->mppriv.curr_rfpath; + u8 rfPath; switch (pAdapter->mppriv.antenna_tx) { case ANTENNA_B: diff --git a/drivers/staging/rtl8712/rtl871x_security.c b/drivers/staging/rtl8712/rtl871x_security.c index 56d36f6f9c46..7bc74d7d8a3a 100644 --- a/drivers/staging/rtl8712/rtl871x_security.c +++ b/drivers/staging/rtl8712/rtl871x_security.c @@ -165,7 +165,7 @@ void r8712_wep_encrypt(struct _adapter *padapter, u8 *pxmitframe) { /* exclude ICV */ unsigned char crc[4]; struct arc4context mycontext; - u32 curfragnum, length, keylength; + u32 curfragnum, length, keylength, pki; u8 *pframe, *payload, *iv; /*,*wepkey*/ u8 wepkey[16]; struct pkt_attrib *pattrib = &((struct xmit_frame *) @@ -178,8 +178,8 @@ void r8712_wep_encrypt(struct _adapter *padapter, u8 *pxmitframe) pframe = ((struct xmit_frame *)pxmitframe)->buf_addr + TXDESC_OFFSET; /*start to encrypt each fragment*/ if ((pattrib->encrypt == _WEP40_) || (pattrib->encrypt == _WEP104_)) { - keylength = psecuritypriv->DefKeylen[psecuritypriv-> - PrivacyKeyIndex]; + pki = psecuritypriv->PrivacyKeyIndex; + keylength = psecuritypriv->DefKeylen[pki]; for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) { iv = pframe + pattrib->hdrlen; @@ -189,9 +189,10 @@ void r8712_wep_encrypt(struct _adapter *padapter, u8 *pxmitframe) keylength); payload = pframe + pattrib->iv_len + pattrib->hdrlen; if ((curfragnum + 1) == pattrib->nr_frags) { - length = pattrib->last_txcmdsz - pattrib-> - hdrlen - pattrib->iv_len - - pattrib->icv_len; + length = pattrib->last_txcmdsz - + pattrib->hdrlen - + pattrib->iv_len - + pattrib->icv_len; *((__le32 *)crc) = cpu_to_le32(getcrc32( payload, length)); arcfour_init(&mycontext, wepkey, 3 + keylength); @@ -606,8 +607,8 @@ u32 r8712_tkip_encrypt(struct _adapter *padapter, u8 *pxmitframe) GET_TKIP_PN(iv, txpn); pnl = (u16)(txpn.val); pnh = (u32)(txpn.val >> 16); - phase1((u16 *)&ttkey[0], prwskey, &pattrib-> - ta[0], pnh); + phase1((u16 *)&ttkey[0], prwskey, + &pattrib->ta[0], pnh); phase2(&rc4key[0], prwskey, (u16 *)&ttkey[0], pnl); if ((curfragnum + 1) == pattrib->nr_frags) { @@ -997,8 +998,9 @@ static void construct_mic_header2(u8 *mic_header2, u8 *mpdu, sint a4_exists, /* Builds the last MIC header block from */ /* header fields. */ /************************************************/ -static void construct_ctr_preload(u8 *ctr_preload, sint a4_exists, sint qc_exists, - u8 *mpdu, u8 *pn_vector, sint c) +static void construct_ctr_preload(u8 *ctr_preload, + sint a4_exists, sint qc_exists, + u8 *mpdu, u8 *pn_vector, sint c) { sint i; @@ -1067,16 +1069,16 @@ static sint aes_cipher(u8 *key, uint hdrlen, if ((frtype == WIFI_DATA_CFACK) || (frtype == WIFI_DATA_CFPOLL) || (frtype == WIFI_DATA_CFACKPOLL)) { - qc_exists = 1; - if (hdrlen != WLAN_HDR_A3_QOS_LEN) - hdrlen += 2; + qc_exists = 1; + if (hdrlen != WLAN_HDR_A3_QOS_LEN) + hdrlen += 2; } else if ((frsubtype == 0x08) || (frsubtype == 0x09) || (frsubtype == 0x0a) || (frsubtype == 0x0b)) { - if (hdrlen != WLAN_HDR_A3_QOS_LEN) - hdrlen += 2; - qc_exists = 1; + if (hdrlen != WLAN_HDR_A3_QOS_LEN) + hdrlen += 2; + qc_exists = 1; } else { qc_exists = 0; } @@ -1184,15 +1186,15 @@ u32 r8712_aes_encrypt(struct _adapter *padapter, u8 *pxmitframe) pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len; - aes_cipher(prwskey, pattrib-> - hdrlen, pframe, length); + aes_cipher(prwskey, pattrib->hdrlen, + pframe, length); } else { length = pxmitpriv->frag_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len; - aes_cipher(prwskey, pattrib-> - hdrlen, pframe, length); + aes_cipher(prwskey, pattrib->hdrlen, + pframe, length); pframe += pxmitpriv->frag_len; pframe = (u8 *)RND4((addr_t)(pframe)); } @@ -1405,7 +1407,7 @@ u32 r8712_aes_decrypt(struct _adapter *padapter, u8 *precvframe) void r8712_use_tkipkey_handler(struct timer_list *t) { struct _adapter *padapter = - from_timer(padapter, t, securitypriv.tkip_timer); + from_timer(padapter, t, securitypriv.tkip_timer); padapter->securitypriv.busetkipkey = true; } diff --git a/drivers/staging/rtl8712/usb_ops_linux.c b/drivers/staging/rtl8712/usb_ops_linux.c index 441e76b8959d..6d12a96fa65f 100644 --- a/drivers/staging/rtl8712/usb_ops_linux.c +++ b/drivers/staging/rtl8712/usb_ops_linux.c @@ -145,7 +145,7 @@ static unsigned int ffaddr2pipehdl(struct dvobj_priv *pdvobj, u32 addr) break; } } else { - pipe = 0; + pipe = 0; } return pipe; } diff --git a/drivers/staging/rtl8723bs/core/rtw_cmd.c b/drivers/staging/rtl8723bs/core/rtw_cmd.c index 9ac2dea6dff1..af0a9e0a00df 100644 --- a/drivers/staging/rtl8723bs/core/rtw_cmd.c +++ b/drivers/staging/rtl8723bs/core/rtw_cmd.c @@ -846,9 +846,7 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) psecnetwork = (struct wlan_bssid_ex *)&psecuritypriv->sec_bss; if (psecnetwork == NULL) { - if (pcmd != NULL) - kfree(pcmd); - + kfree(pcmd); res = _FAIL; RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("rtw_joinbss_cmd :psecnetwork == NULL!!!\n")); diff --git a/drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.c b/drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.c index c16e147d8adc..a99a863be656 100644 --- a/drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.c +++ b/drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.c @@ -1052,7 +1052,7 @@ static u8 phy_PathB_RxIQK8723B(struct adapter *padapter, bool configPathB) /* Check failed */ regEAC = PHY_QueryBBReg(pDM_Odm->Adapter, rRx_Power_After_IQK_A_2, bMaskDWord); - regEA4 = PHY_QueryBBReg(pDM_Odm->Adapter, rRx_Power_Before_IQK_A_2, bMaskDWord);; + regEA4 = PHY_QueryBBReg(pDM_Odm->Adapter, rRx_Power_Before_IQK_A_2, bMaskDWord); ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xeac = 0x%x\n", regEAC)); ODM_RT_TRACE(pDM_Odm, ODM_COMP_CALIBRATION, ODM_DBG_LOUD, ("0xea4 = 0x%x, 0xeac = 0x%x\n", regEA4, regEAC)); diff --git a/drivers/staging/rtl8723bs/hal/HalPwrSeqCmd.c b/drivers/staging/rtl8723bs/hal/HalPwrSeqCmd.c index f4619768a99f..334d680b9b1c 100644 --- a/drivers/staging/rtl8723bs/hal/HalPwrSeqCmd.c +++ b/drivers/staging/rtl8723bs/hal/HalPwrSeqCmd.c @@ -50,7 +50,7 @@ u8 HalPwrSeqCmdParsing( WLAN_PWR_CFG PwrSeqCmd[] ) { - WLAN_PWR_CFG PwrCfgCmd = {0}; + WLAN_PWR_CFG PwrCfgCmd; u8 bPollingBit = false; u32 AryIdx = 0; u8 value = 0; diff --git a/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c b/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c index e6787c22e00b..93d6cc478706 100644 --- a/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c +++ b/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c @@ -66,8 +66,7 @@ u8 PHY_GetTxPowerByRateBase(struct adapter *Adapter, u8 Band, u8 RfPath, DBG_871X("Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n", RateSection, RfPath, TxNum); break; - - }; + } } else if (Band == BAND_ON_5G) { switch (RateSection) { case OFDM: @@ -101,7 +100,7 @@ u8 PHY_GetTxPowerByRateBase(struct adapter *Adapter, u8 Band, u8 RfPath, DBG_871X("Invalid RateSection %d in Band 5G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n", RateSection, RfPath, TxNum); break; - }; + } } else DBG_871X("Invalid Band %d in PHY_GetTxPowerByRateBase()\n", Band); @@ -161,7 +160,7 @@ phy_SetTxPowerByRateBase( DBG_871X("Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in phy_SetTxPowerByRateBase()\n", RateSection, RfPath, TxNum); break; - }; + } } else if (Band == BAND_ON_5G) { switch (RateSection) { case OFDM: @@ -195,7 +194,7 @@ phy_SetTxPowerByRateBase( DBG_871X("Invalid RateSection %d in Band 5G, Rf Path %d, %dTx in phy_SetTxPowerByRateBase()\n", RateSection, RfPath, TxNum); break; - }; + } } else DBG_871X("Invalid Band %d in phy_SetTxPowerByRateBase()\n", Band); } @@ -336,7 +335,7 @@ u8 PHY_GetRateSectionIndexOfTxPowerByRate( default: DBG_871X("Invalid RegAddr 0x3%x in PHY_GetRateSectionIndexOfTxPowerByRate()", RegAddr); break; - }; + } } return index; @@ -726,7 +725,7 @@ PHY_GetRateValuesOfTxPowerByRate( default: DBG_871X("Invalid RegAddr 0x%x in %s()\n", RegAddr, __func__); break; - }; + } } static void PHY_StoreTxPowerByRateNew( @@ -1474,8 +1473,7 @@ u8 PHY_GetRateIndexOfTxPowerByRate(u8 Rate) default: DBG_871X("Invalid rate 0x%x in %s\n", Rate, __func__); break; - }; - + } return index; } diff --git a/drivers/staging/rtl8723bs/hal/rtl8723b_phycfg.c b/drivers/staging/rtl8723bs/hal/rtl8723b_phycfg.c index 21ec890fd60c..e34d133075c0 100644 --- a/drivers/staging/rtl8723bs/hal/rtl8723b_phycfg.c +++ b/drivers/staging/rtl8723bs/hal/rtl8723b_phycfg.c @@ -153,7 +153,7 @@ static u32 phy_RFSerialRead_8723B( NewOffset = Offset; if (eRFPath == RF_PATH_A) { - tmplong2 = PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter2|MaskforPhySet, bMaskDWord);; + tmplong2 = PHY_QueryBBReg(Adapter, rFPGA0_XA_HSSIParameter2|MaskforPhySet, bMaskDWord); tmplong2 = (tmplong2 & (~bLSSIReadAddress)) | (NewOffset<<23) | bLSSIReadEdge; /* T65 RF */ PHY_SetBBReg(Adapter, rFPGA0_XA_HSSIParameter2|MaskforPhySet, bMaskDWord, tmplong2&(~bLSSIReadEdge)); } else { diff --git a/drivers/staging/rtl8723bs/hal/sdio_ops.c b/drivers/staging/rtl8723bs/hal/sdio_ops.c index 9a4c24861947..ab2ff53a8e57 100644 --- a/drivers/staging/rtl8723bs/hal/sdio_ops.c +++ b/drivers/staging/rtl8723bs/hal/sdio_ops.c @@ -28,35 +28,35 @@ /* Creadted by Roger, 2011.01.31. */ /* */ static void HalSdioGetCmdAddr8723BSdio( - struct adapter *padapter, - u8 DeviceID, - u32 Addr, - u32 *pCmdAddr + struct adapter *adapter, + u8 device_id, + u32 addr, + u32 *cmdaddr ) { - switch (DeviceID) { + switch (device_id) { case SDIO_LOCAL_DEVICE_ID: - *pCmdAddr = ((SDIO_LOCAL_DEVICE_ID << 13) | (Addr & SDIO_LOCAL_MSK)); + *cmdaddr = ((SDIO_LOCAL_DEVICE_ID << 13) | (addr & SDIO_LOCAL_MSK)); break; case WLAN_IOREG_DEVICE_ID: - *pCmdAddr = ((WLAN_IOREG_DEVICE_ID << 13) | (Addr & WLAN_IOREG_MSK)); + *cmdaddr = ((WLAN_IOREG_DEVICE_ID << 13) | (addr & WLAN_IOREG_MSK)); break; case WLAN_TX_HIQ_DEVICE_ID: - *pCmdAddr = ((WLAN_TX_HIQ_DEVICE_ID << 13) | (Addr & WLAN_FIFO_MSK)); + *cmdaddr = ((WLAN_TX_HIQ_DEVICE_ID << 13) | (addr & WLAN_FIFO_MSK)); break; case WLAN_TX_MIQ_DEVICE_ID: - *pCmdAddr = ((WLAN_TX_MIQ_DEVICE_ID << 13) | (Addr & WLAN_FIFO_MSK)); + *cmdaddr = ((WLAN_TX_MIQ_DEVICE_ID << 13) | (addr & WLAN_FIFO_MSK)); break; case WLAN_TX_LOQ_DEVICE_ID: - *pCmdAddr = ((WLAN_TX_LOQ_DEVICE_ID << 13) | (Addr & WLAN_FIFO_MSK)); + *cmdaddr = ((WLAN_TX_LOQ_DEVICE_ID << 13) | (addr & WLAN_FIFO_MSK)); break; case WLAN_RX0FF_DEVICE_ID: - *pCmdAddr = ((WLAN_RX0FF_DEVICE_ID << 13) | (Addr & WLAN_RX0FF_MSK)); + *cmdaddr = ((WLAN_RX0FF_DEVICE_ID << 13) | (addr & WLAN_RX0FF_MSK)); break; default: @@ -66,64 +66,64 @@ static void HalSdioGetCmdAddr8723BSdio( static u8 get_deviceid(u32 addr) { - u8 devideId; - u16 pseudoId; + u8 devide_id; + u16 pseudo_id; - pseudoId = (u16)(addr >> 16); - switch (pseudoId) { + pseudo_id = (u16)(addr >> 16); + switch (pseudo_id) { case 0x1025: - devideId = SDIO_LOCAL_DEVICE_ID; + devide_id = SDIO_LOCAL_DEVICE_ID; break; case 0x1026: - devideId = WLAN_IOREG_DEVICE_ID; + devide_id = WLAN_IOREG_DEVICE_ID; break; /* case 0x1027: */ -/* devideId = SDIO_FIRMWARE_FIFO; */ +/* devide_id = SDIO_FIRMWARE_FIFO; */ /* break; */ case 0x1031: - devideId = WLAN_TX_HIQ_DEVICE_ID; + devide_id = WLAN_TX_HIQ_DEVICE_ID; break; case 0x1032: - devideId = WLAN_TX_MIQ_DEVICE_ID; + devide_id = WLAN_TX_MIQ_DEVICE_ID; break; case 0x1033: - devideId = WLAN_TX_LOQ_DEVICE_ID; + devide_id = WLAN_TX_LOQ_DEVICE_ID; break; case 0x1034: - devideId = WLAN_RX0FF_DEVICE_ID; + devide_id = WLAN_RX0FF_DEVICE_ID; break; default: -/* devideId = (u8)((addr >> 13) & 0xF); */ - devideId = WLAN_IOREG_DEVICE_ID; +/* devide_id = (u8)((addr >> 13) & 0xF); */ + devide_id = WLAN_IOREG_DEVICE_ID; break; } - return devideId; + return devide_id; } /* * Ref: *HalSdioGetCmdAddr8723BSdio() */ -static u32 _cvrt2ftaddr(const u32 addr, u8 *pdeviceId, u16 *poffset) +static u32 _cvrt2ftaddr(const u32 addr, u8 *pdevice_id, u16 *poffset) { - u8 deviceId; + u8 device_id; u16 offset; u32 ftaddr; - deviceId = get_deviceid(addr); + device_id = get_deviceid(addr); offset = 0; - switch (deviceId) { + switch (device_id) { case SDIO_LOCAL_DEVICE_ID: offset = addr & SDIO_LOCAL_MSK; break; @@ -140,47 +140,44 @@ static u32 _cvrt2ftaddr(const u32 addr, u8 *pdeviceId, u16 *poffset) case WLAN_IOREG_DEVICE_ID: default: - deviceId = WLAN_IOREG_DEVICE_ID; + device_id = WLAN_IOREG_DEVICE_ID; offset = addr & WLAN_IOREG_MSK; break; } - ftaddr = (deviceId << 13) | offset; + ftaddr = (device_id << 13) | offset; - if (pdeviceId) - *pdeviceId = deviceId; + if (pdevice_id) + *pdevice_id = device_id; if (poffset) *poffset = offset; return ftaddr; } -static u8 sdio_read8(struct intf_hdl *pintfhdl, u32 addr) +static u8 sdio_read8(struct intf_hdl *intfhdl, u32 addr) { u32 ftaddr; - u8 val; - ftaddr = _cvrt2ftaddr(addr, NULL, NULL); - val = sd_read8(pintfhdl, ftaddr, NULL); - return val; + + return sd_read8(intfhdl, ftaddr, NULL); } -static u16 sdio_read16(struct intf_hdl *pintfhdl, u32 addr) +static u16 sdio_read16(struct intf_hdl *intfhdl, u32 addr) { u32 ftaddr; - u16 val; __le16 le_tmp; ftaddr = _cvrt2ftaddr(addr, NULL, NULL); - sd_cmd52_read(pintfhdl, ftaddr, 2, (u8 *)&le_tmp); - val = le16_to_cpu(le_tmp); - return val; + sd_cmd52_read(intfhdl, ftaddr, 2, (u8 *)&le_tmp); + + return le16_to_cpu(le_tmp); } -static u32 sdio_read32(struct intf_hdl *pintfhdl, u32 addr) +static u32 sdio_read32(struct intf_hdl *intfhdl, u32 addr) { - struct adapter *padapter; - u8 bMacPwrCtrlOn; - u8 deviceId; + struct adapter *adapter; + u8 mac_pwr_ctrl_on; + u8 device_id; u16 offset; u32 ftaddr; u8 shift; @@ -188,21 +185,20 @@ static u32 sdio_read32(struct intf_hdl *pintfhdl, u32 addr) s32 err; __le32 le_tmp; - padapter = pintfhdl->padapter; - ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset); + adapter = intfhdl->padapter; + ftaddr = _cvrt2ftaddr(addr, &device_id, &offset); - rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); + rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on); if ( - ((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) || - (false == bMacPwrCtrlOn) || - (true == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode) + ((device_id == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) || + (!mac_pwr_ctrl_on) || + (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode) ) { - err = sd_cmd52_read(pintfhdl, ftaddr, 4, (u8 *)&le_tmp); + err = sd_cmd52_read(intfhdl, ftaddr, 4, (u8 *)&le_tmp); #ifdef SDIO_DEBUG_IO if (!err) { #endif - val = le32_to_cpu(le_tmp); - return val; + return le32_to_cpu(le_tmp); #ifdef SDIO_DEBUG_IO } @@ -214,191 +210,184 @@ static u32 sdio_read32(struct intf_hdl *pintfhdl, u32 addr) /* 4 bytes alignment */ shift = ftaddr & 0x3; if (shift == 0) { - val = sd_read32(pintfhdl, ftaddr, NULL); + val = sd_read32(intfhdl, ftaddr, NULL); } else { - u8 *ptmpbuf; + u8 *tmpbuf; - ptmpbuf = rtw_malloc(8); - if (NULL == ptmpbuf) { + tmpbuf = rtw_malloc(8); + if (!tmpbuf) { DBG_8192C(KERN_ERR "%s: Allocate memory FAIL!(size =8) addr = 0x%x\n", __func__, addr); return SDIO_ERR_VAL32; } ftaddr &= ~(u16)0x3; - sd_read(pintfhdl, ftaddr, 8, ptmpbuf); - memcpy(&le_tmp, ptmpbuf+shift, 4); + sd_read(intfhdl, ftaddr, 8, tmpbuf); + memcpy(&le_tmp, tmpbuf+shift, 4); val = le32_to_cpu(le_tmp); - kfree(ptmpbuf); + kfree(tmpbuf); } return val; } -static s32 sdio_readN(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pbuf) +static s32 sdio_readN(struct intf_hdl *intfhdl, u32 addr, u32 cnt, u8 *buf) { - struct adapter *padapter; - u8 bMacPwrCtrlOn; - u8 deviceId; + struct adapter *adapter; + u8 mac_pwr_ctrl_on; + u8 device_id; u16 offset; u32 ftaddr; u8 shift; s32 err; - padapter = pintfhdl->padapter; + adapter = intfhdl->padapter; err = 0; - ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset); + ftaddr = _cvrt2ftaddr(addr, &device_id, &offset); - rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); + rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on); if ( - ((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) || - (false == bMacPwrCtrlOn) || - (true == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode) - ) { - err = sd_cmd52_read(pintfhdl, ftaddr, cnt, pbuf); - return err; - } + ((device_id == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) || + (!mac_pwr_ctrl_on) || + (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode) + ) + return sd_cmd52_read(intfhdl, ftaddr, cnt, buf); /* 4 bytes alignment */ shift = ftaddr & 0x3; if (shift == 0) { - err = sd_read(pintfhdl, ftaddr, cnt, pbuf); + err = sd_read(intfhdl, ftaddr, cnt, buf); } else { - u8 *ptmpbuf; + u8 *tmpbuf; u32 n; ftaddr &= ~(u16)0x3; n = cnt + shift; - ptmpbuf = rtw_malloc(n); - if (NULL == ptmpbuf) + tmpbuf = rtw_malloc(n); + if (!tmpbuf) return -1; - err = sd_read(pintfhdl, ftaddr, n, ptmpbuf); + err = sd_read(intfhdl, ftaddr, n, tmpbuf); if (!err) - memcpy(pbuf, ptmpbuf+shift, cnt); - kfree(ptmpbuf); + memcpy(buf, tmpbuf+shift, cnt); + kfree(tmpbuf); } return err; } -static s32 sdio_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val) +static s32 sdio_write8(struct intf_hdl *intfhdl, u32 addr, u8 val) { u32 ftaddr; s32 err; ftaddr = _cvrt2ftaddr(addr, NULL, NULL); - sd_write8(pintfhdl, ftaddr, val, &err); + sd_write8(intfhdl, ftaddr, val, &err); return err; } -static s32 sdio_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val) +static s32 sdio_write16(struct intf_hdl *intfhdl, u32 addr, u16 val) { u32 ftaddr; - s32 err; __le16 le_tmp; ftaddr = _cvrt2ftaddr(addr, NULL, NULL); le_tmp = cpu_to_le16(val); - err = sd_cmd52_write(pintfhdl, ftaddr, 2, (u8 *)&le_tmp); - - return err; + return sd_cmd52_write(intfhdl, ftaddr, 2, (u8 *)&le_tmp); } -static s32 sdio_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val) +static s32 sdio_write32(struct intf_hdl *intfhdl, u32 addr, u32 val) { - struct adapter *padapter; - u8 bMacPwrCtrlOn; - u8 deviceId; + struct adapter *adapter; + u8 mac_pwr_ctrl_on; + u8 device_id; u16 offset; u32 ftaddr; u8 shift; s32 err; __le32 le_tmp; - padapter = pintfhdl->padapter; + adapter = intfhdl->padapter; err = 0; - ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset); + ftaddr = _cvrt2ftaddr(addr, &device_id, &offset); - rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); + rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on); if ( - ((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) || - (!bMacPwrCtrlOn) || - (adapter_to_pwrctl(padapter)->bFwCurrentInPSMode) + ((device_id == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) || + (!mac_pwr_ctrl_on) || + (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode) ) { le_tmp = cpu_to_le32(val); - err = sd_cmd52_write(pintfhdl, ftaddr, 4, (u8 *)&le_tmp); - return err; + + return sd_cmd52_write(intfhdl, ftaddr, 4, (u8 *)&le_tmp); } /* 4 bytes alignment */ shift = ftaddr & 0x3; if (shift == 0) { - sd_write32(pintfhdl, ftaddr, val, &err); + sd_write32(intfhdl, ftaddr, val, &err); } else { le_tmp = cpu_to_le32(val); - err = sd_cmd52_write(pintfhdl, ftaddr, 4, (u8 *)&le_tmp); + err = sd_cmd52_write(intfhdl, ftaddr, 4, (u8 *)&le_tmp); } return err; } -static s32 sdio_writeN(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pbuf) +static s32 sdio_writeN(struct intf_hdl *intfhdl, u32 addr, u32 cnt, u8 *buf) { - struct adapter *padapter; - u8 bMacPwrCtrlOn; - u8 deviceId; + struct adapter *adapter; + u8 mac_pwr_ctrl_on; + u8 device_id; u16 offset; u32 ftaddr; u8 shift; s32 err; - padapter = pintfhdl->padapter; + adapter = intfhdl->padapter; err = 0; - ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset); + ftaddr = _cvrt2ftaddr(addr, &device_id, &offset); - rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); + rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on); if ( - ((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) || - (false == bMacPwrCtrlOn) || - (true == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode) - ) { - err = sd_cmd52_write(pintfhdl, ftaddr, cnt, pbuf); - return err; - } + ((device_id == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) || + (!mac_pwr_ctrl_on) || + (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode) + ) + return sd_cmd52_write(intfhdl, ftaddr, cnt, buf); shift = ftaddr & 0x3; if (shift == 0) { - err = sd_write(pintfhdl, ftaddr, cnt, pbuf); + err = sd_write(intfhdl, ftaddr, cnt, buf); } else { - u8 *ptmpbuf; + u8 *tmpbuf; u32 n; ftaddr &= ~(u16)0x3; n = cnt + shift; - ptmpbuf = rtw_malloc(n); - if (NULL == ptmpbuf) + tmpbuf = rtw_malloc(n); + if (!tmpbuf) return -1; - err = sd_read(pintfhdl, ftaddr, 4, ptmpbuf); + err = sd_read(intfhdl, ftaddr, 4, tmpbuf); if (err) { - kfree(ptmpbuf); + kfree(tmpbuf); return err; } - memcpy(ptmpbuf+shift, pbuf, cnt); - err = sd_write(pintfhdl, ftaddr, n, ptmpbuf); - kfree(ptmpbuf); + memcpy(tmpbuf+shift, buf, cnt); + err = sd_write(intfhdl, ftaddr, n, tmpbuf); + kfree(tmpbuf); } return err; } -static u8 sdio_f0_read8(struct intf_hdl *pintfhdl, u32 addr) +static u8 sdio_f0_read8(struct intf_hdl *intfhdl, u32 addr) { - return sd_f0_read8(pintfhdl, addr, NULL); + return sd_f0_read8(intfhdl, addr, NULL); } static void sdio_read_mem( - struct intf_hdl *pintfhdl, + struct intf_hdl *intfhdl, u32 addr, u32 cnt, u8 *rmem @@ -406,18 +395,18 @@ static void sdio_read_mem( { s32 err; - err = sdio_readN(pintfhdl, addr, cnt, rmem); + err = sdio_readN(intfhdl, addr, cnt, rmem); /* TODO: Report error is err not zero */ } static void sdio_write_mem( - struct intf_hdl *pintfhdl, + struct intf_hdl *intfhdl, u32 addr, u32 cnt, u8 *wmem ) { - sdio_writeN(pintfhdl, addr, cnt, wmem); + sdio_writeN(intfhdl, addr, cnt, wmem); } /* @@ -427,7 +416,7 @@ static void sdio_write_mem( *and make sure data transfer will be done in one command. * * Parameters: - *pintfhdl a pointer of intf_hdl + *intfhdl a pointer of intf_hdl *addr port ID *cnt size to read *rmem address to put data @@ -437,15 +426,15 @@ static void sdio_write_mem( *_FAIL(0) Fail */ static u32 sdio_read_port( - struct intf_hdl *pintfhdl, + struct intf_hdl *intfhdl, u32 addr, u32 cnt, u8 *mem ) { - struct adapter *padapter; + struct adapter *adapter; PSDIO_DATA psdio; - struct hal_com_data *phal; + struct hal_com_data *hal; u32 oldcnt; #ifdef SDIO_DYNAMIC_ALLOC_MEM u8 *oldmem; @@ -453,33 +442,18 @@ static u32 sdio_read_port( s32 err; - padapter = pintfhdl->padapter; - psdio = &adapter_to_dvobj(padapter)->intf_data; - phal = GET_HAL_DATA(padapter); + adapter = intfhdl->padapter; + psdio = &adapter_to_dvobj(adapter)->intf_data; + hal = GET_HAL_DATA(adapter); - HalSdioGetCmdAddr8723BSdio(padapter, addr, phal->SdioRxFIFOCnt++, &addr); + HalSdioGetCmdAddr8723BSdio(adapter, addr, hal->SdioRxFIFOCnt++, &addr); oldcnt = cnt; if (cnt > psdio->block_transfer_len) cnt = _RND(cnt, psdio->block_transfer_len); /* cnt = sdio_align_size(cnt); */ - if (oldcnt != cnt) { -#ifdef SDIO_DYNAMIC_ALLOC_MEM - oldmem = mem; - mem = rtw_malloc(cnt); - if (mem == NULL) { - DBG_8192C(KERN_WARNING "%s: allocate memory %d bytes fail!\n", __func__, cnt); - mem = oldmem; - oldmem == NULL; - } -#else - /* in this case, caller should gurante the buffer is big enough */ - /* to receive data after alignment */ -#endif - } - - err = _sd_read(pintfhdl, addr, cnt, mem); + err = _sd_read(intfhdl, addr, cnt, mem); #ifdef SDIO_DYNAMIC_ALLOC_MEM if ((oldcnt != cnt) && (oldmem)) { @@ -500,7 +474,7 @@ static u32 sdio_read_port( *and make sure data could be written in one command. * * Parameters: - *pintfhdl a pointer of intf_hdl + *intfhdl a pointer of intf_hdl *addr port ID *cnt size to write *wmem data pointer to write @@ -510,33 +484,33 @@ static u32 sdio_read_port( *_FAIL(0) Fail */ static u32 sdio_write_port( - struct intf_hdl *pintfhdl, + struct intf_hdl *intfhdl, u32 addr, u32 cnt, u8 *mem ) { - struct adapter *padapter; + struct adapter *adapter; PSDIO_DATA psdio; s32 err; struct xmit_buf *xmitbuf = (struct xmit_buf *)mem; - padapter = pintfhdl->padapter; - psdio = &adapter_to_dvobj(padapter)->intf_data; + adapter = intfhdl->padapter; + psdio = &adapter_to_dvobj(adapter)->intf_data; - if (padapter->hw_init_completed == false) { - DBG_871X("%s [addr = 0x%x cnt =%d] padapter->hw_init_completed == false\n", __func__, addr, cnt); + if (!adapter->hw_init_completed) { + DBG_871X("%s [addr = 0x%x cnt =%d] adapter->hw_init_completed == false\n", __func__, addr, cnt); return _FAIL; } cnt = _RND4(cnt); - HalSdioGetCmdAddr8723BSdio(padapter, addr, cnt >> 2, &addr); + HalSdioGetCmdAddr8723BSdio(adapter, addr, cnt >> 2, &addr); if (cnt > psdio->block_transfer_len) cnt = _RND(cnt, psdio->block_transfer_len); /* cnt = sdio_align_size(cnt); */ - err = sd_write(pintfhdl, addr, cnt, xmitbuf->pdata); + err = sd_write(intfhdl, addr, cnt, xmitbuf->pdata); rtw_sctx_done_err( &xmitbuf->sctx, @@ -548,61 +522,59 @@ static u32 sdio_write_port( return _SUCCESS; } -void sdio_set_intf_ops(struct adapter *padapter, struct _io_ops *pops) +void sdio_set_intf_ops(struct adapter *adapter, struct _io_ops *ops) { - pops->_read8 = &sdio_read8; - pops->_read16 = &sdio_read16; - pops->_read32 = &sdio_read32; - pops->_read_mem = &sdio_read_mem; - pops->_read_port = &sdio_read_port; - - pops->_write8 = &sdio_write8; - pops->_write16 = &sdio_write16; - pops->_write32 = &sdio_write32; - pops->_writeN = &sdio_writeN; - pops->_write_mem = &sdio_write_mem; - pops->_write_port = &sdio_write_port; - - pops->_sd_f0_read8 = sdio_f0_read8; + ops->_read8 = &sdio_read8; + ops->_read16 = &sdio_read16; + ops->_read32 = &sdio_read32; + ops->_read_mem = &sdio_read_mem; + ops->_read_port = &sdio_read_port; + + ops->_write8 = &sdio_write8; + ops->_write16 = &sdio_write16; + ops->_write32 = &sdio_write32; + ops->_writeN = &sdio_writeN; + ops->_write_mem = &sdio_write_mem; + ops->_write_port = &sdio_write_port; + + ops->_sd_f0_read8 = sdio_f0_read8; } /* * Todo: align address to 4 bytes. */ static s32 _sdio_local_read( - struct adapter *padapter, + struct adapter *adapter, u32 addr, u32 cnt, - u8 *pbuf + u8 *buf ) { - struct intf_hdl *pintfhdl; - u8 bMacPwrCtrlOn; + struct intf_hdl *intfhdl; + u8 mac_pwr_ctrl_on; s32 err; - u8 *ptmpbuf; + u8 *tmpbuf; u32 n; - pintfhdl = &padapter->iopriv.intf; + intfhdl = &adapter->iopriv.intf; - HalSdioGetCmdAddr8723BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); + HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); - rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); - if (false == bMacPwrCtrlOn) { - err = _sd_cmd52_read(pintfhdl, addr, cnt, pbuf); - return err; - } + rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on); + if (!mac_pwr_ctrl_on) + return _sd_cmd52_read(intfhdl, addr, cnt, buf); n = RND4(cnt); - ptmpbuf = rtw_malloc(n); - if (!ptmpbuf) + tmpbuf = rtw_malloc(n); + if (!tmpbuf) return (-1); - err = _sd_read(pintfhdl, addr, n, ptmpbuf); + err = _sd_read(intfhdl, addr, n, tmpbuf); if (!err) - memcpy(pbuf, ptmpbuf, cnt); + memcpy(buf, tmpbuf, cnt); - kfree(ptmpbuf); + kfree(tmpbuf); return err; } @@ -611,41 +583,39 @@ static s32 _sdio_local_read( * Todo: align address to 4 bytes. */ s32 sdio_local_read( - struct adapter *padapter, + struct adapter *adapter, u32 addr, u32 cnt, - u8 *pbuf + u8 *buf ) { - struct intf_hdl *pintfhdl; - u8 bMacPwrCtrlOn; + struct intf_hdl *intfhdl; + u8 mac_pwr_ctrl_on; s32 err; - u8 *ptmpbuf; + u8 *tmpbuf; u32 n; - pintfhdl = &padapter->iopriv.intf; + intfhdl = &adapter->iopriv.intf; - HalSdioGetCmdAddr8723BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); + HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); - rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); + rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on); if ( - (false == bMacPwrCtrlOn) || - (true == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode) - ) { - err = sd_cmd52_read(pintfhdl, addr, cnt, pbuf); - return err; - } + (!mac_pwr_ctrl_on) || + (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode) + ) + return sd_cmd52_read(intfhdl, addr, cnt, buf); n = RND4(cnt); - ptmpbuf = rtw_malloc(n); - if (!ptmpbuf) + tmpbuf = rtw_malloc(n); + if (!tmpbuf) return (-1); - err = sd_read(pintfhdl, addr, n, ptmpbuf); + err = sd_read(intfhdl, addr, n, tmpbuf); if (!err) - memcpy(pbuf, ptmpbuf, cnt); + memcpy(buf, tmpbuf, cnt); - kfree(ptmpbuf); + kfree(tmpbuf); return err; } @@ -654,16 +624,16 @@ s32 sdio_local_read( * Todo: align address to 4 bytes. */ s32 sdio_local_write( - struct adapter *padapter, + struct adapter *adapter, u32 addr, u32 cnt, - u8 *pbuf + u8 *buf ) { - struct intf_hdl *pintfhdl; - u8 bMacPwrCtrlOn; + struct intf_hdl *intfhdl; + u8 mac_pwr_ctrl_on; s32 err; - u8 *ptmpbuf; + u8 *tmpbuf; if (addr & 0x3) DBG_8192C("%s, address must be 4 bytes alignment\n", __func__); @@ -671,101 +641,99 @@ s32 sdio_local_write( if (cnt & 0x3) DBG_8192C("%s, size must be the multiple of 4\n", __func__); - pintfhdl = &padapter->iopriv.intf; + intfhdl = &adapter->iopriv.intf; - HalSdioGetCmdAddr8723BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); + HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); - rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); + rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on); if ( - (false == bMacPwrCtrlOn) || - (true == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode) - ) { - err = sd_cmd52_write(pintfhdl, addr, cnt, pbuf); - return err; - } + (!mac_pwr_ctrl_on) || + (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode) + ) + return sd_cmd52_write(intfhdl, addr, cnt, buf); - ptmpbuf = rtw_malloc(cnt); - if (!ptmpbuf) + tmpbuf = rtw_malloc(cnt); + if (!tmpbuf) return (-1); - memcpy(ptmpbuf, pbuf, cnt); + memcpy(tmpbuf, buf, cnt); - err = sd_write(pintfhdl, addr, cnt, ptmpbuf); + err = sd_write(intfhdl, addr, cnt, tmpbuf); - kfree(ptmpbuf); + kfree(tmpbuf); return err; } -u8 SdioLocalCmd52Read1Byte(struct adapter *padapter, u32 addr) +u8 SdioLocalCmd52Read1Byte(struct adapter *adapter, u32 addr) { u8 val = 0; - struct intf_hdl *pintfhdl = &padapter->iopriv.intf; + struct intf_hdl *intfhdl = &adapter->iopriv.intf; - HalSdioGetCmdAddr8723BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); - sd_cmd52_read(pintfhdl, addr, 1, &val); + HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); + sd_cmd52_read(intfhdl, addr, 1, &val); return val; } -static u16 SdioLocalCmd52Read2Byte(struct adapter *padapter, u32 addr) +static u16 SdioLocalCmd52Read2Byte(struct adapter *adapter, u32 addr) { __le16 val = 0; - struct intf_hdl *pintfhdl = &padapter->iopriv.intf; + struct intf_hdl *intfhdl = &adapter->iopriv.intf; - HalSdioGetCmdAddr8723BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); - sd_cmd52_read(pintfhdl, addr, 2, (u8 *)&val); + HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); + sd_cmd52_read(intfhdl, addr, 2, (u8 *)&val); return le16_to_cpu(val); } -static u32 SdioLocalCmd53Read4Byte(struct adapter *padapter, u32 addr) +static u32 SdioLocalCmd53Read4Byte(struct adapter *adapter, u32 addr) { - u8 bMacPwrCtrlOn; + u8 mac_pwr_ctrl_on; u32 val = 0; - struct intf_hdl *pintfhdl = &padapter->iopriv.intf; + struct intf_hdl *intfhdl = &adapter->iopriv.intf; __le32 le_tmp; - HalSdioGetCmdAddr8723BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); - rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn); - if (!bMacPwrCtrlOn || adapter_to_pwrctl(padapter)->bFwCurrentInPSMode) { - sd_cmd52_read(pintfhdl, addr, 4, (u8 *)&le_tmp); + HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); + rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on); + if (!mac_pwr_ctrl_on || adapter_to_pwrctl(adapter)->bFwCurrentInPSMode) { + sd_cmd52_read(intfhdl, addr, 4, (u8 *)&le_tmp); val = le32_to_cpu(le_tmp); } else { - val = sd_read32(pintfhdl, addr, NULL); + val = sd_read32(intfhdl, addr, NULL); } return val; } -void SdioLocalCmd52Write1Byte(struct adapter *padapter, u32 addr, u8 v) +void SdioLocalCmd52Write1Byte(struct adapter *adapter, u32 addr, u8 v) { - struct intf_hdl *pintfhdl = &padapter->iopriv.intf; + struct intf_hdl *intfhdl = &adapter->iopriv.intf; - HalSdioGetCmdAddr8723BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); - sd_cmd52_write(pintfhdl, addr, 1, &v); + HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); + sd_cmd52_write(intfhdl, addr, 1, &v); } -static void SdioLocalCmd52Write4Byte(struct adapter *padapter, u32 addr, u32 v) +static void SdioLocalCmd52Write4Byte(struct adapter *adapter, u32 addr, u32 v) { - struct intf_hdl *pintfhdl = &padapter->iopriv.intf; + struct intf_hdl *intfhdl = &adapter->iopriv.intf; __le32 le_tmp; - HalSdioGetCmdAddr8723BSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); + HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr); le_tmp = cpu_to_le32(v); - sd_cmd52_write(pintfhdl, addr, 4, (u8 *)&le_tmp); + sd_cmd52_write(intfhdl, addr, 4, (u8 *)&le_tmp); } -static s32 ReadInterrupt8723BSdio(struct adapter *padapter, u32 *phisr) +static s32 ReadInterrupt8723BSdio(struct adapter *adapter, u32 *phisr) { u32 hisr, himr; u8 val8, hisr_len; - if (phisr == NULL) + if (!phisr) return false; - himr = GET_HAL_DATA(padapter)->sdio_himr; + himr = GET_HAL_DATA(adapter)->sdio_himr; /* decide how many bytes need to be read */ hisr_len = 0; @@ -777,7 +745,7 @@ static s32 ReadInterrupt8723BSdio(struct adapter *padapter, u32 *phisr) hisr = 0; while (hisr_len != 0) { hisr_len--; - val8 = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HISR+hisr_len); + val8 = SdioLocalCmd52Read1Byte(adapter, SDIO_REG_HISR+hisr_len); hisr |= (val8 << (8*hisr_len)); } @@ -795,13 +763,13 @@ static s32 ReadInterrupt8723BSdio(struct adapter *padapter, u32 *phisr) /* */ /* Created by Roger, 2011.02.11. */ /* */ -void InitInterrupt8723BSdio(struct adapter *padapter) +void InitInterrupt8723BSdio(struct adapter *adapter) { - struct hal_com_data *pHalData; + struct hal_com_data *haldata; - pHalData = GET_HAL_DATA(padapter); - pHalData->sdio_himr = (u32)( \ + haldata = GET_HAL_DATA(adapter); + haldata->sdio_himr = (u32)( \ SDIO_HIMR_RX_REQUEST_MSK | SDIO_HIMR_AVAL_MSK | /* SDIO_HIMR_TXERR_MSK | */ @@ -829,14 +797,14 @@ void InitInterrupt8723BSdio(struct adapter *padapter) /* */ /* Created by Roger, 2011.08.03. */ /* */ -void InitSysInterrupt8723BSdio(struct adapter *padapter) +void InitSysInterrupt8723BSdio(struct adapter *adapter) { - struct hal_com_data *pHalData; + struct hal_com_data *haldata; - pHalData = GET_HAL_DATA(padapter); + haldata = GET_HAL_DATA(adapter); - pHalData->SysIntrMask = ( \ + haldata->SysIntrMask = ( \ /* HSIMR_GPIO12_0_INT_EN | */ /* HSIMR_SPS_OCP_INT_EN | */ /* HSIMR_RON_INT_EN | */ @@ -855,20 +823,19 @@ void InitSysInterrupt8723BSdio(struct adapter *padapter) /* */ /* Created by Roger, 2011.02.11. */ /* */ -void ClearInterrupt8723BSdio(struct adapter *padapter) +void clearinterrupt8723bsdio(struct adapter *adapter) { - struct hal_com_data *pHalData; + struct hal_com_data *haldata; u8 *clear; - - if (true == padapter->bSurpriseRemoved) + if (adapter->bSurpriseRemoved) return; - pHalData = GET_HAL_DATA(padapter); + haldata = GET_HAL_DATA(adapter); clear = rtw_zmalloc(4); /* Clear corresponding HISR Content if needed */ - *(__le32 *)clear = cpu_to_le32(pHalData->sdio_hisr & MASK_SDIO_HISR_CLEAR); + *(__le32 *)clear = cpu_to_le32(haldata->sdio_hisr & MASK_SDIO_HISR_CLEAR); if (*(__le32 *)clear) { /* Perform write one clear operation */ sdio_local_write(padapter, SDIO_REG_HISR, 4, clear); @@ -888,16 +855,16 @@ void ClearInterrupt8723BSdio(struct adapter *padapter) /* */ /* Created by Roger, 2011.02.11. */ /* */ -void EnableInterrupt8723BSdio(struct adapter *padapter) +void EnableInterrupt8723BSdio(struct adapter *adapter) { - struct hal_com_data *pHalData; + struct hal_com_data *haldata; __le32 himr; u32 tmp; - pHalData = GET_HAL_DATA(padapter); + haldata = GET_HAL_DATA(adapter); - himr = cpu_to_le32(pHalData->sdio_himr); - sdio_local_write(padapter, SDIO_REG_HIMR, 4, (u8 *)&himr); + himr = cpu_to_le32(haldata->sdio_himr); + sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&himr); RT_TRACE( _module_hci_ops_c_, @@ -905,13 +872,13 @@ void EnableInterrupt8723BSdio(struct adapter *padapter) ( "%s: enable SDIO HIMR = 0x%08X\n", __func__, - pHalData->sdio_himr + haldata->sdio_himr ) ); /* Update current system IMR settings */ - tmp = rtw_read32(padapter, REG_HSIMR); - rtw_write32(padapter, REG_HSIMR, tmp | pHalData->SysIntrMask); + tmp = rtw_read32(adapter, REG_HSIMR); + rtw_write32(adapter, REG_HSIMR, tmp | haldata->SysIntrMask); RT_TRACE( _module_hci_ops_c_, @@ -919,7 +886,7 @@ void EnableInterrupt8723BSdio(struct adapter *padapter) ( "%s: enable HSIMR = 0x%08X\n", __func__, - pHalData->SysIntrMask + haldata->SysIntrMask ) ); @@ -928,7 +895,7 @@ void EnableInterrupt8723BSdio(struct adapter *padapter) /* So we need to clear all C2H events that FW has notified, otherwise FW won't schedule any commands anymore. */ /* 2011.10.19. */ /* */ - rtw_write8(padapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE); + rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE); } /* */ @@ -940,12 +907,12 @@ void EnableInterrupt8723BSdio(struct adapter *padapter) /* */ /* Created by Roger, 2011.02.11. */ /* */ -void DisableInterrupt8723BSdio(struct adapter *padapter) +void DisableInterrupt8723BSdio(struct adapter *adapter) { __le32 himr; himr = cpu_to_le32(SDIO_HIMR_DISABLED); - sdio_local_write(padapter, SDIO_REG_HIMR, 4, (u8 *)&himr); + sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&himr); } /* */ @@ -957,27 +924,27 @@ void DisableInterrupt8723BSdio(struct adapter *padapter) /* */ /* Created by Isaac, 2013.09.10. */ /* */ -u8 CheckIPSStatus(struct adapter *padapter) +u8 CheckIPSStatus(struct adapter *adapter) { DBG_871X( "%s(): Read 0x100 = 0x%02x 0x86 = 0x%02x\n", __func__, - rtw_read8(padapter, 0x100), - rtw_read8(padapter, 0x86) + rtw_read8(adapter, 0x100), + rtw_read8(adapter, 0x86) ); - if (rtw_read8(padapter, 0x100) == 0xEA) + if (rtw_read8(adapter, 0x100) == 0xEA) return true; else return false; } -static struct recv_buf *sd_recv_rxfifo(struct adapter *padapter, u32 size) +static struct recv_buf *sd_recv_rxfifo(struct adapter *adapter, u32 size) { u32 readsize, ret; - u8 *preadbuf; - struct recv_priv *precvpriv; - struct recv_buf *precvbuf; + u8 *readbuf; + struct recv_priv *recv_priv; + struct recv_buf *recvbuf; /* Patch for some SDIO Host 4 bytes issue */ @@ -985,37 +952,37 @@ static struct recv_buf *sd_recv_rxfifo(struct adapter *padapter, u32 size) readsize = RND4(size); /* 3 1. alloc recvbuf */ - precvpriv = &padapter->recvpriv; - precvbuf = rtw_dequeue_recvbuf(&precvpriv->free_recv_buf_queue); - if (precvbuf == NULL) { + recv_priv = &adapter->recvpriv; + recvbuf = rtw_dequeue_recvbuf(&recv_priv->free_recv_buf_queue); + if (!recvbuf) { DBG_871X_LEVEL(_drv_err_, "%s: alloc recvbuf FAIL!\n", __func__); return NULL; } /* 3 2. alloc skb */ - if (precvbuf->pskb == NULL) { + if (!recvbuf->pskb) { SIZE_PTR tmpaddr = 0; SIZE_PTR alignment = 0; - precvbuf->pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ); + recvbuf->pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ); - if (precvbuf->pskb) { - precvbuf->pskb->dev = padapter->pnetdev; + if (recvbuf->pskb) { + recvbuf->pskb->dev = adapter->pnetdev; - tmpaddr = (SIZE_PTR)precvbuf->pskb->data; + tmpaddr = (SIZE_PTR)recvbuf->pskb->data; alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1); - skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment)); + skb_reserve(recvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment)); } - if (precvbuf->pskb == NULL) { + if (!recvbuf->pskb) { DBG_871X("%s: alloc_skb fail! read =%d\n", __func__, readsize); return NULL; } } /* 3 3. read data from rxfifo */ - preadbuf = precvbuf->pskb->data; - ret = sdio_read_port(&padapter->iopriv.intf, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf); + readbuf = recvbuf->pskb->data; + ret = sdio_read_port(&adapter->iopriv.intf, WLAN_RX0FF_DEVICE_ID, readsize, readbuf); if (ret == _FAIL) { RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("%s: read port FAIL!\n", __func__)); return NULL; @@ -1023,72 +990,72 @@ static struct recv_buf *sd_recv_rxfifo(struct adapter *padapter, u32 size) /* 3 4. init recvbuf */ - precvbuf->len = size; - precvbuf->phead = precvbuf->pskb->head; - precvbuf->pdata = precvbuf->pskb->data; - skb_set_tail_pointer(precvbuf->pskb, size); - precvbuf->ptail = skb_tail_pointer(precvbuf->pskb); - precvbuf->pend = skb_end_pointer(precvbuf->pskb); - - return precvbuf; + recvbuf->len = size; + recvbuf->phead = recvbuf->pskb->head; + recvbuf->pdata = recvbuf->pskb->data; + skb_set_tail_pointer(recvbuf->pskb, size); + recvbuf->ptail = skb_tail_pointer(recvbuf->pskb); + recvbuf->pend = skb_end_pointer(recvbuf->pskb); + + return recvbuf; } -static void sd_rxhandler(struct adapter *padapter, struct recv_buf *precvbuf) +static void sd_rxhandler(struct adapter *adapter, struct recv_buf *recvbuf) { - struct recv_priv *precvpriv; - struct __queue *ppending_queue; + struct recv_priv *recv_priv; + struct __queue *pending_queue; - precvpriv = &padapter->recvpriv; - ppending_queue = &precvpriv->recv_buf_pending_queue; + recv_priv = &adapter->recvpriv; + pending_queue = &recv_priv->recv_buf_pending_queue; /* 3 1. enqueue recvbuf */ - rtw_enqueue_recvbuf(precvbuf, ppending_queue); + rtw_enqueue_recvbuf(recvbuf, pending_queue); /* 3 2. schedule tasklet */ - tasklet_schedule(&precvpriv->recv_tasklet); + tasklet_schedule(&recv_priv->recv_tasklet); } -void sd_int_dpc(struct adapter *padapter) +void sd_int_dpc(struct adapter *adapter) { - struct hal_com_data *phal; + struct hal_com_data *hal; struct dvobj_priv *dvobj; - struct intf_hdl *pintfhdl = &padapter->iopriv.intf; + struct intf_hdl *intfhdl = &adapter->iopriv.intf; struct pwrctrl_priv *pwrctl; - phal = GET_HAL_DATA(padapter); - dvobj = adapter_to_dvobj(padapter); + hal = GET_HAL_DATA(adapter); + dvobj = adapter_to_dvobj(adapter); pwrctl = dvobj_to_pwrctl(dvobj); - if (phal->sdio_hisr & SDIO_HISR_AVAL) { + if (hal->sdio_hisr & SDIO_HISR_AVAL) { u8 freepage[4]; - _sdio_local_read(padapter, SDIO_REG_FREE_TXPG, 4, freepage); - up(&(padapter->xmitpriv.xmit_sema)); + _sdio_local_read(adapter, SDIO_REG_FREE_TXPG, 4, freepage); + up(&(adapter->xmitpriv.xmit_sema)); } - if (phal->sdio_hisr & SDIO_HISR_CPWM1) { + if (hal->sdio_hisr & SDIO_HISR_CPWM1) { struct reportpwrstate_parm report; u8 bcancelled; _cancel_timer(&(pwrctl->pwr_rpwm_timer), &bcancelled); - report.state = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HCPWM1_8723B); + report.state = SdioLocalCmd52Read1Byte(adapter, SDIO_REG_HCPWM1_8723B); - /* cpwm_int_hdl(padapter, &report); */ + /* cpwm_int_hdl(adapter, &report); */ _set_workitem(&(pwrctl->cpwm_event)); } - if (phal->sdio_hisr & SDIO_HISR_TXERR) { + if (hal->sdio_hisr & SDIO_HISR_TXERR) { u8 *status; u32 addr; status = rtw_malloc(4); if (status) { addr = REG_TXDMA_STATUS; - HalSdioGetCmdAddr8723BSdio(padapter, WLAN_IOREG_DEVICE_ID, addr, &addr); - _sd_read(pintfhdl, addr, 4, status); - _sd_write(pintfhdl, addr, 4, status); + HalSdioGetCmdAddr8723BSdio(adapter, WLAN_IOREG_DEVICE_ID, addr, &addr); + _sd_read(intfhdl, addr, 4, status); + _sd_write(intfhdl, addr, 4, status); DBG_8192C("%s: SDIO_HISR_TXERR (0x%08x)\n", __func__, le32_to_cpu(*(u32 *)status)); kfree(status); } else { @@ -1096,71 +1063,71 @@ void sd_int_dpc(struct adapter *padapter) } } - if (phal->sdio_hisr & SDIO_HISR_TXBCNOK) { + if (hal->sdio_hisr & SDIO_HISR_TXBCNOK) { DBG_8192C("%s: SDIO_HISR_TXBCNOK\n", __func__); } - if (phal->sdio_hisr & SDIO_HISR_TXBCNERR) { + if (hal->sdio_hisr & SDIO_HISR_TXBCNERR) { DBG_8192C("%s: SDIO_HISR_TXBCNERR\n", __func__); } #ifndef CONFIG_C2H_PACKET_EN - if (phal->sdio_hisr & SDIO_HISR_C2HCMD) { + if (hal->sdio_hisr & SDIO_HISR_C2HCMD) { struct c2h_evt_hdr_88xx *c2h_evt; DBG_8192C("%s: C2H Command\n", __func__); c2h_evt = rtw_zmalloc(16); if (c2h_evt != NULL) { - if (rtw_hal_c2h_evt_read(padapter, (u8 *)c2h_evt) == _SUCCESS) { + if (rtw_hal_c2h_evt_read(adapter, (u8 *)c2h_evt) == _SUCCESS) { if (c2h_id_filter_ccx_8723b((u8 *)c2h_evt)) { /* Handle CCX report here */ - rtw_hal_c2h_handler(padapter, (u8 *)c2h_evt); + rtw_hal_c2h_handler(adapter, (u8 *)c2h_evt); kfree((u8 *)c2h_evt); } else { - rtw_c2h_wk_cmd(padapter, (u8 *)c2h_evt); + rtw_c2h_wk_cmd(adapter, (u8 *)c2h_evt); } } } else { /* Error handling for malloc fail */ - if (rtw_cbuf_push(padapter->evtpriv.c2h_queue, NULL) != _SUCCESS) + if (rtw_cbuf_push(adapter->evtpriv.c2h_queue, NULL) != _SUCCESS) DBG_871X("%s rtw_cbuf_push fail\n", __func__); - _set_workitem(&padapter->evtpriv.c2h_wk); + _set_workitem(&adapter->evtpriv.c2h_wk); } } #endif - if (phal->sdio_hisr & SDIO_HISR_RXFOVW) { + if (hal->sdio_hisr & SDIO_HISR_RXFOVW) { DBG_8192C("%s: Rx Overflow\n", __func__); } - if (phal->sdio_hisr & SDIO_HISR_RXERR) { + if (hal->sdio_hisr & SDIO_HISR_RXERR) { DBG_8192C("%s: Rx Error\n", __func__); } - if (phal->sdio_hisr & SDIO_HISR_RX_REQUEST) { - struct recv_buf *precvbuf; + if (hal->sdio_hisr & SDIO_HISR_RX_REQUEST) { + struct recv_buf *recvbuf; int alloc_fail_time = 0; u32 hisr; -/* DBG_8192C("%s: RX Request, size =%d\n", __func__, phal->SdioRxFIFOSize); */ - phal->sdio_hisr ^= SDIO_HISR_RX_REQUEST; +/* DBG_8192C("%s: RX Request, size =%d\n", __func__, hal->SdioRxFIFOSize); */ + hal->sdio_hisr ^= SDIO_HISR_RX_REQUEST; do { - phal->SdioRxFIFOSize = SdioLocalCmd52Read2Byte(padapter, SDIO_REG_RX0_REQ_LEN); - if (phal->SdioRxFIFOSize != 0) { - precvbuf = sd_recv_rxfifo(padapter, phal->SdioRxFIFOSize); - if (precvbuf) - sd_rxhandler(padapter, precvbuf); + hal->SdioRxFIFOSize = SdioLocalCmd52Read2Byte(adapter, SDIO_REG_RX0_REQ_LEN); + if (hal->SdioRxFIFOSize != 0) { + recvbuf = sd_recv_rxfifo(adapter, hal->SdioRxFIFOSize); + if (recvbuf) + sd_rxhandler(adapter, recvbuf); else { alloc_fail_time++; - DBG_871X("precvbuf is Null for %d times because alloc memory failed\n", alloc_fail_time); + DBG_871X("recvbuf is Null for %d times because alloc memory failed\n", alloc_fail_time); if (alloc_fail_time >= 10) break; } - phal->SdioRxFIFOSize = 0; + hal->SdioRxFIFOSize = 0; } else break; hisr = 0; - ReadInterrupt8723BSdio(padapter, &hisr); + ReadInterrupt8723BSdio(adapter, &hisr); hisr &= SDIO_HISR_RX_REQUEST; if (!hisr) break; @@ -1172,38 +1139,37 @@ void sd_int_dpc(struct adapter *padapter) } } -void sd_int_hdl(struct adapter *padapter) +void sd_int_hdl(struct adapter *adapter) { - struct hal_com_data *phal; + struct hal_com_data *hal; if ( - (padapter->bDriverStopped == true) || - (padapter->bSurpriseRemoved == true) + (adapter->bDriverStopped) || (adapter->bSurpriseRemoved) ) return; - phal = GET_HAL_DATA(padapter); + hal = GET_HAL_DATA(adapter); - phal->sdio_hisr = 0; - ReadInterrupt8723BSdio(padapter, &phal->sdio_hisr); + hal->sdio_hisr = 0; + ReadInterrupt8723BSdio(adapter, &hal->sdio_hisr); - if (phal->sdio_hisr & phal->sdio_himr) { + if (hal->sdio_hisr & hal->sdio_himr) { u32 v32; - phal->sdio_hisr &= phal->sdio_himr; + hal->sdio_hisr &= hal->sdio_himr; /* clear HISR */ - v32 = phal->sdio_hisr & MASK_SDIO_HISR_CLEAR; + v32 = hal->sdio_hisr & MASK_SDIO_HISR_CLEAR; if (v32) { - SdioLocalCmd52Write4Byte(padapter, SDIO_REG_HISR, v32); + SdioLocalCmd52Write4Byte(adapter, SDIO_REG_HISR, v32); } - sd_int_dpc(padapter); + sd_int_dpc(adapter); } else { RT_TRACE(_module_hci_ops_c_, _drv_err_, ("%s: HISR(0x%08x) and HIMR(0x%08x) not match!\n", - __func__, phal->sdio_hisr, phal->sdio_himr)); + __func__, hal->sdio_hisr, hal->sdio_himr)); } } @@ -1217,27 +1183,27 @@ void sd_int_hdl(struct adapter *padapter) /* */ /* Created by Roger, 2011.01.28. */ /* */ -u8 HalQueryTxBufferStatus8723BSdio(struct adapter *padapter) +u8 HalQueryTxBufferStatus8723BSdio(struct adapter *adapter) { - struct hal_com_data *phal; - u32 NumOfFreePage; - /* _irqL irql; */ + struct hal_com_data *hal; + u32 numof_free_page; + /* _irql irql; */ - phal = GET_HAL_DATA(padapter); + hal = GET_HAL_DATA(adapter); - NumOfFreePage = SdioLocalCmd53Read4Byte(padapter, SDIO_REG_FREE_TXPG); + numof_free_page = SdioLocalCmd53Read4Byte(adapter, SDIO_REG_FREE_TXPG); /* spin_lock_bh(&phal->SdioTxFIFOFreePageLock); */ - memcpy(phal->SdioTxFIFOFreePage, &NumOfFreePage, 4); + memcpy(hal->SdioTxFIFOFreePage, &numof_free_page, 4); RT_TRACE(_module_hci_ops_c_, _drv_notice_, ("%s: Free page for HIQ(%#x), MIDQ(%#x), LOWQ(%#x), PUBQ(%#x)\n", __func__, - phal->SdioTxFIFOFreePage[HI_QUEUE_IDX], - phal->SdioTxFIFOFreePage[MID_QUEUE_IDX], - phal->SdioTxFIFOFreePage[LOW_QUEUE_IDX], - phal->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX])); - /* spin_unlock_bh(&phal->SdioTxFIFOFreePageLock); */ + hal->SdioTxFIFOFreePage[HI_QUEUE_IDX], + hal->SdioTxFIFOFreePage[MID_QUEUE_IDX], + hal->SdioTxFIFOFreePage[LOW_QUEUE_IDX], + hal->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX])); + /* spin_unlock_bh(&hal->SdioTxFIFOFreePageLock); */ return true; } @@ -1246,19 +1212,19 @@ u8 HalQueryTxBufferStatus8723BSdio(struct adapter *padapter) /* Description: */ /* Query SDIO Local register to get the current number of TX OQT Free Space. */ /* */ -u8 HalQueryTxOQTBufferStatus8723BSdio(struct adapter *padapter) +u8 HalQueryTxOQTBufferStatus8723BSdio(struct adapter *adapter) { - struct hal_com_data *pHalData = GET_HAL_DATA(padapter); + struct hal_com_data *haldata = GET_HAL_DATA(adapter); - pHalData->SdioTxOQTFreeSpace = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_OQT_FREE_PG); + haldata->SdioTxOQTFreeSpace = SdioLocalCmd52Read1Byte(adapter, SDIO_REG_OQT_FREE_PG); return true; } #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN) -u8 RecvOnePkt(struct adapter *padapter, u32 size) +u8 RecvOnePkt(struct adapter *adapter, u32 size) { - struct recv_buf *precvbuf; - struct dvobj_priv *psddev; + struct recv_buf *recvbuf; + struct dvobj_priv *sddev; PSDIO_DATA psdio_data; struct sdio_func *func; @@ -1266,22 +1232,22 @@ u8 RecvOnePkt(struct adapter *padapter, u32 size) DBG_871X("+%s: size: %d+\n", __func__, size); - if (padapter == NULL) { - DBG_871X(KERN_ERR "%s: padapter is NULL!\n", __func__); + if (!adapter) { + DBG_871X(KERN_ERR "%s: adapter is NULL!\n", __func__); return false; } - psddev = adapter_to_dvobj(padapter); - psdio_data = &psddev->intf_data; + sddev = adapter_to_dvobj(adapter); + psdio_data = &sddev->intf_data; func = psdio_data->func; if (size) { sdio_claim_host(func); - precvbuf = sd_recv_rxfifo(padapter, size); + recvbuf = sd_recv_rxfifo(adapter, size); - if (precvbuf) { + if (recvbuf) { /* printk("Completed Recv One Pkt.\n"); */ - sd_rxhandler(padapter, precvbuf); + sd_rxhandler(adapter, recvbuf); res = true; } else { res = false; diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c index 3fca0c2d4c8d..cc18d0ad7d7b 100644 --- a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c +++ b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c @@ -371,7 +371,7 @@ static char *translate_scan(struct adapter *padapter, u8 *wpsie_ptr = NULL; uint wps_ielen = 0; - u8 *ie_ptr = pnetwork->network.IEs + ie_offset; + u8 *ie_ptr; total_ielen = pnetwork->network.IELength - ie_offset; if (pnetwork->network.Reserved[0] == 2) { /* Probe Request */ @@ -967,7 +967,7 @@ static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a, break; default : - ret = -EINVAL;; + ret = -EINVAL; RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_, ("\n Mode: %s is not supported \n", iw_operation_mode[wrqu->mode])); goto exit; } diff --git a/drivers/staging/rtlwifi/Kconfig b/drivers/staging/rtlwifi/Kconfig index cb3a29ae764b..b6b03950987b 100644 --- a/drivers/staging/rtlwifi/Kconfig +++ b/drivers/staging/rtlwifi/Kconfig @@ -6,16 +6,6 @@ config R8822BE This is the staging driver for Realtek RTL8822BE 802.11ac PCIe wireless network adapters. -config RTLHALMAC_ST - tristate - depends on R8822BE - default m - -config RTLPHYDM_ST - tristate - depends on R8822BE - default m - config RTLWIFI_DEBUG_ST boolean depends on R8822BE diff --git a/drivers/staging/rtlwifi/btcoexist/halbtcoutsrc.c b/drivers/staging/rtlwifi/btcoexist/halbtcoutsrc.c index 52620b72cfa9..493011a54e64 100644 --- a/drivers/staging/rtlwifi/btcoexist/halbtcoutsrc.c +++ b/drivers/staging/rtlwifi/btcoexist/halbtcoutsrc.c @@ -800,7 +800,7 @@ static void halbtc_display_wifi_status(struct btc_coexist *btcoexist, u32 wifi_link_status = 0x0; bool bt_hs_on = false, under_ips = false, under_lps = false; bool low_power = false, dc_mode = false; - u8 wifi_chnl = 0, wifi_hs_chnl = 0, fw_ps_state; + u8 wifi_chnl = 0, wifi_hs_chnl = 0; u8 ap_num = 0; wifi_link_status = halbtc_get_wifi_link_status(btcoexist); @@ -856,7 +856,6 @@ static void halbtc_display_wifi_status(struct btc_coexist *btcoexist, dc_mode = true; /*TODO*/ under_ips = rtlpriv->psc.inactive_pwrstate == ERFOFF ? 1 : 0; under_lps = rtlpriv->psc.dot11_psmode == EACTIVE ? 0 : 1; - fw_ps_state = 0; low_power = 0; /*TODO*/ seq_printf(m, "\n %-35s = %s%s%s%s", "Power Status", @@ -1644,26 +1643,9 @@ void exhalbtc_rf_status_notify(struct btc_coexist *btcoexist, u8 type) void exhalbtc_stack_operation_notify(struct btc_coexist *btcoexist, u8 type) { - u8 stack_op_type; - if (!halbtc_is_bt_coexist_available(btcoexist)) return; btcoexist->statistics.cnt_stack_operation_notify++; - if (btcoexist->manual_control) - return; - - if ((type == HCI_BT_OP_INQUIRY_START) || - (type == HCI_BT_OP_PAGING_START) || - (type == HCI_BT_OP_PAIRING_START)) { - stack_op_type = BTC_STACK_OP_INQ_PAGE_PAIR_START; - } else if ((type == HCI_BT_OP_INQUIRY_FINISH) || - (type == HCI_BT_OP_PAGING_SUCCESS) || - (type == HCI_BT_OP_PAGING_UNSUCCESS) || - (type == HCI_BT_OP_PAIRING_FINISH)) { - stack_op_type = BTC_STACK_OP_INQ_PAGE_PAIR_FINISH; - } else { - stack_op_type = BTC_STACK_OP_NONE; - } } void exhalbtc_halt_notify(struct btc_coexist *btcoexist) diff --git a/drivers/staging/rtlwifi/cam.c b/drivers/staging/rtlwifi/cam.c index 9c8c907cb48e..ca1c9e36d976 100644 --- a/drivers/staging/rtlwifi/cam.c +++ b/drivers/staging/rtlwifi/cam.c @@ -181,7 +181,7 @@ void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index) u32 ul_command; u32 ul_content; - u32 ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES]; + u32 ul_enc_algo; switch (rtlpriv->sec.pairwise_enc_algorithm) { case WEP40_ENCRYPTION: @@ -221,7 +221,7 @@ void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index) u32 ul_command; u32 ul_content; - u32 ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES]; + u32 ul_encalgo; u8 entry_i; switch (rtlpriv->sec.pairwise_enc_algorithm) { diff --git a/drivers/staging/rtlwifi/core.c b/drivers/staging/rtlwifi/core.c index b00e51df984f..3ec039498208 100644 --- a/drivers/staging/rtlwifi/core.c +++ b/drivers/staging/rtlwifi/core.c @@ -509,15 +509,13 @@ static int rtl_op_suspend(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtlpriv); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - struct timeval ts; RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "\n"); if (WARN_ON(!wow)) return -EINVAL; /* to resolve s4 can not wake up*/ - do_gettimeofday(&ts); - rtlhal->last_suspend_sec = ts.tv_sec; + rtlhal->last_suspend_sec = ktime_get_real_seconds(); if ((ppsc->wo_wlan_mode & WAKE_ON_PATTERN_MATCH) && wow->n_patterns) _rtl_add_wowlan_patterns(hw, wow); @@ -536,7 +534,6 @@ static int rtl_op_resume(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtlpriv); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct timeval ts; RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "\n"); rtlhal->driver_is_goingto_unload = false; @@ -544,8 +541,7 @@ static int rtl_op_resume(struct ieee80211_hw *hw) rtlhal->wake_from_pnp_sleep = true; /* to resovle s4 can not wake up*/ - do_gettimeofday(&ts); - if (ts.tv_sec - rtlhal->last_suspend_sec < 5) + if (ktime_get_real_seconds() - rtlhal->last_suspend_sec < 5) return -1; rtl_op_start(hw); @@ -1820,7 +1816,7 @@ bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, u8 faversion, u8 interface_type, struct wlan_pwr_cfg pwrcfgcmd[]) { - struct wlan_pwr_cfg cfg_cmd = {0}; + struct wlan_pwr_cfg cfg_cmd; bool polling_bit = false; u32 ary_idx = 0; u8 value = 0; diff --git a/drivers/staging/rtlwifi/rtl8822be/fw.c b/drivers/staging/rtlwifi/rtl8822be/fw.c index f45487122517..483ea85943c3 100644 --- a/drivers/staging/rtlwifi/rtl8822be/fw.c +++ b/drivers/staging/rtlwifi/rtl8822be/fw.c @@ -464,6 +464,8 @@ bool rtl8822b_halmac_cb_write_data_rsvd_page(struct rtl_priv *rtlpriv, u8 *buf, int count; skb = dev_alloc_skb(size); + if (!skb) + return false; memcpy((u8 *)skb_put(skb, size), buf, size); if (!_rtl8822be_send_bcn_or_cmd_packet(rtlpriv->hw, skb, BEACON_QUEUE)) diff --git a/drivers/staging/rtlwifi/wifi.h b/drivers/staging/rtlwifi/wifi.h index eb91c130b245..ca0243fa2e66 100644 --- a/drivers/staging/rtlwifi/wifi.h +++ b/drivers/staging/rtlwifi/wifi.h @@ -1670,7 +1670,7 @@ struct rtl_hal { bool enter_pnp_sleep; bool wake_from_pnp_sleep; bool wow_enabled; - __kernel_time_t last_suspend_sec; + time64_t last_suspend_sec; u32 wowlan_fwsize; u8 *wowlan_firmware; diff --git a/drivers/staging/rts5208/ms.c b/drivers/staging/rts5208/ms.c index 7cdce87f3051..821256b95e22 100644 --- a/drivers/staging/rts5208/ms.c +++ b/drivers/staging/rts5208/ms.c @@ -2821,6 +2821,7 @@ BUILD_FAIL: int reset_ms_card(struct rtsx_chip *chip) { struct ms_info *ms_card = &chip->ms_card; + int seg_no = ms_card->total_block / 512 - 1; int retval; memset(ms_card, 0, sizeof(struct ms_info)); @@ -2863,7 +2864,7 @@ int reset_ms_card(struct rtsx_chip *chip) /* Build table for the last segment, * to check if L2P table block exists, erasing it */ - retval = ms_build_l2p_tbl(chip, ms_card->total_block / 512 - 1); + retval = ms_build_l2p_tbl(chip, seg_no); if (retval != STATUS_SUCCESS) { rtsx_trace(chip); return STATUS_FAIL; diff --git a/drivers/staging/rts5208/rtsx.c b/drivers/staging/rts5208/rtsx.c index 89e2cfe7d1cc..70e0b8623110 100644 --- a/drivers/staging/rts5208/rtsx.c +++ b/drivers/staging/rts5208/rtsx.c @@ -275,23 +275,6 @@ static int rtsx_acquire_irq(struct rtsx_dev *dev) return 0; } -int rtsx_read_pci_cfg_byte(u8 bus, u8 dev, u8 func, u8 offset, u8 *val) -{ - struct pci_dev *pdev; - u8 data; - u8 devfn = (dev << 3) | func; - - pdev = pci_get_bus_and_slot(bus, devfn); - if (!pdev) - return -1; - - pci_read_config_byte(pdev, offset, &data); - if (val) - *val = data; - - return 0; -} - #ifdef CONFIG_PM /* * power management diff --git a/drivers/staging/rts5208/rtsx.h b/drivers/staging/rts5208/rtsx.h index 575e5734f2a5..62e467c5a6d7 100644 --- a/drivers/staging/rts5208/rtsx.h +++ b/drivers/staging/rts5208/rtsx.h @@ -174,8 +174,6 @@ static inline void get_current_time(u8 *timeval_buf, int buf_len) /* struct scsi_cmnd transfer buffer access utilities */ enum xfer_buf_dir {TO_XFER_BUF, FROM_XFER_BUF}; -int rtsx_read_pci_cfg_byte(u8 bus, u8 dev, u8 func, u8 offset, u8 *val); - #define _MSG_TRACE #include "trace.h" diff --git a/drivers/staging/rts5208/sd.h b/drivers/staging/rts5208/sd.h index 55764e16b93a..900be444acf9 100644 --- a/drivers/staging/rts5208/sd.h +++ b/drivers/staging/rts5208/sd.h @@ -118,7 +118,7 @@ #define SUPPORT_MAX_POWER_PERMANCE 0x10000000 #define SUPPORT_1V8 0x01000000 -#define SWTICH_NO_ERR 0x00 +#define SWITCH_NO_ERR 0x00 #define CARD_NOT_EXIST 0x01 #define SPEC_NOT_SUPPORT 0x02 #define CHECK_MODE_ERR 0x03 diff --git a/drivers/staging/sm750fb/TODO b/drivers/staging/sm750fb/TODO index a3a877d90066..f710ab15abfe 100644 --- a/drivers/staging/sm750fb/TODO +++ b/drivers/staging/sm750fb/TODO @@ -6,8 +6,8 @@ TODO: - check on hardware effects of removal of USE_HW_I2C and USE_DVICHIP (these two are supposed to be sample code which is given here if someone wants to use those functionalities) -- move it to drivers/video/fbdev -- modify the code for drm framework +- must be ported to the atomic kms framework in the drm subsystem (which will + give you a basic fbdev driver for free) Please send any patches to Greg Kroah-Hartman <greg@kroah.com> diff --git a/drivers/staging/sm750fb/ddk750_sii164.c b/drivers/staging/sm750fb/ddk750_sii164.c index c787a74c4f9c..4b34a083f5cf 100644 --- a/drivers/staging/sm750fb/ddk750_sii164.c +++ b/drivers/staging/sm750fb/ddk750_sii164.c @@ -62,8 +62,6 @@ unsigned short sii164GetDeviceID(void) return deviceID; } - - /* DVI.C will handle all SiI164 chip stuffs and try it best to make code minimal and useful */ /* @@ -239,10 +237,6 @@ long sii164InitChip(unsigned char edgeSelect, return -1; } - - - - /* below sii164 function is not necessary */ #ifdef SII164_FULL_FUNCTIONS @@ -402,5 +396,3 @@ void sii164ClearInterrupt(void) #endif #endif - - diff --git a/drivers/staging/sm750fb/ddk750_sii164.h b/drivers/staging/sm750fb/ddk750_sii164.h index 2e9a88cd6af3..862e7bf27353 100644 --- a/drivers/staging/sm750fb/ddk750_sii164.h +++ b/drivers/staging/sm750fb/ddk750_sii164.h @@ -12,7 +12,6 @@ enum sii164_hot_plug_mode { SII164_HOTPLUG_USE_HTPLG /* Use Hot Plug detect bit. */ }; - /* Silicon Image SiI164 chip prototype */ long sii164InitChip(unsigned char edgeSelect, unsigned char busSelect, @@ -28,7 +27,6 @@ long sii164InitChip(unsigned char edgeSelect, unsigned short sii164GetVendorID(void); unsigned short sii164GetDeviceID(void); - #ifdef SII164_FULL_FUNCTIONS void sii164ResetChip(void); char *sii164GetChipString(void); diff --git a/drivers/staging/sm750fb/sm750_hw.c b/drivers/staging/sm750fb/sm750_hw.c index ffd114a6d09b..a8c79864ee4b 100644 --- a/drivers/staging/sm750fb/sm750_hw.c +++ b/drivers/staging/sm750fb/sm750_hw.c @@ -185,29 +185,29 @@ int hw_sm750_output_setMode(struct lynxfb_output *output, struct fb_fix_screeninfo *fix) { int ret; - disp_output_t dispSet; + disp_output_t disp_set; int channel; ret = 0; - dispSet = 0; + disp_set = 0; channel = *output->channel; if (sm750_get_chip_type() != SM750LE) { if (channel == sm750_primary) { pr_info("primary channel\n"); if (output->paths & sm750_panel) - dispSet |= do_LCD1_PRI; + disp_set |= do_LCD1_PRI; if (output->paths & sm750_crt) - dispSet |= do_CRT_PRI; + disp_set |= do_CRT_PRI; } else { pr_info("secondary channel\n"); if (output->paths & sm750_panel) - dispSet |= do_LCD1_SEC; + disp_set |= do_LCD1_SEC; if (output->paths & sm750_crt) - dispSet |= do_CRT_SEC; + disp_set |= do_CRT_SEC; } - ddk750_setLogicalDispOut(dispSet); + ddk750_setLogicalDispOut(disp_set); } else { /* just open DISPLAY_CONTROL_750LE register bit 3:0 */ u32 reg; diff --git a/drivers/staging/speakup/buffers.c b/drivers/staging/speakup/buffers.c index 6137fa83c609..461f131644a2 100644 --- a/drivers/staging/speakup/buffers.c +++ b/drivers/staging/speakup/buffers.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include <linux/console.h> #include <linux/types.h> #include <linux/wait.h> diff --git a/drivers/staging/speakup/fakekey.c b/drivers/staging/speakup/fakekey.c index 294c74b47224..cd029968462f 100644 --- a/drivers/staging/speakup/fakekey.c +++ b/drivers/staging/speakup/fakekey.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* fakekey.c * Functions for simulating keypresses. * * Copyright (C) 2010 the Speakup Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/types.h> #include <linux/slab.h> diff --git a/drivers/staging/speakup/keyhelp.c b/drivers/staging/speakup/keyhelp.c index 4e6e5daba50c..5f1bda37f86d 100644 --- a/drivers/staging/speakup/keyhelp.c +++ b/drivers/staging/speakup/keyhelp.c @@ -1,19 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* speakup_keyhelp.c * help module for speakup * *written by David Borowski. * * Copyright (C) 2003 David Borowski. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/keyboard.h> diff --git a/drivers/staging/speakup/kobjects.c b/drivers/staging/speakup/kobjects.c index ca85476e3ff7..f1f90222186b 100644 --- a/drivers/staging/speakup/kobjects.c +++ b/drivers/staging/speakup/kobjects.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Speakup kobject implementation * diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c index aae868509e13..cf1259059776 100644 --- a/drivers/staging/speakup/main.c +++ b/drivers/staging/speakup/main.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* speakup.c * review functions for the speakup screen review package. * originally written by: Kirk Reiser and Andy Berdan. @@ -6,16 +7,6 @@ * ** Copyright (C) 1998 Kirk Reiser. * Copyright (C) 2003 David Borowski. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/kernel.h> diff --git a/drivers/staging/speakup/selection.c b/drivers/staging/speakup/selection.c index 66061b5c3427..0ed1fefee0e9 100644 --- a/drivers/staging/speakup/selection.c +++ b/drivers/staging/speakup/selection.c @@ -64,13 +64,8 @@ int speakup_set_selection(struct tty_struct *tty) ps = spk_ys * vc->vc_size_row + (spk_xs << 1); pe = spk_ye * vc->vc_size_row + (spk_xe << 1); - if (ps > pe) { - /* make sel_start <= sel_end */ - int tmp = ps; - - ps = pe; - pe = tmp; - } + if (ps > pe) /* make sel_start <= sel_end */ + swap(ps, pe); if (spk_sel_cons != vc_cons[fg_console].d) { speakup_clear_selection(); diff --git a/drivers/staging/speakup/serialio.c b/drivers/staging/speakup/serialio.c index 9cfc8142a318..177a2988641c 100644 --- a/drivers/staging/speakup/serialio.c +++ b/drivers/staging/speakup/serialio.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include <linux/interrupt.h> #include <linux/ioport.h> diff --git a/drivers/staging/speakup/speakup_acntpc.c b/drivers/staging/speakup/speakup_acntpc.c index a041441766aa..28519754b2f0 100644 --- a/drivers/staging/speakup/speakup_acntpc.c +++ b/drivers/staging/speakup/speakup_acntpc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * written by: Kirk Reiser <kirk@braille.uwo.ca> * this version considerably modified by David Borowski, david575@rogers.com @@ -5,15 +6,6 @@ * Copyright (C) 1998-99 Kirk Reiser. * Copyright (C) 2003 David Borowski. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. * this code is specificly written as a driver for the speakup screenreview * package and is not a general device driver. * This driver is for the Aicom Acent PC internal synthesizer. diff --git a/drivers/staging/speakup/speakup_acntsa.c b/drivers/staging/speakup/speakup_acntsa.c index 43315849b7b6..3a863dc61286 100644 --- a/drivers/staging/speakup/speakup_acntsa.c +++ b/drivers/staging/speakup/speakup_acntsa.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * originally written by: Kirk Reiser <kirk@braille.uwo.ca> * this version considerably modified by David Borowski, david575@rogers.com @@ -5,16 +6,6 @@ * Copyright (C) 1998-99 Kirk Reiser. * Copyright (C) 2003 David Borowski. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * this code is specificly written as a driver for the speakup screenreview * package and is not a general device driver. */ diff --git a/drivers/staging/speakup/speakup_apollo.c b/drivers/staging/speakup/speakup_apollo.c index dcf0c3b59fdd..0877b4044c28 100644 --- a/drivers/staging/speakup/speakup_apollo.c +++ b/drivers/staging/speakup/speakup_apollo.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * originally written by: Kirk Reiser <kirk@braille.uwo.ca> * this version considerably modified by David Borowski, david575@rogers.com @@ -5,16 +6,6 @@ * Copyright (C) 1998-99 Kirk Reiser. * Copyright (C) 2003 David Borowski. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * this code is specificly written as a driver for the speakup screenreview * package and is not a general device driver. */ diff --git a/drivers/staging/speakup/speakup_audptr.c b/drivers/staging/speakup/speakup_audptr.c index 45b5721441ba..e6a6a9665d8f 100644 --- a/drivers/staging/speakup/speakup_audptr.c +++ b/drivers/staging/speakup/speakup_audptr.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * originally written by: Kirk Reiser <kirk@braille.uwo.ca> * this version considerably modified by David Borowski, david575@rogers.com @@ -5,16 +6,6 @@ * Copyright (C) 1998-99 Kirk Reiser. * Copyright (C) 2003 David Borowski. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * specificly written as a driver for the speakup screenreview * s not a general device driver. */ diff --git a/drivers/staging/speakup/speakup_bns.c b/drivers/staging/speakup/speakup_bns.c index 402b0fbfb94d..76dfa3f7c058 100644 --- a/drivers/staging/speakup/speakup_bns.c +++ b/drivers/staging/speakup/speakup_bns.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * originally written by: Kirk Reiser <kirk@braille.uwo.ca> * this version considerably modified by David Borowski, david575@rogers.com @@ -5,16 +6,6 @@ * Copyright (C) 1998-99 Kirk Reiser. * Copyright (C) 2003 David Borowski. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * this code is specificly written as a driver for the speakup screenreview * package and is not a general device driver. */ diff --git a/drivers/staging/speakup/speakup_decext.c b/drivers/staging/speakup/speakup_decext.c index 4310c2c276c4..3741c0fcf5bb 100644 --- a/drivers/staging/speakup/speakup_decext.c +++ b/drivers/staging/speakup/speakup_decext.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * originally written by: Kirk Reiser <kirk@braille.uwo.ca> * this version considerably modified by David Borowski, david575@rogers.com @@ -5,16 +6,6 @@ * Copyright (C) 1998-99 Kirk Reiser. * Copyright (C) 2003 David Borowski. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * specificly written as a driver for the speakup screenreview * s not a general device driver. */ diff --git a/drivers/staging/speakup/speakup_decpc.c b/drivers/staging/speakup/speakup_decpc.c index 7a8df7dc1e38..303f393d3f2f 100644 --- a/drivers/staging/speakup/speakup_decpc.c +++ b/drivers/staging/speakup/speakup_decpc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * This is the DECtalk PC speakup driver * @@ -14,16 +15,6 @@ * Copyright (c) 2003 David Borowski <david575@golden.net> * * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/jiffies.h> #include <linux/sched.h> diff --git a/drivers/staging/speakup/speakup_dectlk.c b/drivers/staging/speakup/speakup_dectlk.c index 5d6a861c9b1e..2ea22a2eb5f9 100644 --- a/drivers/staging/speakup/speakup_dectlk.c +++ b/drivers/staging/speakup/speakup_dectlk.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * originally written by: Kirk Reiser <kirk@braille.uwo.ca> * this version considerably modified by David Borowski, david575@rogers.com @@ -5,16 +6,6 @@ * Copyright (C) 1998-99 Kirk Reiser. * Copyright (C) 2003 David Borowski. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * specificly written as a driver for the speakup screenreview * s not a general device driver. */ diff --git a/drivers/staging/speakup/speakup_dtlk.c b/drivers/staging/speakup/speakup_dtlk.c index 8999e3eb5c26..f8cb83c9b82e 100644 --- a/drivers/staging/speakup/speakup_dtlk.c +++ b/drivers/staging/speakup/speakup_dtlk.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * originally written by: Kirk Reiser <kirk@braille.uwo.ca> * this version considerably modified by David Borowski, david575@rogers.com @@ -5,16 +6,6 @@ * Copyright (C) 1998-99 Kirk Reiser. * Copyright (C) 2003 David Borowski. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * specificly written as a driver for the speakup screenreview * package it's not a general device driver. * This driver is for the RC Systems DoubleTalk PC internal synthesizer. diff --git a/drivers/staging/speakup/speakup_dummy.c b/drivers/staging/speakup/speakup_dummy.c index ea3b2911cab9..a30d60450bd5 100644 --- a/drivers/staging/speakup/speakup_dummy.c +++ b/drivers/staging/speakup/speakup_dummy.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * originally written by: Kirk Reiser <kirk@braille.uwo.ca> * this version considerably modified by David Borowski, david575@rogers.com @@ -7,16 +8,6 @@ * Copyright (C) 2003 David Borowski. * Copyright (C) 2007 Samuel Thibault. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * specificly written as a driver for the speakup screenreview * s not a general device driver. */ diff --git a/drivers/staging/speakup/speakup_keypc.c b/drivers/staging/speakup/speakup_keypc.c index d3203f8fc3d0..de76183932e1 100644 --- a/drivers/staging/speakup/speakup_keypc.c +++ b/drivers/staging/speakup/speakup_keypc.c @@ -1,18 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * written by David Borowski * * Copyright (C) 2003 David Borowski. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * specificly written as a driver for the speakup screenreview * package it's not a general device driver. * This driver is for the Keynote Gold internal synthesizer. diff --git a/drivers/staging/speakup/speakup_ltlk.c b/drivers/staging/speakup/speakup_ltlk.c index 95efaab73813..3c59519a871f 100644 --- a/drivers/staging/speakup/speakup_ltlk.c +++ b/drivers/staging/speakup/speakup_ltlk.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * originally written by: Kirk Reiser <kirk@braille.uwo.ca> * this version considerably modified by David Borowski, david575@rogers.com @@ -5,16 +6,6 @@ * Copyright (C) 1998-99 Kirk Reiser. * Copyright (C) 2003 David Borowski. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * specificly written as a driver for the speakup screenreview * s not a general device driver. */ diff --git a/drivers/staging/speakup/speakup_soft.c b/drivers/staging/speakup/speakup_soft.c index 585c6aa124cd..0e74d09e18ea 100644 --- a/drivers/staging/speakup/speakup_soft.c +++ b/drivers/staging/speakup/speakup_soft.c @@ -1,20 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* speakup_soft.c - speakup driver to register and make available * a user space device for software synthesizers. written by: Kirk * Reiser <kirk@braille.uwo.ca> * * Copyright (C) 2003 Kirk Reiser. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * this code is specificly written as a driver for the speakup screenreview * package and is not a general device driver. */ diff --git a/drivers/staging/speakup/speakup_spkout.c b/drivers/staging/speakup/speakup_spkout.c index 1037aa0d085a..6e933bf1de2e 100644 --- a/drivers/staging/speakup/speakup_spkout.c +++ b/drivers/staging/speakup/speakup_spkout.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * originally written by: Kirk Reiser <kirk@braille.uwo.ca> * this version considerably modified by David Borowski, david575@rogers.com @@ -5,16 +6,6 @@ * Copyright (C) 1998-99 Kirk Reiser. * Copyright (C) 2003 David Borowski. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * specificly written as a driver for the speakup screenreview * s not a general device driver. */ diff --git a/drivers/staging/speakup/speakup_txprt.c b/drivers/staging/speakup/speakup_txprt.c index e160034e4a68..a7326f226a5e 100644 --- a/drivers/staging/speakup/speakup_txprt.c +++ b/drivers/staging/speakup/speakup_txprt.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * originally written by: Kirk Reiser <kirk@braille.uwo.ca> * this version considerably modified by David Borowski, david575@rogers.com @@ -5,16 +6,6 @@ * Copyright (C) 1998-99 Kirk Reiser. * Copyright (C) 2003 David Borowski. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * specificly written as a driver for the speakup screenreview * s not a general device driver. */ diff --git a/drivers/staging/speakup/spk_priv.h b/drivers/staging/speakup/spk_priv.h index 046040ac074c..00430437eb4c 100644 --- a/drivers/staging/speakup/spk_priv.h +++ b/drivers/staging/speakup/spk_priv.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* spk_priv.h * review functions for the speakup screen review package. * originally written by: Kirk Reiser and Andy Berdan. @@ -6,16 +7,6 @@ * * Copyright (C) 1998 Kirk Reiser. * Copyright (C) 2003 David Borowski. - - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _SPEAKUP_PRIVATE_H #define _SPEAKUP_PRIVATE_H diff --git a/drivers/staging/speakup/spk_priv_keyinfo.h b/drivers/staging/speakup/spk_priv_keyinfo.h index c95b68ebd8e7..cc99fcd1bc6e 100644 --- a/drivers/staging/speakup/spk_priv_keyinfo.h +++ b/drivers/staging/speakup/spk_priv_keyinfo.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* spk_priv.h * review functions for the speakup screen review package. * originally written by: Kirk Reiser and Andy Berdan. @@ -6,16 +7,6 @@ * * Copyright (C) 1998 Kirk Reiser. * Copyright (C) 2003 David Borowski. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _SPEAKUP_KEYINFO_H diff --git a/drivers/staging/speakup/spk_ttyio.c b/drivers/staging/speakup/spk_ttyio.c index 513cebbd161c..5aa3ffa3772d 100644 --- a/drivers/staging/speakup/spk_ttyio.c +++ b/drivers/staging/speakup/spk_ttyio.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include <linux/types.h> #include <linux/tty.h> #include <linux/tty_flip.h> diff --git a/drivers/staging/speakup/synth.c b/drivers/staging/speakup/synth.c index aac29c816d09..c06e6a810999 100644 --- a/drivers/staging/speakup/synth.c +++ b/drivers/staging/speakup/synth.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include <linux/types.h> #include <linux/ctype.h> /* for isdigit() and friends */ #include <linux/fs.h> diff --git a/drivers/staging/speakup/thread.c b/drivers/staging/speakup/thread.c index 8c64f1ada6e0..2fc75e60fbac 100644 --- a/drivers/staging/speakup/thread.c +++ b/drivers/staging/speakup/thread.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include <linux/kthread.h> #include <linux/wait.h> diff --git a/drivers/staging/speakup/varhandlers.c b/drivers/staging/speakup/varhandlers.c index d37d24e26641..321405532a8e 100644 --- a/drivers/staging/speakup/varhandlers.c +++ b/drivers/staging/speakup/varhandlers.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include <linux/ctype.h> #include "spk_types.h" #include "spk_priv.h" diff --git a/drivers/staging/typec/tcpci.c b/drivers/staging/typec/tcpci.c index b6abaf79ef0b..9bd4412356c9 100644 --- a/drivers/staging/typec/tcpci.c +++ b/drivers/staging/typec/tcpci.c @@ -1,16 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright 2015-2017 Google, Inc * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * USB Type-C Port Controller Interface. */ @@ -47,7 +38,7 @@ static inline struct tcpci *tcpc_to_tcpci(struct tcpc_dev *tcpc) } static int tcpci_read16(struct tcpci *tcpci, unsigned int reg, - unsigned int *val) + u16 *val) { return regmap_raw_read(tcpci->regmap, reg, val, sizeof(u16)); } @@ -285,15 +276,15 @@ static int tcpci_pd_transmit(struct tcpc_dev *tcpc, const struct pd_message *msg) { struct tcpci *tcpci = tcpc_to_tcpci(tcpc); - unsigned int reg, cnt, header; + u16 header = msg ? le16_to_cpu(msg->header) : 0; + unsigned int reg, cnt; int ret; - cnt = msg ? pd_header_cnt(msg->header) * 4 : 0; + cnt = msg ? pd_header_cnt(header) * 4 : 0; ret = regmap_write(tcpci->regmap, TCPC_TX_BYTE_CNT, cnt + 2); if (ret < 0) return ret; - header = msg ? msg->header : 0; ret = tcpci_write16(tcpci, TCPC_TX_HDR, header); if (ret < 0) return ret; @@ -356,7 +347,7 @@ static int tcpci_init(struct tcpc_dev *tcpc) static irqreturn_t tcpci_irq(int irq, void *dev_id) { struct tcpci *tcpci = dev_id; - unsigned int status, reg; + u16 status; tcpci_read16(tcpci, TCPC_ALERT, &status); @@ -372,6 +363,8 @@ static irqreturn_t tcpci_irq(int irq, void *dev_id) tcpm_cc_change(tcpci->port); if (status & TCPC_ALERT_POWER_STATUS) { + unsigned int reg; + regmap_read(tcpci->regmap, TCPC_POWER_STATUS_MASK, ®); /* @@ -387,11 +380,12 @@ static irqreturn_t tcpci_irq(int irq, void *dev_id) if (status & TCPC_ALERT_RX_STATUS) { struct pd_message msg; unsigned int cnt; + u16 header; regmap_read(tcpci->regmap, TCPC_RX_BYTE_CNT, &cnt); - tcpci_read16(tcpci, TCPC_RX_HDR, ®); - msg.header = reg; + tcpci_read16(tcpci, TCPC_RX_HDR, &header); + msg.header = cpu_to_le16(header); if (WARN_ON(cnt > sizeof(msg.payload))) cnt = sizeof(msg.payload); diff --git a/drivers/staging/typec/tcpci.h b/drivers/staging/typec/tcpci.h index 10b04c8723da..fdfb06cc3b86 100644 --- a/drivers/staging/typec/tcpci.h +++ b/drivers/staging/typec/tcpci.h @@ -1,16 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright 2015-2017 Google, Inc * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * USB Type-C Port Controller Interface. */ diff --git a/drivers/staging/unisys/Kconfig b/drivers/staging/unisys/Kconfig index 4f1f5e624604..c27dab3b610f 100644 --- a/drivers/staging/unisys/Kconfig +++ b/drivers/staging/unisys/Kconfig @@ -3,15 +3,11 @@ # menuconfig UNISYSSPAR bool "Unisys SPAR driver support" - depends on X86_64 && !UML - select PCI - select ACPI ---help--- Support for the Unisys SPAR drivers if UNISYSSPAR -source "drivers/staging/unisys/visorbus/Kconfig" source "drivers/staging/unisys/visornic/Kconfig" source "drivers/staging/unisys/visorinput/Kconfig" source "drivers/staging/unisys/visorhba/Kconfig" diff --git a/drivers/staging/unisys/Makefile b/drivers/staging/unisys/Makefile index 20eb098538d3..e45f44b64202 100644 --- a/drivers/staging/unisys/Makefile +++ b/drivers/staging/unisys/Makefile @@ -1,7 +1,6 @@ # # Makefile for Unisys SPAR drivers # -obj-$(CONFIG_UNISYS_VISORBUS) += visorbus/ obj-$(CONFIG_UNISYS_VISORNIC) += visornic/ obj-$(CONFIG_UNISYS_VISORINPUT) += visorinput/ obj-$(CONFIG_UNISYS_VISORHBA) += visorhba/ diff --git a/drivers/staging/unisys/include/iochannel.h b/drivers/staging/unisys/include/iochannel.h index 5cd407ca2251..45c785d80ce4 100644 --- a/drivers/staging/unisys/include/iochannel.h +++ b/drivers/staging/unisys/include/iochannel.h @@ -1,17 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2010 - 2016 UNISYS CORPORATION * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. */ #ifndef __IOCHANNEL_H__ @@ -43,8 +33,7 @@ #include <linux/uuid.h> #include <linux/skbuff.h> - -#include "visorchannel.h" +#include <linux/visorbus.h> /* * Must increment these whenever you insert or delete fields within this channel diff --git a/drivers/staging/unisys/include/visorbus.h b/drivers/staging/unisys/include/visorbus.h deleted file mode 100644 index 1a0986ba3d24..000000000000 --- a/drivers/staging/unisys/include/visorbus.h +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (C) 2010 - 2013 UNISYS CORPORATION - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - */ - -/* - * This header file is to be included by other kernel mode components that - * implement a particular kind of visor_device. Each of these other kernel - * mode components is called a visor device driver. Refer to visortemplate - * for a minimal sample visor device driver. - * - * There should be nothing in this file that is private to the visorbus - * bus implementation itself. - */ - -#ifndef __VISORBUS_H__ -#define __VISORBUS_H__ - -#include <linux/device.h> - -#include "visorchannel.h" - -struct visorchipset_state { - u32 created:1; - u32 attached:1; - u32 configured:1; - u32 running:1; - /* Remaining bits in this 32-bit word are reserved. */ -}; - -/** - * struct visor_device - A device type for things "plugged" into the visorbus - * bus - * @visorchannel: Points to the channel that the device is - * associated with. - * @channel_type_guid: Identifies the channel type to the bus driver. - * @device: Device struct meant for use by the bus driver - * only. - * @list_all: Used by the bus driver to enumerate devices. - * @timer: Timer fired periodically to do interrupt-type - * activity. - * @being_removed: Indicates that the device is being removed from - * the bus. Private bus driver use only. - * @visordriver_callback_lock: Used by the bus driver to lock when adding and - * removing devices. - * @pausing: Indicates that a change towards a paused state. - * is in progress. Only modified by the bus driver. - * @resuming: Indicates that a change towards a running state - * is in progress. Only modified by the bus driver. - * @chipset_bus_no: Private field used by the bus driver. - * @chipset_dev_no: Private field used the bus driver. - * @state: Used to indicate the current state of the - * device. - * @inst: Unique GUID for this instance of the device. - * @name: Name of the device. - * @pending_msg_hdr: For private use by bus driver to respond to - * hypervisor requests. - * @vbus_hdr_info: A pointer to header info. Private use by bus - * driver. - * @partition_guid: Indicates client partion id. This should be the - * same across all visor_devices in the current - * guest. Private use by bus driver only. - */ -struct visor_device { - struct visorchannel *visorchannel; - guid_t channel_type_guid; - /* These fields are for private use by the bus driver only. */ - struct device device; - struct list_head list_all; - struct timer_list timer; - bool timer_active; - bool being_removed; - struct mutex visordriver_callback_lock; /* synchronize probe/remove */ - bool pausing; - bool resuming; - u32 chipset_bus_no; - u32 chipset_dev_no; - struct visorchipset_state state; - guid_t inst; - u8 *name; - struct controlvm_message_header *pending_msg_hdr; - void *vbus_hdr_info; - guid_t partition_guid; - struct dentry *debugfs_dir; - struct dentry *debugfs_bus_info; -}; - -#define to_visor_device(x) container_of(x, struct visor_device, device) - -typedef void (*visorbus_state_complete_func) (struct visor_device *dev, - int status); - -/* - * This struct describes a specific visor channel, by providing its GUID, name, - * and sizes. - */ -struct visor_channeltype_descriptor { - const guid_t guid; - const char *name; - u64 min_bytes; - u32 version; -}; - -/** - * struct visor_driver - Information provided by each visor driver when it - * registers with the visorbus driver - * @name: Name of the visor driver. - * @owner: The module owner. - * @channel_types: Types of channels handled by this driver, ending with - * a zero GUID. Our specialized BUS.match() method knows - * about this list, and uses it to determine whether this - * driver will in fact handle a new device that it has - * detected. - * @probe: Called when a new device comes online, by our probe() - * function specified by driver.probe() (triggered - * ultimately by some call to driver_register(), - * bus_add_driver(), or driver_attach()). - * @remove: Called when a new device is removed, by our remove() - * function specified by driver.remove() (triggered - * ultimately by some call to device_release_driver()). - * @channel_interrupt: Called periodically, whenever there is a possiblity - * that "something interesting" may have happened to the - * channel. - * @pause: Called to initiate a change of the device's state. If - * the return valu`e is < 0, there was an error and the - * state transition will NOT occur. If the return value - * is >= 0, then the state transition was INITIATED - * successfully, and complete_func() will be called (or - * was just called) with the final status when either the - * state transition fails or completes successfully. - * @resume: Behaves similar to pause. - * @driver: Private reference to the device driver. For use by bus - * driver only. - */ -struct visor_driver { - const char *name; - struct module *owner; - struct visor_channeltype_descriptor *channel_types; - int (*probe)(struct visor_device *dev); - void (*remove)(struct visor_device *dev); - void (*channel_interrupt)(struct visor_device *dev); - int (*pause)(struct visor_device *dev, - visorbus_state_complete_func complete_func); - int (*resume)(struct visor_device *dev, - visorbus_state_complete_func complete_func); - - /* These fields are for private use by the bus driver only. */ - struct device_driver driver; -}; - -#define to_visor_driver(x) (container_of(x, struct visor_driver, driver)) - -int visor_check_channel(struct channel_header *ch, struct device *dev, - const guid_t *expected_uuid, char *chname, - u64 expected_min_bytes, u32 expected_version, - u64 expected_signature); - -int visorbus_register_visor_driver(struct visor_driver *drv); -void visorbus_unregister_visor_driver(struct visor_driver *drv); -int visorbus_read_channel(struct visor_device *dev, - unsigned long offset, void *dest, - unsigned long nbytes); -int visorbus_write_channel(struct visor_device *dev, - unsigned long offset, void *src, - unsigned long nbytes); -int visorbus_enable_channel_interrupts(struct visor_device *dev); -void visorbus_disable_channel_interrupts(struct visor_device *dev); - -int visorchannel_signalremove(struct visorchannel *channel, u32 queue, - void *msg); -int visorchannel_signalinsert(struct visorchannel *channel, u32 queue, - void *msg); -bool visorchannel_signalempty(struct visorchannel *channel, u32 queue); -const guid_t *visorchannel_get_guid(struct visorchannel *channel); - -#define BUS_ROOT_DEVICE UINT_MAX -struct visor_device *visorbus_get_device_by_id(u32 bus_no, u32 dev_no, - struct visor_device *from); -#endif diff --git a/drivers/staging/unisys/include/visorchannel.h b/drivers/staging/unisys/include/visorchannel.h deleted file mode 100644 index 33945749c8b6..000000000000 --- a/drivers/staging/unisys/include/visorchannel.h +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (C) 2010 - 2013 UNISYS CORPORATION - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - */ - -#ifndef __VISORCHANNEL_H__ -#define __VISORCHANNEL_H__ - -#include <linux/types.h> -#include <linux/uuid.h> - -#define VISOR_CHANNEL_SIGNATURE ('L' << 24 | 'N' << 16 | 'C' << 8 | 'E') - -/* - * enum channel_serverstate - * @CHANNELSRV_UNINITIALIZED: Channel is in an undefined state. - * @CHANNELSRV_READY: Channel has been initialized by server. - */ -enum channel_serverstate { - CHANNELSRV_UNINITIALIZED = 0, - CHANNELSRV_READY = 1 -}; - -/* - * enum channel_clientstate - * @CHANNELCLI_DETACHED: - * @CHANNELCLI_DISABLED: Client can see channel but is NOT allowed to use it - * unless given TBD* explicit request - * (should actually be < DETACHED). - * @CHANNELCLI_ATTACHING: Legacy EFI client request for EFI server to attach. - * @CHANNELCLI_ATTACHED: Idle, but client may want to use channel any time. - * @CHANNELCLI_BUSY: Client either wants to use or is using channel. - * @CHANNELCLI_OWNED: "No worries" state - client can access channel - * anytime. - */ -enum channel_clientstate { - CHANNELCLI_DETACHED = 0, - CHANNELCLI_DISABLED = 1, - CHANNELCLI_ATTACHING = 2, - CHANNELCLI_ATTACHED = 3, - CHANNELCLI_BUSY = 4, - CHANNELCLI_OWNED = 5 -}; - -/* - * Values for VISOR_CHANNEL_PROTOCOL.Features: This define exists so that - * a guest can look at the FeatureFlags in the io channel, and configure the - * driver to use interrupts or not based on this setting. All feature bits for - * all channels should be defined here. The io channel feature bits are defined - * below. - */ -#define VISOR_DRIVER_ENABLES_INTS (0x1ULL << 1) -#define VISOR_CHANNEL_IS_POLLING (0x1ULL << 3) -#define VISOR_IOVM_OK_DRIVER_DISABLING_INTS (0x1ULL << 4) -#define VISOR_DRIVER_DISABLES_INTS (0x1ULL << 5) -#define VISOR_DRIVER_ENHANCED_RCVBUF_CHECKING (0x1ULL << 6) - -/* - * struct channel_header - Common Channel Header - * @signature: Signature. - * @legacy_state: DEPRECATED - being replaced by. - * @header_size: sizeof(struct channel_header). - * @size: Total size of this channel in bytes. - * @features: Flags to modify behavior. - * @chtype: Channel type: data, bus, control, etc.. - * @partition_handle: ID of guest partition. - * @handle: Device number of this channel in client. - * @ch_space_offset: Offset in bytes to channel specific area. - * @version_id: Struct channel_header Version ID. - * @partition_index: Index of guest partition. - * @zone_uuid: Guid of Channel's zone. - * @cli_str_offset: Offset from channel header to null-terminated - * ClientString (0 if ClientString not present). - * @cli_state_boot: CHANNEL_CLIENTSTATE of pre-boot EFI client of this - * channel. - * @cmd_state_cli: CHANNEL_COMMANDSTATE (overloaded in Windows drivers, see - * ServerStateUp, ServerStateDown, etc). - * @cli_state_os: CHANNEL_CLIENTSTATE of Guest OS client of this channel. - * @ch_characteristic: CHANNEL_CHARACTERISTIC_<xxx>. - * @cmd_state_srv: CHANNEL_COMMANDSTATE (overloaded in Windows drivers, see - * ServerStateUp, ServerStateDown, etc). - * @srv_state: CHANNEL_SERVERSTATE. - * @cli_error_boot: Bits to indicate err states for boot clients, so err - * messages can be throttled. - * @cli_error_os: Bits to indicate err states for OS clients, so err - * messages can be throttled. - * @filler: Pad out to 128 byte cacheline. - * @recover_channel: Please add all new single-byte values below here. - */ -struct channel_header { - u64 signature; - u32 legacy_state; - /* SrvState, CliStateBoot, and CliStateOS below */ - u32 header_size; - u64 size; - u64 features; - guid_t chtype; - u64 partition_handle; - u64 handle; - u64 ch_space_offset; - u32 version_id; - u32 partition_index; - guid_t zone_guid; - u32 cli_str_offset; - u32 cli_state_boot; - u32 cmd_state_cli; - u32 cli_state_os; - u32 ch_characteristic; - u32 cmd_state_srv; - u32 srv_state; - u8 cli_error_boot; - u8 cli_error_os; - u8 filler[1]; - u8 recover_channel; -} __packed; - -#define VISOR_CHANNEL_ENABLE_INTS (0x1ULL << 0) - -/* - * struct signal_queue_header - Subheader for the Signal Type variation of the - * Common Channel. - * @version: SIGNAL_QUEUE_HEADER Version ID. - * @chtype: Queue type: storage, network. - * @size: Total size of this queue in bytes. - * @sig_base_offset: Offset to signal queue area. - * @features: Flags to modify behavior. - * @num_sent: Total # of signals placed in this queue. - * @num_overflows: Total # of inserts failed due to full queue. - * @signal_size: Total size of a signal for this queue. - * @max_slots: Max # of slots in queue, 1 slot is always empty. - * @max_signals: Max # of signals in queue (MaxSignalSlots-1). - * @head: Queue head signal #. - * @num_received: Total # of signals removed from this queue. - * @tail: Queue tail signal. - * @reserved1: Reserved field. - * @reserved2: Reserved field. - * @client_queue: - * @num_irq_received: Total # of Interrupts received. This is incremented by the - * ISR in the guest windows driver. - * @num_empty: Number of times that visor_signal_remove is called and - * returned Empty Status. - * @errorflags: Error bits set during SignalReinit to denote trouble with - * client's fields. - * @filler: Pad out to 64 byte cacheline. - */ -struct signal_queue_header { - /* 1st cache line */ - u32 version; - u32 chtype; - u64 size; - u64 sig_base_offset; - u64 features; - u64 num_sent; - u64 num_overflows; - u32 signal_size; - u32 max_slots; - u32 max_signals; - u32 head; - /* 2nd cache line */ - u64 num_received; - u32 tail; - u32 reserved1; - u64 reserved2; - u64 client_queue; - u64 num_irq_received; - u64 num_empty; - u32 errorflags; - u8 filler[12]; -} __packed; - -/* VISORCHANNEL Guids */ -/* {414815ed-c58c-11da-95a9-00e08161165f} */ -#define VISOR_VHBA_CHANNEL_GUID \ - GUID_INIT(0x414815ed, 0xc58c, 0x11da, \ - 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f) -#define VISOR_VHBA_CHANNEL_GUID_STR \ - "414815ed-c58c-11da-95a9-00e08161165f" -#endif diff --git a/drivers/staging/unisys/visorbus/Kconfig b/drivers/staging/unisys/visorbus/Kconfig deleted file mode 100644 index 511388075ffa..000000000000 --- a/drivers/staging/unisys/visorbus/Kconfig +++ /dev/null @@ -1,14 +0,0 @@ -# -# Unisys visorbus configuration -# - -config UNISYS_VISORBUS - tristate "Unisys visorbus driver" - depends on UNISYSSPAR - ---help--- - The visorbus driver is a virtualized bus for the Unisys s-Par firmware. - Virtualized devices allow Linux guests on a system to share disks and - network cards that do not have SR-IOV support, and to be accessed using - the partition desktop application. The visorbus driver is required to - discover devices on an s-Par guest, and must be present for any other - s-Par guest driver to function correctly. diff --git a/drivers/staging/unisys/visorbus/Makefile b/drivers/staging/unisys/visorbus/Makefile deleted file mode 100644 index 784cdc1f9d6a..000000000000 --- a/drivers/staging/unisys/visorbus/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# Makefile for Unisys visorbus -# - -obj-$(CONFIG_UNISYS_VISORBUS) += visorbus.o - -visorbus-y := visorbus_main.o -visorbus-y += visorchannel.o -visorbus-y += visorchipset.o - -ccflags-y += -Idrivers/staging/unisys/include diff --git a/drivers/staging/unisys/visorbus/controlvmchannel.h b/drivers/staging/unisys/visorbus/controlvmchannel.h deleted file mode 100644 index 9ee9886a9aed..000000000000 --- a/drivers/staging/unisys/visorbus/controlvmchannel.h +++ /dev/null @@ -1,660 +0,0 @@ -/* - * Copyright (C) 2010 - 2015 UNISYS CORPORATION - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - */ - -#ifndef __CONTROLVMCHANNEL_H__ -#define __CONTROLVMCHANNEL_H__ - -#include <linux/uuid.h> - -#include "visorchannel.h" - -/* {2B3C2D10-7EF5-4ad8-B966-3448B7386B3D} */ -#define VISOR_CONTROLVM_CHANNEL_GUID \ - GUID_INIT(0x2b3c2d10, 0x7ef5, 0x4ad8, \ - 0xb9, 0x66, 0x34, 0x48, 0xb7, 0x38, 0x6b, 0x3d) - -#define CONTROLVM_MESSAGE_MAX 64 - -/* - * Must increment this whenever you insert or delete fields within this channel - * struct. Also increment whenever you change the meaning of fields within this - * channel struct so as to break pre-existing software. Note that you can - * usually add fields to the END of the channel struct withOUT needing to - * increment this. - */ -#define VISOR_CONTROLVM_CHANNEL_VERSIONID 1 - -/* Defines for various channel queues */ -#define CONTROLVM_QUEUE_REQUEST 0 -#define CONTROLVM_QUEUE_RESPONSE 1 -#define CONTROLVM_QUEUE_EVENT 2 -#define CONTROLVM_QUEUE_ACK 3 - -/* Max num of messages stored during IOVM creation to be reused after crash */ -#define CONTROLVM_CRASHMSG_MAX 2 - -/* - * struct visor_segment_state - * @enabled: May enter other states. - * @active: Assigned to active partition. - * @alive: Configure message sent to service/server. - * @revoked: Similar to partition state ShuttingDown. - * @allocated: Memory (device/port number) has been selected by Command. - * @known: Has been introduced to the service/guest partition. - * @ready: Service/Guest partition has responded to introduction. - * @operating: Resource is configured and operating. - * @reserved: Natural alignment. - * - * Note: Don't use high bit unless we need to switch to ushort which is - * non-compliant. - */ -struct visor_segment_state { - u16 enabled:1; - u16 active:1; - u16 alive:1; - u16 revoked:1; - u16 allocated:1; - u16 known:1; - u16 ready:1; - u16 operating:1; - u16 reserved:8; -} __packed; - -static const struct visor_segment_state segment_state_running = { - 1, 1, 1, 0, 1, 1, 1, 1 -}; - -static const struct visor_segment_state segment_state_paused = { - 1, 1, 1, 0, 1, 1, 1, 0 -}; - -static const struct visor_segment_state segment_state_standby = { - 1, 1, 0, 0, 1, 1, 1, 0 -}; - -/* - * enum controlvm_id - * @CONTROLVM_INVALID: - * @CONTROLVM_BUS_CREATE: CP --> SP, GP. - * @CONTROLVM_BUS_DESTROY: CP --> SP, GP. - * @CONTROLVM_BUS_CONFIGURE: CP --> SP. - * @CONTROLVM_BUS_CHANGESTATE: CP --> SP, GP. - * @CONTROLVM_BUS_CHANGESTATE_EVENT: SP, GP --> CP. - * @CONTROLVM_DEVICE_CREATE: CP --> SP, GP. - * @CONTROLVM_DEVICE_DESTROY: CP --> SP, GP. - * @CONTROLVM_DEVICE_CONFIGURE: CP --> SP. - * @CONTROLVM_DEVICE_CHANGESTATE: CP --> SP, GP. - * @CONTROLVM_DEVICE_CHANGESTATE_EVENT: SP, GP --> CP. - * @CONTROLVM_DEVICE_RECONFIGURE: CP --> Boot. - * @CONTROLVM_CHIPSET_INIT: CP --> SP, GP. - * @CONTROLVM_CHIPSET_STOP: CP --> SP, GP. - * @CONTROLVM_CHIPSET_READY: CP --> SP. - * @CONTROLVM_CHIPSET_SELFTEST: CP --> SP. - * - * Ids for commands that may appear in either queue of a ControlVm channel. - * - * Commands that are initiated by the command partition (CP), by an IO or - * console service partition (SP), or by a guest partition (GP) are: - * - issued on the RequestQueue queue (q #0) in the ControlVm channel - * - responded to on the ResponseQueue queue (q #1) in the ControlVm channel - * - * Events that are initiated by an IO or console service partition (SP) or - * by a guest partition (GP) are: - * - issued on the EventQueue queue (q #2) in the ControlVm channel - * - responded to on the EventAckQueue queue (q #3) in the ControlVm channel - */ -enum controlvm_id { - CONTROLVM_INVALID = 0, - /* - * SWITCH commands required Parameter: SwitchNumber. - * BUS commands required Parameter: BusNumber - */ - CONTROLVM_BUS_CREATE = 0x101, - CONTROLVM_BUS_DESTROY = 0x102, - CONTROLVM_BUS_CONFIGURE = 0x104, - CONTROLVM_BUS_CHANGESTATE = 0x105, - CONTROLVM_BUS_CHANGESTATE_EVENT = 0x106, - /* DEVICE commands required Parameter: BusNumber, DeviceNumber */ - CONTROLVM_DEVICE_CREATE = 0x201, - CONTROLVM_DEVICE_DESTROY = 0x202, - CONTROLVM_DEVICE_CONFIGURE = 0x203, - CONTROLVM_DEVICE_CHANGESTATE = 0x204, - CONTROLVM_DEVICE_CHANGESTATE_EVENT = 0x205, - CONTROLVM_DEVICE_RECONFIGURE = 0x206, - /* CHIPSET commands */ - CONTROLVM_CHIPSET_INIT = 0x301, - CONTROLVM_CHIPSET_STOP = 0x302, - CONTROLVM_CHIPSET_READY = 0x304, - CONTROLVM_CHIPSET_SELFTEST = 0x305, -}; - -/* - * struct irq_info - * @reserved1: Natural alignment purposes - * @recv_irq_handle: Specifies interrupt handle. It is used to retrieve the - * corresponding interrupt pin from Monitor; and the interrupt - * pin is used to connect to the corresponding interrupt. - * Used by IOPart-GP only. - * @recv_irq_vector: Specifies interrupt vector. It, interrupt pin, and shared - * are used to connect to the corresponding interrupt. - * Used by IOPart-GP only. - * @recv_irq_shared: Specifies if the recvInterrupt is shared. It, interrupt - * pin and vector are used to connect to 0 = not shared; - * 1 = shared the corresponding interrupt. - * Used by IOPart-GP only. - * @reserved: Natural alignment purposes - */ -struct irq_info { - u64 reserved1; - u64 recv_irq_handle; - u32 recv_irq_vector; - u8 recv_irq_shared; - u8 reserved[3]; -} __packed; - -/* - * struct efi_visor_indication - * @boot_to_fw_ui: Stop in UEFI UI - * @clear_nvram: Clear NVRAM - * @clear_cmos: Clear CMOS - * @boot_to_tool: Run install tool - * @reserved: Natural alignment - */ -struct efi_visor_indication { - u64 boot_to_fw_ui:1; - u64 clear_nvram:1; - u64 clear_cmos:1; - u64 boot_to_tool:1; - /* Remaining bits are available */ - u64 reserved:60; -} __packed; - -enum visor_chipset_feature { - VISOR_CHIPSET_FEATURE_REPLY = 0x00000001, - VISOR_CHIPSET_FEATURE_PARA_HOTPLUG = 0x00000002, -}; - -/* - * struct controlvm_message_header - * @id: See CONTROLVM_ID. - * @message_size: Includes size of this struct + size of message. - * @segment_index: Index of segment containing Vm message/information. - * @completion_status: Error status code or result of message completion. - * @struct flags: - * @failed: =1 in a response to signify failure. - * @response_expected: =1 in all messages that expect a response. - * @server: =1 in all bus & device-related messages where the - * message receiver is to act as the bus or device - * server. - * @test_message: =1 for testing use only (Control and Command - * ignore this). - * @partial_completion: =1 if there are forthcoming responses/acks - * associated with this message. - * @preserve: =1 this is to let us know to preserve channel - * contents. - * @writer_in_diag: =1 the DiagWriter is active in the Diagnostic - * Partition. - * @reserve: Natural alignment. - * @reserved: Natural alignment. - * @message_handle: Identifies the particular message instance. - * @payload_vm_offset: Offset of payload area from start of this instance. - * @payload_max_bytes: Maximum bytes allocated in payload area of ControlVm - * segment. - * @payload_bytes: Actual number of bytes of payload area to copy between - * IO/Command. If non-zero, there is a payload to copy. - * - * This is the common structure that is at the beginning of every - * ControlVm message (both commands and responses) in any ControlVm - * queue. Commands are easily distinguished from responses by - * looking at the flags.response field. - */ -struct controlvm_message_header { - u32 id; - /* - * For requests, indicates the message type. For responses, indicates - * the type of message we are responding to. - */ - u32 message_size; - u32 segment_index; - u32 completion_status; - struct { - u32 failed:1; - u32 response_expected:1; - u32 server:1; - u32 test_message:1; - u32 partial_completion:1; - u32 preserve:1; - u32 writer_in_diag:1; - u32 reserve:25; - } __packed flags; - u32 reserved; - u64 message_handle; - u64 payload_vm_offset; - u32 payload_max_bytes; - u32 payload_bytes; -} __packed; - -/* - * struct controlvm_packet_device_create - For CONTROLVM_DEVICE_CREATE - * @bus_no: Bus # (0..n-1) from the msg receiver's end. - * @dev_no: Bus-relative (0..n-1) device number. - * @channel_addr: Guest physical address of the channel, which can be - * dereferenced by the receiver of this ControlVm command. - * @channel_bytes: Specifies size of the channel in bytes. - * @data_type_uuid: Specifies format of data in channel. - * @dev_inst_uuid: Instance guid for the device. - * @irq_info intr: Specifies interrupt information. - */ -struct controlvm_packet_device_create { - u32 bus_no; - u32 dev_no; - u64 channel_addr; - u64 channel_bytes; - guid_t data_type_guid; - guid_t dev_inst_guid; - struct irq_info intr; -} __packed; - -/* - * struct controlvm_packet_device_configure - For CONTROLVM_DEVICE_CONFIGURE - * @bus_no: Bus number (0..n-1) from the msg receiver's perspective. - * @dev_no: Bus-relative (0..n-1) device number. - */ -struct controlvm_packet_device_configure { - u32 bus_no; - u32 dev_no; -} __packed; - -/* Total 128 bytes */ -struct controlvm_message_device_create { - struct controlvm_message_header header; - struct controlvm_packet_device_create packet; -} __packed; - -/* Total 56 bytes */ -struct controlvm_message_device_configure { - struct controlvm_message_header header; - struct controlvm_packet_device_configure packet; -} __packed; - -/* - * struct controlvm_message_packet - This is the format for a message in any - * ControlVm queue. - * @struct create_bus: For CONTROLVM_BUS_CREATE. - * @bus_no: Bus # (0..n-1) from the msg receiver's perspective. - * @dev_count: Indicates the max number of devices on this bus. - * @channel_addr: Guest physical address of the channel, which can be - * dereferenced by the receiver of this ControlVM - * command. - * @channel_bytes: Size of the channel. - * @bus_data_type_uuid: Indicates format of data in bus channel. - * @bus_inst_uuid: Instance uuid for the bus. - * - * @struct destroy_bus: For CONTROLVM_BUS_DESTROY. - * @bus_no: Bus # (0..n-1) from the msg receiver's perspective. - * @reserved: Natural alignment purposes. - * - * @struct configure_bus: For CONTROLVM_BUS_CONFIGURE. - * @bus_no: Bus # (0..n-1) from the receiver's perspective. - * @reserved1: For alignment purposes. - * @guest_handle: This is used to convert guest physical address to - * physical address. - * @recv_bus_irq_handle: Specifies interrupt info. It is used by SP to - * register to receive interrupts from the CP. This - * interrupt is used for bus level notifications. - * The corresponding sendBusInterruptHandle is kept - * in CP. - * - * @struct create_device: For CONTROLVM_DEVICE_CREATE. - * - * @struct destroy_device: For CONTROLVM_DEVICE_DESTROY. - * @bus_no: Bus # (0..n-1) from the msg receiver's perspective. - * @dev_no: Bus-relative (0..n-1) device number. - * - * @struct configure_device: For CONTROLVM_DEVICE_CONFIGURE. - * - * @struct reconfigure_device: For CONTROLVM_DEVICE_RECONFIGURE. - * @bus_no: Bus # (0..n-1) from the msg receiver's perspective. - * @dev_no: Bus-relative (0..n-1) device number. - * - * @struct bus_change_state: For CONTROLVM_BUS_CHANGESTATE. - * @bus_no: - * @struct state: - * @reserved: Natural alignment purposes. - * - * @struct device_change_state: For CONTROLVM_DEVICE_CHANGESTATE. - * @bus_no: - * @dev_no: - * @struct state: - * @struct flags: - * @phys_device: =1 if message is for a physical device. - * @reserved: Natural alignment. - * @reserved1: Natural alignment. - * @reserved: Natural alignment purposes. - * - * @struct device_change_state_event: For CONTROLVM_DEVICE_CHANGESTATE_EVENT. - * @bus_no: - * @dev_no: - * @struct state: - * @reserved: Natural alignment purposes. - * - * @struct init_chipset: For CONTROLVM_CHIPSET_INIT. - * @bus_count: Indicates the max number of busses. - * @switch_count: Indicates the max number of switches. - * @enum features: - * @platform_number: - * - * @struct chipset_selftest: For CONTROLVM_CHIPSET_SELFTEST. - * @options: Reserved. - * @test: Bit 0 set to run embedded selftest. - * - * @addr: A physical address of something, that can be dereferenced by the - * receiver of this ControlVm command. - * - * @handle: A handle of something (depends on command id). - */ -struct controlvm_message_packet { - union { - struct { - u32 bus_no; - u32 dev_count; - u64 channel_addr; - u64 channel_bytes; - guid_t bus_data_type_guid; - guid_t bus_inst_guid; - } __packed create_bus; - struct { - u32 bus_no; - u32 reserved; - } __packed destroy_bus; - struct { - u32 bus_no; - u32 reserved1; - u64 guest_handle; - u64 recv_bus_irq_handle; - } __packed configure_bus; - struct controlvm_packet_device_create create_device; - struct { - u32 bus_no; - u32 dev_no; - } __packed destroy_device; - struct controlvm_packet_device_configure configure_device; - struct { - u32 bus_no; - u32 dev_no; - } __packed reconfigure_device; - struct { - u32 bus_no; - struct visor_segment_state state; - u8 reserved[2]; - } __packed bus_change_state; - struct { - u32 bus_no; - u32 dev_no; - struct visor_segment_state state; - struct { - u32 phys_device:1; - u32 reserved:31; - u32 reserved1; - } __packed flags; - u8 reserved[2]; - } __packed device_change_state; - struct { - u32 bus_no; - u32 dev_no; - struct visor_segment_state state; - u8 reserved[6]; - } __packed device_change_state_event; - struct { - u32 bus_count; - u32 switch_count; - enum visor_chipset_feature features; - u32 platform_number; - } __packed init_chipset; - struct { - u32 options; - u32 test; - } __packed chipset_selftest; - u64 addr; - u64 handle; - }; -} __packed; - -/* All messages in any ControlVm queue have this layout. */ -struct controlvm_message { - struct controlvm_message_header hdr; - struct controlvm_message_packet cmd; -} __packed; - -/* - * struct visor_controlvm_channel - * @struct header: - * @gp_controlvm: Guest phys addr of this channel. - * @gp_partition_tables: Guest phys addr of partition tables. - * @gp_diag_guest: Guest phys addr of diagnostic channel. - * @gp_boot_romdisk: Guest phys addr of (read* only) Boot - * ROM disk. - * @gp_boot_ramdisk: Guest phys addr of writable Boot RAM - * disk. - * @gp_acpi_table: Guest phys addr of acpi table. - * @gp_control_channel: Guest phys addr of control channel. - * @gp_diag_romdisk: Guest phys addr of diagnostic ROM disk. - * @gp_nvram: Guest phys addr of NVRAM channel. - * @request_payload_offset: Offset to request payload area. - * @event_payload_offset: Offset to event payload area. - * @request_payload_bytes: Bytes available in request payload area. - * @event_payload_bytes: Bytes available in event payload area. - * @control_channel_bytes: - * @nvram_channel_bytes: Bytes in PartitionNvram segment. - * @message_bytes: sizeof(CONTROLVM_MESSAGE). - * @message_count: CONTROLVM_MESSAGE_MAX. - * @gp_smbios_table: Guest phys addr of SMBIOS tables. - * @gp_physical_smbios_table: Guest phys addr of SMBIOS table. - * @gp_reserved: VISOR_MAX_GUESTS_PER_SERVICE. - * @virtual_guest_firmware_image_base: Guest physical address of EFI firmware - * image base. - * @virtual_guest_firmware_entry_point: Guest physical address of EFI firmware - * entry point. - * @virtual_guest_firmware_image_size: Guest EFI firmware image size. - * @virtual_guest_firmware_boot_base: GPA = 1MB where EFI firmware image is - * copied to. - * @virtual_guest_image_base: - * @virtual_guest_image_size: - * @prototype_control_channel_offset: - * @virtual_guest_partition_handle: - * @restore_action: Restore Action field to restore the - * guest partition. - * @dump_action: For Windows guests it shows if the - * visordisk is in dump mode. - * @nvram_fail_count: - * @saved_crash_message_count: = CONTROLVM_CRASHMSG_MAX. - * @saved_crash_message_offset: Offset to request payload area needed - * for crash dump. - * @installation_error: Type of error encountered during - * installation. - * @installation_text_id: Id of string to display. - * @installation_remaining_steps: Number of remaining installation steps - * (for progress bars). - * @tool_action: VISOR_TOOL_ACTIONS Installation Action - * field. - * @reserved: Alignment. - * @struct efi_visor_ind: - * @sp_reserved: - * @reserved2: Force signals to begin on 128-byte - * cache line. - * @struct request_queue: Guest partition uses this queue to send - * requests to Control. - * @struct response_queue: Control uses this queue to respond to - * service or guest partition request. - * @struct event_queue: Control uses this queue to send events - * to guest partition. - * @struct event_ack_queue: Service or guest partition uses this - * queue to ack Control events. - * @struct request_msg: Request fixed-size message pool - - * does not include payload. - * @struct response_msg: Response fixed-size message pool - - * does not include payload. - * @struct event_msg: Event fixed-size message pool - - * does not include payload. - * @struct event_ack_msg: Ack fixed-size message pool - - * does not include payload. - * @struct saved_crash_msg: Message stored during IOVM creation to - * be reused after crash. - */ -struct visor_controlvm_channel { - struct channel_header header; - u64 gp_controlvm; - u64 gp_partition_tables; - u64 gp_diag_guest; - u64 gp_boot_romdisk; - u64 gp_boot_ramdisk; - u64 gp_acpi_table; - u64 gp_control_channel; - u64 gp_diag_romdisk; - u64 gp_nvram; - u64 request_payload_offset; - u64 event_payload_offset; - u32 request_payload_bytes; - u32 event_payload_bytes; - u32 control_channel_bytes; - u32 nvram_channel_bytes; - u32 message_bytes; - u32 message_count; - u64 gp_smbios_table; - u64 gp_physical_smbios_table; - char gp_reserved[2688]; - u64 virtual_guest_firmware_image_base; - u64 virtual_guest_firmware_entry_point; - u64 virtual_guest_firmware_image_size; - u64 virtual_guest_firmware_boot_base; - u64 virtual_guest_image_base; - u64 virtual_guest_image_size; - u64 prototype_control_channel_offset; - u64 virtual_guest_partition_handle; - u16 restore_action; - u16 dump_action; - u16 nvram_fail_count; - u16 saved_crash_message_count; - u32 saved_crash_message_offset; - u32 installation_error; - u32 installation_text_id; - u16 installation_remaining_steps; - u8 tool_action; - u8 reserved; - struct efi_visor_indication efi_visor_ind; - u32 sp_reserved; - u8 reserved2[28]; - struct signal_queue_header request_queue; - struct signal_queue_header response_queue; - struct signal_queue_header event_queue; - struct signal_queue_header event_ack_queue; - struct controlvm_message request_msg[CONTROLVM_MESSAGE_MAX]; - struct controlvm_message response_msg[CONTROLVM_MESSAGE_MAX]; - struct controlvm_message event_msg[CONTROLVM_MESSAGE_MAX]; - struct controlvm_message event_ack_msg[CONTROLVM_MESSAGE_MAX]; - struct controlvm_message saved_crash_msg[CONTROLVM_CRASHMSG_MAX]; -} __packed; - -/* - * struct visor_controlvm_parameters_header - * - * The following header will be located at the beginning of PayloadVmOffset for - * various ControlVm commands. The receiver of a ControlVm command with a - * PayloadVmOffset will dereference this address and then use connection_offset, - * initiator_offset, and target_offset to get the location of UTF-8 formatted - * strings that can be parsed to obtain command-specific information. The value - * of total_length should equal PayloadBytes. The format of the strings at - * PayloadVmOffset will take different forms depending on the message. - */ -struct visor_controlvm_parameters_header { - u32 total_length; - u32 header_length; - u32 connection_offset; - u32 connection_length; - u32 initiator_offset; - u32 initiator_length; - u32 target_offset; - u32 target_length; - u32 client_offset; - u32 client_length; - u32 name_offset; - u32 name_length; - guid_t id; - u32 revision; - /* Natural alignment */ - u32 reserved; -} __packed; - -/* General Errors------------------------------------------------------[0-99] */ -#define CONTROLVM_RESP_SUCCESS 0 -#define CONTROLVM_RESP_ALREADY_DONE 1 -#define CONTROLVM_RESP_IOREMAP_FAILED 2 -#define CONTROLVM_RESP_KMALLOC_FAILED 3 -#define CONTROLVM_RESP_ID_UNKNOWN 4 -#define CONTROLVM_RESP_ID_INVALID_FOR_CLIENT 5 -/* CONTROLVM_INIT_CHIPSET-------------------------------------------[100-199] */ -#define CONTROLVM_RESP_CLIENT_SWITCHCOUNT_NONZERO 100 -#define CONTROLVM_RESP_EXPECTED_CHIPSET_INIT 101 -/* Maximum Limit----------------------------------------------------[200-299] */ -/* BUS_CREATE */ -#define CONTROLVM_RESP_ERROR_MAX_BUSES 201 -/* DEVICE_CREATE */ -#define CONTROLVM_RESP_ERROR_MAX_DEVICES 202 -/* Payload and Parameter Related------------------------------------[400-499] */ -/* SWITCH_ATTACHEXTPORT, DEVICE_CONFIGURE */ -#define CONTROLVM_RESP_PAYLOAD_INVALID 400 -/* Multiple */ -#define CONTROLVM_RESP_INITIATOR_PARAMETER_INVALID 401 -/* DEVICE_CONFIGURE */ -#define CONTROLVM_RESP_TARGET_PARAMETER_INVALID 402 -/* DEVICE_CONFIGURE */ -#define CONTROLVM_RESP_CLIENT_PARAMETER_INVALID 403 -/* Specified[Packet Structure] Value--------------------------------[500-599] */ -/* SWITCH_ATTACHINTPORT */ -/* BUS_CONFIGURE, DEVICE_CREATE, DEVICE_CONFIG, DEVICE_DESTROY */ -#define CONTROLVM_RESP_BUS_INVALID 500 -/* SWITCH_ATTACHINTPORT*/ -/* DEVICE_CREATE, DEVICE_CONFIGURE, DEVICE_DESTROY */ -#define CONTROLVM_RESP_DEVICE_INVALID 501 -/* DEVICE_CREATE, DEVICE_CONFIGURE */ -#define CONTROLVM_RESP_CHANNEL_INVALID 502 -/* Partition Driver Callback Interface------------------------------[600-699] */ -/* BUS_CREATE, BUS_DESTROY, DEVICE_CREATE, DEVICE_DESTROY */ -#define CONTROLVM_RESP_VIRTPCI_DRIVER_FAILURE 604 -/* Unable to invoke VIRTPCI callback. VIRTPCI Callback returned error. */ -/* BUS_CREATE, BUS_DESTROY, DEVICE_CREATE, DEVICE_DESTROY */ -#define CONTROLVM_RESP_VIRTPCI_DRIVER_CALLBACK_ERROR 605 -/* Generic device callback returned error. */ -/* SWITCH_ATTACHEXTPORT, SWITCH_DETACHEXTPORT, DEVICE_CONFIGURE */ -#define CONTROLVM_RESP_GENERIC_DRIVER_CALLBACK_ERROR 606 -/* Bus Related------------------------------------------------------[700-799] */ -/* BUS_DESTROY */ -#define CONTROLVM_RESP_ERROR_BUS_DEVICE_ATTACHED 700 -/* Channel Related--------------------------------------------------[800-899] */ -/* GET_CHANNELINFO, DEVICE_DESTROY */ -#define CONTROLVM_RESP_CHANNEL_TYPE_UNKNOWN 800 -/* DEVICE_CREATE */ -#define CONTROLVM_RESP_CHANNEL_SIZE_TOO_SMALL 801 -/* Chipset Shutdown Related---------------------------------------[1000-1099] */ -#define CONTROLVM_RESP_CHIPSET_SHUTDOWN_FAILED 1000 -#define CONTROLVM_RESP_CHIPSET_SHUTDOWN_ALREADY_ACTIVE 1001 -/* Chipset Stop Related-------------------------------------------[1100-1199] */ -#define CONTROLVM_RESP_CHIPSET_STOP_FAILED_BUS 1100 -#define CONTROLVM_RESP_CHIPSET_STOP_FAILED_SWITCH 1101 -/* Device Related-------------------------------------------------[1400-1499] */ -#define CONTROLVM_RESP_DEVICE_UDEV_TIMEOUT 1400 - -/* __CONTROLVMCHANNEL_H__ */ -#endif diff --git a/drivers/staging/unisys/visorbus/vbuschannel.h b/drivers/staging/unisys/visorbus/vbuschannel.h deleted file mode 100644 index 981b180f3c4b..000000000000 --- a/drivers/staging/unisys/visorbus/vbuschannel.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2010 - 2015 UNISYS CORPORATION - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - */ - -#ifndef __VBUSCHANNEL_H__ -#define __VBUSCHANNEL_H__ - -/* - * The vbus channel is the channel area provided via the BUS_CREATE controlvm - * message for each virtual bus. This channel area is provided to both server - * and client ends of the bus. The channel header area is initialized by - * the server, and the remaining information is filled in by the client. - * We currently use this for the client to provide various information about - * the client devices and client drivers for the server end to see. - */ - -#include <linux/uuid.h> -#include "visorchannel.h" - -/* {193b331b-c58f-11da-95a9-00e08161165f} */ -#define VISOR_VBUS_CHANNEL_GUID \ - GUID_INIT(0x193b331b, 0xc58f, 0x11da, \ - 0x95, 0xa9, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f) - -/* - * Must increment this whenever you insert or delete fields within this channel - * struct. Also increment whenever you change the meaning of fields within this - * channel struct so as to break pre-existing software. Note that you can - * usually add fields to the END of the channel struct withOUT needing to - * increment this. - */ -#define VISOR_VBUS_CHANNEL_VERSIONID 1 - -/* - * struct visor_vbus_deviceinfo - * @devtype: Short string identifying the device type. - * @drvname: Driver .sys file name. - * @infostrs: Kernel vversion. - * @reserved: Pad size to 256 bytes. - * - * An array of this struct is present in the channel area for each vbus. It is - * filled in by the client side to provide info about the device and driver from - * the client's perspective. - */ -struct visor_vbus_deviceinfo { - u8 devtype[16]; - u8 drvname[16]; - u8 infostrs[96]; - u8 reserved[128]; -} __packed; - -/* - * struct visor_vbus_headerinfo - * @struct_bytes: Size of this struct in bytes. - * @device_info_struct_bytes: Size of VISOR_VBUS_DEVICEINFO. - * @dev_info_count: Num of items in DevInfo member. This is the - * allocated size. - * @chp_info_offset: Byte offset from beginning of this struct to the - * ChpInfo struct. - * @bus_info_offset: Byte offset from beginning of this struct to the - * BusInfo struct. - * @dev_info_offset: Byte offset from beginning of this struct to the - * DevInfo array. - * @reserved: Natural alignment. - */ -struct visor_vbus_headerinfo { - u32 struct_bytes; - u32 device_info_struct_bytes; - u32 dev_info_count; - u32 chp_info_offset; - u32 bus_info_offset; - u32 dev_info_offset; - u8 reserved[104]; -} __packed; - -/* - * struct visor_vbus_channel - * @channel_header: Initialized by server. - * @hdr_info: Initialized by server. - * @chp_info: Describes client chipset device and driver. - * @bus_info: Describes client bus device and driver. - * @dev_info: Describes client device and driver for each device on the - * bus. - */ -struct visor_vbus_channel { - struct channel_header channel_header; - struct visor_vbus_headerinfo hdr_info; - struct visor_vbus_deviceinfo chp_info; - struct visor_vbus_deviceinfo bus_info; - struct visor_vbus_deviceinfo dev_info[0]; -} __packed; - -#endif diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c deleted file mode 100644 index 6cb6eb0673c6..000000000000 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ /dev/null @@ -1,1243 +0,0 @@ -/* - * Copyright � 2010 - 2015 UNISYS CORPORATION - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - */ - -#include <linux/ctype.h> -#include <linux/debugfs.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/uuid.h> - -#include "visorbus.h" -#include "visorbus_private.h" - -static const guid_t visor_vbus_channel_guid = VISOR_VBUS_CHANNEL_GUID; - -/* Display string that is guaranteed to be no longer the 99 characters */ -#define LINESIZE 99 -#define POLLJIFFIES_NORMALCHANNEL 10 - -/* stores whether bus_registration was successful */ -static bool initialized; -static struct dentry *visorbus_debugfs_dir; - -/* - * DEVICE type attributes - * - * The modalias file will contain the guid of the device. - */ -static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct visor_device *vdev; - const guid_t *guid; - - vdev = to_visor_device(dev); - guid = visorchannel_get_guid(vdev->visorchannel); - return sprintf(buf, "visorbus:%pUl\n", guid); -} -static DEVICE_ATTR_RO(modalias); - -static struct attribute *visorbus_dev_attrs[] = { - &dev_attr_modalias.attr, - NULL, -}; - -ATTRIBUTE_GROUPS(visorbus_dev); - -/* filled in with info about parent chipset driver when we register with it */ -static struct visor_vbus_deviceinfo chipset_driverinfo; -/* filled in with info about this driver, wrt it servicing client busses */ -static struct visor_vbus_deviceinfo clientbus_driverinfo; - -/* list of visor_device structs, linked via .list_all */ -static LIST_HEAD(list_all_bus_instances); -/* list of visor_device structs, linked via .list_all */ -static LIST_HEAD(list_all_device_instances); - -/* - * Generic function useful for validating any type of channel when it is - * received by the client that will be accessing the channel. - * Note that <logCtx> is only needed for callers in the EFI environment, and - * is used to pass the EFI_DIAG_CAPTURE_PROTOCOL needed to log messages. - */ -int visor_check_channel(struct channel_header *ch, struct device *dev, - const guid_t *expected_guid, char *chname, - u64 expected_min_bytes, u32 expected_version, - u64 expected_signature) -{ - if (!guid_is_null(expected_guid)) { - /* caller wants us to verify type GUID */ - if (!guid_equal(&ch->chtype, expected_guid)) { - dev_err(dev, "Channel mismatch on channel=%s(%pUL) field=type expected=%pUL actual=%pUL\n", - chname, expected_guid, expected_guid, - &ch->chtype); - return 0; - } - } - /* verify channel size */ - if (expected_min_bytes > 0) { - if (ch->size < expected_min_bytes) { - dev_err(dev, "Channel mismatch on channel=%s(%pUL) field=size expected=0x%-8.8Lx actual=0x%-8.8Lx\n", - chname, expected_guid, - (unsigned long long)expected_min_bytes, - ch->size); - return 0; - } - } - /* verify channel version */ - if (expected_version > 0) { - if (ch->version_id != expected_version) { - dev_err(dev, "Channel mismatch on channel=%s(%pUL) field=version expected=0x%-8.8lx actual=0x%-8.8x\n", - chname, expected_guid, - (unsigned long)expected_version, - ch->version_id); - return 0; - } - } - /* verify channel signature */ - if (expected_signature > 0) { - if (ch->signature != expected_signature) { - dev_err(dev, "Channel mismatch on channel=%s(%pUL) field=signature expected=0x%-8.8Lx actual=0x%-8.8Lx\n", - chname, expected_guid, expected_signature, - ch->signature); - return 0; - } - } - return 1; -} - -static int visorbus_uevent(struct device *xdev, struct kobj_uevent_env *env) -{ - struct visor_device *dev; - const guid_t *guid; - - dev = to_visor_device(xdev); - guid = visorchannel_get_guid(dev->visorchannel); - return add_uevent_var(env, "MODALIAS=visorbus:%pUl", guid); -} - -/* - * visorbus_match() - called automatically upon adding a visor_device - * (device_add), or adding a visor_driver - * (visorbus_register_visor_driver) - * @xdev: struct device for the device being matched - * @xdrv: struct device_driver for driver to match device against - * - * Return: 1 iff the provided driver can control the specified device - */ -static int visorbus_match(struct device *xdev, struct device_driver *xdrv) -{ - const guid_t *channel_type; - int i; - struct visor_device *dev; - struct visor_driver *drv; - struct visorchannel *chan; - - dev = to_visor_device(xdev); - channel_type = visorchannel_get_guid(dev->visorchannel); - drv = to_visor_driver(xdrv); - chan = dev->visorchannel; - if (!drv->channel_types) - return 0; - for (i = 0; !guid_is_null(&drv->channel_types[i].guid); i++) - if (guid_equal(&drv->channel_types[i].guid, channel_type) && - visor_check_channel(visorchannel_get_header(chan), - xdev, - &drv->channel_types[i].guid, - (char *)drv->channel_types[i].name, - drv->channel_types[i].min_bytes, - drv->channel_types[i].version, - VISOR_CHANNEL_SIGNATURE)) - return i + 1; - return 0; -} - -/* - * This describes the TYPE of bus. - * (Don't confuse this with an INSTANCE of the bus.) - */ -static struct bus_type visorbus_type = { - .name = "visorbus", - .match = visorbus_match, - .uevent = visorbus_uevent, - .dev_groups = visorbus_dev_groups, -}; - -struct visor_busdev { - u32 bus_no; - u32 dev_no; -}; - -static int match_visorbus_dev_by_id(struct device *dev, void *data) -{ - struct visor_device *vdev = to_visor_device(dev); - struct visor_busdev *id = data; - - if (vdev->chipset_bus_no == id->bus_no && - vdev->chipset_dev_no == id->dev_no) - return 1; - return 0; -} - -struct visor_device *visorbus_get_device_by_id(u32 bus_no, u32 dev_no, - struct visor_device *from) -{ - struct device *dev; - struct device *dev_start = NULL; - struct visor_busdev id = { - .bus_no = bus_no, - .dev_no = dev_no - }; - - if (from) - dev_start = &from->device; - dev = bus_find_device(&visorbus_type, dev_start, (void *)&id, - match_visorbus_dev_by_id); - if (!dev) - return NULL; - return to_visor_device(dev); -} - -/* - * visorbus_release_busdevice() - called when device_unregister() is called for - * the bus device instance, after all other tasks - * involved with destroying the dev are complete - * @xdev: struct device for the bus being released - */ -static void visorbus_release_busdevice(struct device *xdev) -{ - struct visor_device *dev = dev_get_drvdata(xdev); - - debugfs_remove(dev->debugfs_bus_info); - debugfs_remove_recursive(dev->debugfs_dir); - visorchannel_destroy(dev->visorchannel); - kfree(dev); -} - -/* - * visorbus_release_device() - called when device_unregister() is called for - * each child device instance - * @xdev: struct device for the visor device being released - */ -static void visorbus_release_device(struct device *xdev) -{ - struct visor_device *dev = to_visor_device(xdev); - - visorchannel_destroy(dev->visorchannel); - kfree(dev); -} - -/* - * BUS specific channel attributes to appear under - * /sys/bus/visorbus<x>/dev<y>/channel - */ - -static ssize_t physaddr_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct visor_device *vdev = to_visor_device(dev); - - return sprintf(buf, "0x%llx\n", - visorchannel_get_physaddr(vdev->visorchannel)); -} -static DEVICE_ATTR_RO(physaddr); - -static ssize_t nbytes_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct visor_device *vdev = to_visor_device(dev); - - return sprintf(buf, "0x%lx\n", - visorchannel_get_nbytes(vdev->visorchannel)); -} -static DEVICE_ATTR_RO(nbytes); - -static ssize_t clientpartition_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct visor_device *vdev = to_visor_device(dev); - - return sprintf(buf, "0x%llx\n", - visorchannel_get_clientpartition(vdev->visorchannel)); -} -static DEVICE_ATTR_RO(clientpartition); - -static ssize_t typeguid_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct visor_device *vdev = to_visor_device(dev); - char typeid[LINESIZE]; - - return sprintf(buf, "%s\n", - visorchannel_id(vdev->visorchannel, typeid)); -} -static DEVICE_ATTR_RO(typeguid); - -static ssize_t zoneguid_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct visor_device *vdev = to_visor_device(dev); - char zoneid[LINESIZE]; - - return sprintf(buf, "%s\n", - visorchannel_zoneid(vdev->visorchannel, zoneid)); -} -static DEVICE_ATTR_RO(zoneguid); - -static ssize_t typename_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - int i = 0; - struct bus_type *xbus = dev->bus; - struct device_driver *xdrv = dev->driver; - struct visor_driver *drv = NULL; - - if (!xdrv) - return 0; - i = xbus->match(dev, xdrv); - if (!i) - return 0; - drv = to_visor_driver(xdrv); - return sprintf(buf, "%s\n", drv->channel_types[i - 1].name); -} -static DEVICE_ATTR_RO(typename); - -static struct attribute *channel_attrs[] = { - &dev_attr_physaddr.attr, - &dev_attr_nbytes.attr, - &dev_attr_clientpartition.attr, - &dev_attr_typeguid.attr, - &dev_attr_zoneguid.attr, - &dev_attr_typename.attr, - NULL -}; - -ATTRIBUTE_GROUPS(channel); - -/* - * BUS instance attributes - * - * define & implement display of bus attributes under - * /sys/bus/visorbus/devices/visorbus<n>. - */ -static ssize_t partition_handle_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct visor_device *vdev = to_visor_device(dev); - u64 handle = visorchannel_get_clientpartition(vdev->visorchannel); - - return sprintf(buf, "0x%llx\n", handle); -} -static DEVICE_ATTR_RO(partition_handle); - -static ssize_t partition_guid_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct visor_device *vdev = to_visor_device(dev); - - return sprintf(buf, "{%pUb}\n", &vdev->partition_guid); -} -static DEVICE_ATTR_RO(partition_guid); - -static ssize_t partition_name_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct visor_device *vdev = to_visor_device(dev); - - return sprintf(buf, "%s\n", vdev->name); -} -static DEVICE_ATTR_RO(partition_name); - -static ssize_t channel_addr_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct visor_device *vdev = to_visor_device(dev); - u64 addr = visorchannel_get_physaddr(vdev->visorchannel); - - return sprintf(buf, "0x%llx\n", addr); -} -static DEVICE_ATTR_RO(channel_addr); - -static ssize_t channel_bytes_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct visor_device *vdev = to_visor_device(dev); - u64 nbytes = visorchannel_get_nbytes(vdev->visorchannel); - - return sprintf(buf, "0x%llx\n", nbytes); -} -static DEVICE_ATTR_RO(channel_bytes); - -static ssize_t channel_id_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct visor_device *vdev = to_visor_device(dev); - int len = 0; - - visorchannel_id(vdev->visorchannel, buf); - len = strlen(buf); - buf[len++] = '\n'; - return len; -} -static DEVICE_ATTR_RO(channel_id); - -static struct attribute *visorbus_attrs[] = { - &dev_attr_partition_handle.attr, - &dev_attr_partition_guid.attr, - &dev_attr_partition_name.attr, - &dev_attr_channel_addr.attr, - &dev_attr_channel_bytes.attr, - &dev_attr_channel_id.attr, - NULL -}; - -ATTRIBUTE_GROUPS(visorbus); - -/* - * BUS debugfs entries - * - * define & implement display of debugfs attributes under - * /sys/kernel/debug/visorbus/visorbus<n>. - */ - -/* - * vbuschannel_print_devinfo() - format a struct visor_vbus_deviceinfo - * and write it to a seq_file - * @devinfo: the struct visor_vbus_deviceinfo to format - * @seq: seq_file to write to - * @devix: the device index to be included in the output data, or -1 if no - * device index is to be included - * - * Reads @devInfo, and writes it in human-readable notation to @seq. - */ -static void vbuschannel_print_devinfo(struct visor_vbus_deviceinfo *devinfo, - struct seq_file *seq, int devix) -{ - /* uninitialized vbus device entry */ - if (!isprint(devinfo->devtype[0])) - return; - if (devix >= 0) - seq_printf(seq, "[%d]", devix); - else - /* vbus device entry is for bus or chipset */ - seq_puts(seq, " "); - /* - * Note: because the s-Par back-end is free to scribble in this area, - * we never assume '\0'-termination. - */ - seq_printf(seq, "%-*.*s ", (int)sizeof(devinfo->devtype), - (int)sizeof(devinfo->devtype), devinfo->devtype); - seq_printf(seq, "%-*.*s ", (int)sizeof(devinfo->drvname), - (int)sizeof(devinfo->drvname), devinfo->drvname); - seq_printf(seq, "%.*s\n", (int)sizeof(devinfo->infostrs), - devinfo->infostrs); -} - -static int bus_info_debugfs_show(struct seq_file *seq, void *v) -{ - int i = 0; - unsigned long off; - struct visor_vbus_deviceinfo dev_info; - struct visor_device *vdev = seq->private; - struct visorchannel *channel = vdev->visorchannel; - - if (!channel) - return 0; - - seq_printf(seq, - "Client device/driver info for %s partition (vbus #%u):\n", - ((vdev->name) ? (char *)(vdev->name) : ""), - vdev->chipset_bus_no); - if (visorchannel_read(channel, - offsetof(struct visor_vbus_channel, chp_info), - &dev_info, sizeof(dev_info)) >= 0) - vbuschannel_print_devinfo(&dev_info, seq, -1); - if (visorchannel_read(channel, - offsetof(struct visor_vbus_channel, bus_info), - &dev_info, sizeof(dev_info)) >= 0) - vbuschannel_print_devinfo(&dev_info, seq, -1); - - off = offsetof(struct visor_vbus_channel, dev_info); - while (off + sizeof(dev_info) <= visorchannel_get_nbytes(channel)) { - if (visorchannel_read(channel, off, &dev_info, - sizeof(dev_info)) >= 0) - vbuschannel_print_devinfo(&dev_info, seq, i); - off += sizeof(dev_info); - i++; - } - return 0; -} - -static int bus_info_debugfs_open(struct inode *inode, struct file *file) -{ - return single_open(file, bus_info_debugfs_show, inode->i_private); -} - -static const struct file_operations bus_info_debugfs_fops = { - .owner = THIS_MODULE, - .open = bus_info_debugfs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static void dev_periodic_work(struct timer_list *t) -{ - struct visor_device *dev = from_timer(dev, t, timer); - struct visor_driver *drv = to_visor_driver(dev->device.driver); - - drv->channel_interrupt(dev); - mod_timer(&dev->timer, jiffies + POLLJIFFIES_NORMALCHANNEL); -} - -static int dev_start_periodic_work(struct visor_device *dev) -{ - if (dev->being_removed || dev->timer_active) - return -EINVAL; - - /* now up by at least 2 */ - get_device(&dev->device); - dev->timer.expires = jiffies + POLLJIFFIES_NORMALCHANNEL; - add_timer(&dev->timer); - dev->timer_active = true; - return 0; -} - -static void dev_stop_periodic_work(struct visor_device *dev) -{ - if (!dev->timer_active) - return; - - del_timer_sync(&dev->timer); - dev->timer_active = false; - put_device(&dev->device); -} - -/* - * visordriver_remove_device() - handle visor device going away - * @xdev: struct device for the visor device being removed - * - * This is called when device_unregister() is called for each child device - * instance, to notify the appropriate visorbus function driver that the device - * is going away, and to decrease the reference count of the device. - * - * Return: 0 iff successful - */ -static int visordriver_remove_device(struct device *xdev) -{ - struct visor_device *dev = to_visor_device(xdev); - struct visor_driver *drv = to_visor_driver(xdev->driver); - - mutex_lock(&dev->visordriver_callback_lock); - dev->being_removed = true; - drv->remove(dev); - mutex_unlock(&dev->visordriver_callback_lock); - dev_stop_periodic_work(dev); - put_device(&dev->device); - return 0; -} - -/* - * visorbus_unregister_visor_driver() - unregisters the provided driver - * @drv: the driver to unregister - * - * A visor function driver calls this function to unregister the driver, - * i.e., within its module_exit function. - */ -void visorbus_unregister_visor_driver(struct visor_driver *drv) -{ - driver_unregister(&drv->driver); -} -EXPORT_SYMBOL_GPL(visorbus_unregister_visor_driver); - -/* - * visorbus_read_channel() - reads from the designated channel into - * the provided buffer - * @dev: the device whose channel is read from - * @offset: the offset into the channel at which reading starts - * @dest: the destination buffer that is written into from the channel - * @nbytes: the number of bytes to read from the channel - * - * If receiving a message, use the visorchannel_signalremove() function instead. - * - * Return: integer indicating success (zero) or failure (non-zero) - */ -int visorbus_read_channel(struct visor_device *dev, unsigned long offset, - void *dest, unsigned long nbytes) -{ - return visorchannel_read(dev->visorchannel, offset, dest, nbytes); -} -EXPORT_SYMBOL_GPL(visorbus_read_channel); - -/* - * visorbus_write_channel() - writes the provided buffer into the designated - * channel - * @dev: the device whose channel is written to - * @offset: the offset into the channel at which writing starts - * @src: the source buffer that is written into the channel - * @nbytes: the number of bytes to write into the channel - * - * If sending a message, use the visorchannel_signalinsert() function instead. - * - * Return: integer indicating success (zero) or failure (non-zero) - */ -int visorbus_write_channel(struct visor_device *dev, unsigned long offset, - void *src, unsigned long nbytes) -{ - return visorchannel_write(dev->visorchannel, offset, src, nbytes); -} -EXPORT_SYMBOL_GPL(visorbus_write_channel); - -/* - * visorbus_enable_channel_interrupts() - enables interrupts on the - * designated device - * @dev: the device on which to enable interrupts - * - * Currently we don't yet have a real interrupt, so for now we just call the - * interrupt function periodically via a timer. - */ -int visorbus_enable_channel_interrupts(struct visor_device *dev) -{ - struct visor_driver *drv = to_visor_driver(dev->device.driver); - - if (!drv->channel_interrupt) { - dev_err(&dev->device, "%s no interrupt function!\n", __func__); - return -ENOENT; - } - - return dev_start_periodic_work(dev); -} -EXPORT_SYMBOL_GPL(visorbus_enable_channel_interrupts); - -/* - * visorbus_disable_channel_interrupts() - disables interrupts on the - * designated device - * @dev: the device on which to disable interrupts - */ -void visorbus_disable_channel_interrupts(struct visor_device *dev) -{ - dev_stop_periodic_work(dev); -} -EXPORT_SYMBOL_GPL(visorbus_disable_channel_interrupts); - -/* - * create_visor_device() - create visor device as a result of receiving the - * controlvm device_create message for a new device - * @dev: a freshly-zeroed struct visor_device, containing only filled-in values - * for chipset_bus_no and chipset_dev_no, that will be initialized - * - * This is how everything starts from the device end. - * This function is called when a channel first appears via a ControlVM - * message. In response, this function allocates a visor_device to correspond - * to the new channel, and attempts to connect it the appropriate * driver. If - * the appropriate driver is found, the visor_driver.probe() function for that - * driver will be called, and will be passed the new * visor_device that we - * just created. - * - * It's ok if the appropriate driver is not yet loaded, because in that case - * the new device struct will just stick around in the bus' list of devices. - * When the appropriate driver calls visorbus_register_visor_driver(), the - * visor_driver.probe() for the new driver will be called with the new device. - * - * Return: 0 if successful, otherwise the negative value returned by - * device_add() indicating the reason for failure - */ -int create_visor_device(struct visor_device *dev) -{ - int err; - u32 chipset_bus_no = dev->chipset_bus_no; - u32 chipset_dev_no = dev->chipset_dev_no; - - mutex_init(&dev->visordriver_callback_lock); - dev->device.bus = &visorbus_type; - dev->device.groups = channel_groups; - device_initialize(&dev->device); - dev->device.release = visorbus_release_device; - /* keep a reference just for us (now 2) */ - get_device(&dev->device); - timer_setup(&dev->timer, dev_periodic_work, 0); - /* - * bus_id must be a unique name with respect to this bus TYPE (NOT bus - * instance). That's why we need to include the bus number within the - * name. - */ - err = dev_set_name(&dev->device, "vbus%u:dev%u", - chipset_bus_no, chipset_dev_no); - if (err) - goto err_put; - /* - * device_add does this: - * bus_add_device(dev) - * ->device_attach(dev) - * ->for each driver drv registered on the bus that dev is on - * if (dev.drv) ** device already has a driver ** - * ** not sure we could ever get here... ** - * else - * if (bus.match(dev,drv)) [visorbus_match] - * dev.drv = drv - * if (!drv.probe(dev)) [visordriver_probe_device] - * dev.drv = NULL - * - * Note that device_add does NOT fail if no driver failed to claim the - * device. The device will be linked onto bus_type.klist_devices - * regardless (use bus_for_each_dev). - */ - err = device_add(&dev->device); - if (err < 0) - goto err_put; - list_add_tail(&dev->list_all, &list_all_device_instances); - dev->state.created = 1; - visorbus_response(dev, err, CONTROLVM_DEVICE_CREATE); - /* success: reference kept via unmatched get_device() */ - return 0; - -err_put: - put_device(&dev->device); - dev_err(&dev->device, "Creating visor device failed. %d\n", err); - return err; -} - -void remove_visor_device(struct visor_device *dev) -{ - list_del(&dev->list_all); - put_device(&dev->device); - if (dev->pending_msg_hdr) - visorbus_response(dev, 0, CONTROLVM_DEVICE_DESTROY); - device_unregister(&dev->device); -} - -static int get_vbus_header_info(struct visorchannel *chan, - struct device *dev, - struct visor_vbus_headerinfo *hdr_info) -{ - int err; - - if (!visor_check_channel(visorchannel_get_header(chan), - dev, - &visor_vbus_channel_guid, - "vbus", - sizeof(struct visor_vbus_channel), - VISOR_VBUS_CHANNEL_VERSIONID, - VISOR_CHANNEL_SIGNATURE)) - return -EINVAL; - - err = visorchannel_read(chan, sizeof(struct channel_header), hdr_info, - sizeof(*hdr_info)); - if (err < 0) - return err; - if (hdr_info->struct_bytes < sizeof(struct visor_vbus_headerinfo)) - return -EINVAL; - if (hdr_info->device_info_struct_bytes < - sizeof(struct visor_vbus_deviceinfo)) - return -EINVAL; - return 0; -} - -/* - * write_vbus_chp_info() - write the contents of <info> to the struct - * visor_vbus_channel.chp_info - * @chan: indentifies the s-Par channel that will be updated - * @hdr_info: used to find appropriate channel offset to write data - * @info: contains the information to write - * - * Writes chipset info into the channel memory to be used for diagnostic - * purposes. - * - * Returns no value since this is debug information and not needed for - * device functionality. - */ -static void write_vbus_chp_info(struct visorchannel *chan, - struct visor_vbus_headerinfo *hdr_info, - struct visor_vbus_deviceinfo *info) -{ - int off; - - if (hdr_info->chp_info_offset == 0) - return; - - off = sizeof(struct channel_header) + hdr_info->chp_info_offset; - visorchannel_write(chan, off, info, sizeof(*info)); -} - -/* - * write_vbus_bus_info() - write the contents of <info> to the struct - * visor_vbus_channel.bus_info - * @chan: indentifies the s-Par channel that will be updated - * @hdr_info: used to find appropriate channel offset to write data - * @info: contains the information to write - * - * Writes bus info into the channel memory to be used for diagnostic - * purposes. - * - * Returns no value since this is debug information and not needed for - * device functionality. - */ -static void write_vbus_bus_info(struct visorchannel *chan, - struct visor_vbus_headerinfo *hdr_info, - struct visor_vbus_deviceinfo *info) -{ - int off; - - if (hdr_info->bus_info_offset == 0) - return; - - off = sizeof(struct channel_header) + hdr_info->bus_info_offset; - visorchannel_write(chan, off, info, sizeof(*info)); -} - -/* - * write_vbus_dev_info() - write the contents of <info> to the struct - * visor_vbus_channel.dev_info[<devix>] - * @chan: indentifies the s-Par channel that will be updated - * @hdr_info: used to find appropriate channel offset to write data - * @info: contains the information to write - * @devix: the relative device number (0..n-1) of the device on the bus - * - * Writes device info into the channel memory to be used for diagnostic - * purposes. - * - * Returns no value since this is debug information and not needed for - * device functionality. - */ -static void write_vbus_dev_info(struct visorchannel *chan, - struct visor_vbus_headerinfo *hdr_info, - struct visor_vbus_deviceinfo *info, - unsigned int devix) -{ - int off; - - if (hdr_info->dev_info_offset == 0) - return; - off = (sizeof(struct channel_header) + hdr_info->dev_info_offset) + - (hdr_info->device_info_struct_bytes * devix); - visorchannel_write(chan, off, info, sizeof(*info)); -} - -static void bus_device_info_init( - struct visor_vbus_deviceinfo *bus_device_info_ptr, - const char *dev_type, const char *drv_name) -{ - memset(bus_device_info_ptr, 0, sizeof(struct visor_vbus_deviceinfo)); - snprintf(bus_device_info_ptr->devtype, - sizeof(bus_device_info_ptr->devtype), - "%s", (dev_type) ? dev_type : "unknownType"); - snprintf(bus_device_info_ptr->drvname, - sizeof(bus_device_info_ptr->drvname), - "%s", (drv_name) ? drv_name : "unknownDriver"); - snprintf(bus_device_info_ptr->infostrs, - sizeof(bus_device_info_ptr->infostrs), "kernel ver. %s", - utsname()->release); -} - -/* - * publish_vbus_dev_info() - for a child device just created on a client bus, - * fill in information about the driver that is - * controlling this device into the appropriate slot - * within the vbus channel of the bus instance - * @visordev: struct visor_device for the desired device - */ -static void publish_vbus_dev_info(struct visor_device *visordev) -{ - int i; - struct visor_device *bdev; - struct visor_driver *visordrv; - u32 bus_no = visordev->chipset_bus_no; - u32 dev_no = visordev->chipset_dev_no; - struct visor_vbus_deviceinfo dev_info; - const char *chan_type_name = NULL; - struct visor_vbus_headerinfo *hdr_info; - - if (!visordev->device.driver) - return; - bdev = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL); - if (!bdev) - return; - hdr_info = (struct visor_vbus_headerinfo *)bdev->vbus_hdr_info; - if (!hdr_info) - return; - visordrv = to_visor_driver(visordev->device.driver); - - /* - * Within the list of device types (by GUID) that the driver - * says it supports, find out which one of those types matches - * the type of this device, so that we can include the device - * type name - */ - for (i = 0; visordrv->channel_types[i].name; i++) { - if (guid_equal(&visordrv->channel_types[i].guid, - &visordev->channel_type_guid)) { - chan_type_name = visordrv->channel_types[i].name; - break; - } - } - bus_device_info_init(&dev_info, chan_type_name, visordrv->name); - write_vbus_dev_info(bdev->visorchannel, hdr_info, &dev_info, dev_no); - write_vbus_chp_info(bdev->visorchannel, hdr_info, &chipset_driverinfo); - write_vbus_bus_info(bdev->visorchannel, hdr_info, - &clientbus_driverinfo); -} - -/* - * visordriver_probe_device() - handle new visor device coming online - * @xdev: struct device for the visor device being probed - * - * This is called automatically upon adding a visor_device (device_add), or - * adding a visor_driver (visorbus_register_visor_driver), but only after - * visorbus_match() has returned 1 to indicate a successful match between - * driver and device. - * - * If successful, a reference to the device will be held onto via get_device(). - * - * Return: 0 if successful, meaning the function driver's probe() function - * was successful with this device, otherwise a negative errno - * value indicating failure reason - */ -static int visordriver_probe_device(struct device *xdev) -{ - int err; - struct visor_driver *drv = to_visor_driver(xdev->driver); - struct visor_device *dev = to_visor_device(xdev); - - mutex_lock(&dev->visordriver_callback_lock); - dev->being_removed = false; - err = drv->probe(dev); - if (err) { - mutex_unlock(&dev->visordriver_callback_lock); - return err; - } - /* success: reference kept via unmatched get_device() */ - get_device(&dev->device); - publish_vbus_dev_info(dev); - mutex_unlock(&dev->visordriver_callback_lock); - return 0; -} - -/* - * visorbus_register_visor_driver() - registers the provided visor driver for - * handling one or more visor device - * types (channel_types) - * @drv: the driver to register - * - * A visor function driver calls this function to register the driver. The - * caller MUST fill in the following fields within the #drv structure: - * name, version, owner, channel_types, probe, remove - * - * Here's how the whole Linux bus / driver / device model works. - * - * At system start-up, the visorbus kernel module is loaded, which registers - * visorbus_type as a bus type, using bus_register(). - * - * All kernel modules that support particular device types on a - * visorbus bus are loaded. Each of these kernel modules calls - * visorbus_register_visor_driver() in their init functions, passing a - * visor_driver struct. visorbus_register_visor_driver() in turn calls - * register_driver(&visor_driver.driver). This .driver member is - * initialized with generic methods (like probe), whose sole responsibility - * is to act as a broker for the real methods, which are within the - * visor_driver struct. (This is the way the subclass behavior is - * implemented, since visor_driver is essentially a subclass of the - * generic driver.) Whenever a driver_register() happens, core bus code in - * the kernel does (see device_attach() in drivers/base/dd.c): - * - * for each dev associated with the bus (the bus that driver is on) that - * does not yet have a driver - * if bus.match(dev,newdriver) == yes_matched ** .match specified - * ** during bus_register(). - * newdriver.probe(dev) ** for visor drivers, this will call - * ** the generic driver.probe implemented in visorbus.c, - * ** which in turn calls the probe specified within the - * ** struct visor_driver (which was specified by the - * ** actual device driver as part of - * ** visorbus_register_visor_driver()). - * - * The above dance also happens when a new device appears. - * So the question is, how are devices created within the system? - * Basically, just call device_add(dev). See pci_bus_add_devices(). - * pci_scan_device() shows an example of how to build a device struct. It - * returns the newly-created struct to pci_scan_single_device(), who adds it - * to the list of devices at PCIBUS.devices. That list of devices is what - * is traversed by pci_bus_add_devices(). - * - * Return: integer indicating success (zero) or failure (non-zero) - */ -int visorbus_register_visor_driver(struct visor_driver *drv) -{ - /* can't register on a nonexistent bus */ - if (!initialized) - return -ENODEV; - if (!drv->probe) - return -EINVAL; - if (!drv->remove) - return -EINVAL; - if (!drv->pause) - return -EINVAL; - if (!drv->resume) - return -EINVAL; - - drv->driver.name = drv->name; - drv->driver.bus = &visorbus_type; - drv->driver.probe = visordriver_probe_device; - drv->driver.remove = visordriver_remove_device; - drv->driver.owner = drv->owner; - /* - * driver_register does this: - * bus_add_driver(drv) - * ->if (drv.bus) ** (bus_type) ** - * driver_attach(drv) - * for each dev with bus type of drv.bus - * if (!dev.drv) ** no driver assigned yet ** - * if (bus.match(dev,drv)) [visorbus_match] - * dev.drv = drv - * if (!drv.probe(dev)) [visordriver_probe_device] - * dev.drv = NULL - */ - return driver_register(&drv->driver); -} -EXPORT_SYMBOL_GPL(visorbus_register_visor_driver); - -/* - * visorbus_create_instance() - create a device instance for the visorbus itself - * @dev: struct visor_device indicating the bus instance - * - * Return: 0 for success, otherwise negative errno value indicating reason for - * failure - */ -int visorbus_create_instance(struct visor_device *dev) -{ - int id = dev->chipset_bus_no; - int err; - struct visor_vbus_headerinfo *hdr_info; - - hdr_info = kzalloc(sizeof(*hdr_info), GFP_KERNEL); - if (!hdr_info) - return -ENOMEM; - dev_set_name(&dev->device, "visorbus%d", id); - dev->device.bus = &visorbus_type; - dev->device.groups = visorbus_groups; - dev->device.release = visorbus_release_busdevice; - dev->debugfs_dir = debugfs_create_dir(dev_name(&dev->device), - visorbus_debugfs_dir); - dev->debugfs_bus_info = debugfs_create_file("client_bus_info", 0440, - dev->debugfs_dir, dev, - &bus_info_debugfs_fops); - dev_set_drvdata(&dev->device, dev); - err = get_vbus_header_info(dev->visorchannel, &dev->device, hdr_info); - if (err < 0) - goto err_debugfs_dir; - err = device_register(&dev->device); - if (err < 0) - goto err_debugfs_dir; - list_add_tail(&dev->list_all, &list_all_bus_instances); - dev->state.created = 1; - dev->vbus_hdr_info = (void *)hdr_info; - write_vbus_chp_info(dev->visorchannel, hdr_info, &chipset_driverinfo); - write_vbus_bus_info(dev->visorchannel, hdr_info, &clientbus_driverinfo); - visorbus_response(dev, err, CONTROLVM_BUS_CREATE); - return 0; - -err_debugfs_dir: - debugfs_remove_recursive(dev->debugfs_dir); - kfree(hdr_info); - dev_err(&dev->device, "%s failed: %d\n", __func__, err); - return err; -} - -/* - * visorbus_remove_instance() - remove a device instance for the visorbus itself - * @dev: struct visor_device indentifying the bus to remove - */ -void visorbus_remove_instance(struct visor_device *dev) -{ - /* - * Note that this will result in the release method for - * dev->dev being called, which will call - * visorbus_release_busdevice(). This has something to do with - * the put_device() done in device_unregister(), but I have never - * successfully been able to trace thru the code to see where/how - * release() gets called. But I know it does. - */ - kfree(dev->vbus_hdr_info); - list_del(&dev->list_all); - if (dev->pending_msg_hdr) - visorbus_response(dev, 0, CONTROLVM_BUS_DESTROY); - device_unregister(&dev->device); -} - -/* - * remove_all_visor_devices() - remove all child visorbus device instances - */ -static void remove_all_visor_devices(void) -{ - struct list_head *listentry, *listtmp; - - list_for_each_safe(listentry, listtmp, &list_all_device_instances) { - struct visor_device *dev; - - dev = list_entry(listentry, struct visor_device, list_all); - remove_visor_device(dev); - } -} - -/* - * pause_state_change_complete() - the callback function to be called by a - * visorbus function driver when a - * pending "pause device" operation has - * completed - * @dev: struct visor_device identifying the paused device - * @status: 0 iff the pause state change completed successfully, otherwise - * a negative errno value indicating the reason for failure - */ -static void pause_state_change_complete(struct visor_device *dev, int status) -{ - if (!dev->pausing) - return; - - dev->pausing = false; - visorbus_device_changestate_response(dev, status, - segment_state_standby); -} - -/* - * resume_state_change_complete() - the callback function to be called by a - * visorbus function driver when a - * pending "resume device" operation has - * completed - * @dev: struct visor_device identifying the resumed device - * @status: 0 iff the resume state change completed successfully, otherwise - * a negative errno value indicating the reason for failure - */ -static void resume_state_change_complete(struct visor_device *dev, int status) -{ - if (!dev->resuming) - return; - - dev->resuming = false; - /* - * Notify the chipset driver that the resume is complete, - * which will presumably want to send some sort of response to - * the initiator. - */ - visorbus_device_changestate_response(dev, status, - segment_state_running); -} - -/* - * visorchipset_initiate_device_pause_resume() - start a pause or resume - * operation for a visor device - * @dev: struct visor_device identifying the device being paused or resumed - * @is_pause: true to indicate pause operation, false to indicate resume - * - * Tell the subordinate function driver for a specific device to pause - * or resume that device. Success/failure result is returned asynchronously - * via a callback function; see pause_state_change_complete() and - * resume_state_change_complete(). - */ -static int visorchipset_initiate_device_pause_resume(struct visor_device *dev, - bool is_pause) -{ - int err; - struct visor_driver *drv; - - /* If no driver associated with the device nothing to pause/resume */ - if (!dev->device.driver) - return 0; - if (dev->pausing || dev->resuming) - return -EBUSY; - - drv = to_visor_driver(dev->device.driver); - if (is_pause) { - dev->pausing = true; - err = drv->pause(dev, pause_state_change_complete); - } else { - /* - * The vbus_dev_info structure in the channel was been cleared, - * make sure it is valid. - */ - publish_vbus_dev_info(dev); - dev->resuming = true; - err = drv->resume(dev, resume_state_change_complete); - } - return err; -} - -/* - * visorchipset_device_pause() - start a pause operation for a visor device - * @dev_info: struct visor_device identifying the device being paused - * - * Tell the subordinate function driver for a specific device to pause - * that device. Success/failure result is returned asynchronously - * via a callback function; see pause_state_change_complete(). - */ -int visorchipset_device_pause(struct visor_device *dev_info) -{ - int err; - - err = visorchipset_initiate_device_pause_resume(dev_info, true); - if (err < 0) { - dev_info->pausing = false; - return err; - } - return 0; -} - -/* - * visorchipset_device_resume() - start a resume operation for a visor device - * @dev_info: struct visor_device identifying the device being resumed - * - * Tell the subordinate function driver for a specific device to resume - * that device. Success/failure result is returned asynchronously - * via a callback function; see resume_state_change_complete(). - */ -int visorchipset_device_resume(struct visor_device *dev_info) -{ - int err; - - err = visorchipset_initiate_device_pause_resume(dev_info, false); - if (err < 0) { - dev_info->resuming = false; - return err; - } - return 0; -} - -int visorbus_init(void) -{ - int err; - - visorbus_debugfs_dir = debugfs_create_dir("visorbus", NULL); - bus_device_info_init(&clientbus_driverinfo, "clientbus", "visorbus"); - err = bus_register(&visorbus_type); - if (err < 0) - return err; - initialized = true; - bus_device_info_init(&chipset_driverinfo, "chipset", "visorchipset"); - return 0; -} - -void visorbus_exit(void) -{ - struct list_head *listentry, *listtmp; - - remove_all_visor_devices(); - list_for_each_safe(listentry, listtmp, &list_all_bus_instances) { - struct visor_device *dev; - - dev = list_entry(listentry, struct visor_device, list_all); - visorbus_remove_instance(dev); - } - bus_unregister(&visorbus_type); - initialized = false; - debugfs_remove_recursive(visorbus_debugfs_dir); -} diff --git a/drivers/staging/unisys/visorbus/visorbus_private.h b/drivers/staging/unisys/visorbus/visorbus_private.h deleted file mode 100644 index 4a8b12d7cfaa..000000000000 --- a/drivers/staging/unisys/visorbus/visorbus_private.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2010 - 2015 UNISYS CORPORATION - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - */ - -#ifndef __VISORBUS_PRIVATE_H__ -#define __VISORBUS_PRIVATE_H__ - -#include <linux/uuid.h> -#include <linux/utsname.h> - -#include "controlvmchannel.h" -#include "vbuschannel.h" -#include "visorbus.h" - -struct visor_device *visorbus_get_device_by_id(u32 bus_no, u32 dev_no, - struct visor_device *from); -int visorbus_create_instance(struct visor_device *dev); -void visorbus_remove_instance(struct visor_device *bus_info); -int create_visor_device(struct visor_device *dev_info); -void remove_visor_device(struct visor_device *dev_info); -int visorchipset_device_pause(struct visor_device *dev_info); -int visorchipset_device_resume(struct visor_device *dev_info); -void visorbus_response(struct visor_device *p, int response, int controlvm_id); -void visorbus_device_changestate_response(struct visor_device *p, int response, - struct visor_segment_state state); -int visorbus_init(void); -void visorbus_exit(void); - -/* visorchannel access functions */ -struct visorchannel *visorchannel_create(u64 physaddr, gfp_t gfp, - const guid_t *guid, bool needs_lock); -void visorchannel_destroy(struct visorchannel *channel); -int visorchannel_read(struct visorchannel *channel, ulong offset, - void *dest, ulong nbytes); -int visorchannel_write(struct visorchannel *channel, ulong offset, - void *dest, ulong nbytes); -u64 visorchannel_get_physaddr(struct visorchannel *channel); -ulong visorchannel_get_nbytes(struct visorchannel *channel); -char *visorchannel_id(struct visorchannel *channel, char *s); -char *visorchannel_zoneid(struct visorchannel *channel, char *s); -u64 visorchannel_get_clientpartition(struct visorchannel *channel); -int visorchannel_set_clientpartition(struct visorchannel *channel, - u64 partition_handle); -char *visorchannel_guid_id(const guid_t *guid, char *s); -void *visorchannel_get_header(struct visorchannel *channel); -#endif diff --git a/drivers/staging/unisys/visorbus/visorchannel.c b/drivers/staging/unisys/visorbus/visorchannel.c deleted file mode 100644 index aae16073ba03..000000000000 --- a/drivers/staging/unisys/visorbus/visorchannel.c +++ /dev/null @@ -1,443 +0,0 @@ -/* - * Copyright (C) 2010 - 2015 UNISYS CORPORATION - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - */ - -/* - * This provides s-Par channel communication primitives, which are - * independent of the mechanism used to access the channel data. - */ - -#include <linux/uuid.h> -#include <linux/io.h> -#include <linux/slab.h> - -#include "visorbus.h" -#include "visorbus_private.h" -#include "controlvmchannel.h" - -#define VISOR_DRV_NAME "visorchannel" - -#define VISOR_CONSOLEVIDEO_CHANNEL_GUID \ - GUID_INIT(0x3cd6e705, 0xd6a2, 0x4aa5, \ - 0xad, 0x5c, 0x7b, 0x8, 0x88, 0x9d, 0xff, 0xe2) - -static const guid_t visor_video_guid = VISOR_CONSOLEVIDEO_CHANNEL_GUID; - -struct visorchannel { - u64 physaddr; - ulong nbytes; - void *mapped; - bool requested; - struct channel_header chan_hdr; - guid_t guid; - /* - * channel creator knows if more than one thread will be inserting or - * removing - */ - bool needs_lock; - /* protect head writes in chan_hdr */ - spinlock_t insert_lock; - /* protect tail writes in chan_hdr */ - spinlock_t remove_lock; - guid_t type; - guid_t inst; -}; - -void visorchannel_destroy(struct visorchannel *channel) -{ - if (!channel) - return; - - if (channel->mapped) { - memunmap(channel->mapped); - if (channel->requested) - release_mem_region(channel->physaddr, channel->nbytes); - } - kfree(channel); -} - -u64 visorchannel_get_physaddr(struct visorchannel *channel) -{ - return channel->physaddr; -} - -ulong visorchannel_get_nbytes(struct visorchannel *channel) -{ - return channel->nbytes; -} - -char *visorchannel_guid_id(const guid_t *guid, char *s) -{ - sprintf(s, "%pUL", guid); - return s; -} - -char *visorchannel_id(struct visorchannel *channel, char *s) -{ - return visorchannel_guid_id(&channel->guid, s); -} - -char *visorchannel_zoneid(struct visorchannel *channel, char *s) -{ - return visorchannel_guid_id(&channel->chan_hdr.zone_guid, s); -} - -u64 visorchannel_get_clientpartition(struct visorchannel *channel) -{ - return channel->chan_hdr.partition_handle; -} - -int visorchannel_set_clientpartition(struct visorchannel *channel, - u64 partition_handle) -{ - channel->chan_hdr.partition_handle = partition_handle; - return 0; -} - -/** - * visorchannel_get_guid() - queries the GUID of the designated channel - * @channel: the channel to query - * - * Return: the GUID of the provided channel - */ -const guid_t *visorchannel_get_guid(struct visorchannel *channel) -{ - return &channel->guid; -} -EXPORT_SYMBOL_GPL(visorchannel_get_guid); - -int visorchannel_read(struct visorchannel *channel, ulong offset, void *dest, - ulong nbytes) -{ - if (offset + nbytes > channel->nbytes) - return -EIO; - - memcpy(dest, channel->mapped + offset, nbytes); - return 0; -} - -int visorchannel_write(struct visorchannel *channel, ulong offset, void *dest, - ulong nbytes) -{ - size_t chdr_size = sizeof(struct channel_header); - size_t copy_size; - - if (offset + nbytes > channel->nbytes) - return -EIO; - - if (offset < chdr_size) { - copy_size = min(chdr_size - offset, nbytes); - memcpy(((char *)(&channel->chan_hdr)) + offset, - dest, copy_size); - } - memcpy(channel->mapped + offset, dest, nbytes); - return 0; -} - -void *visorchannel_get_header(struct visorchannel *channel) -{ - return &channel->chan_hdr; -} - -/* - * Return offset of a specific SIGNAL_QUEUE_HEADER from the beginning of a - * channel header - */ -static int sig_queue_offset(struct channel_header *chan_hdr, int q) -{ - return ((chan_hdr)->ch_space_offset + - ((q) * sizeof(struct signal_queue_header))); -} - -/* - * Return offset of a specific queue entry (data) from the beginning of a - * channel header - */ -static int sig_data_offset(struct channel_header *chan_hdr, int q, - struct signal_queue_header *sig_hdr, int slot) -{ - return (sig_queue_offset(chan_hdr, q) + sig_hdr->sig_base_offset + - (slot * sig_hdr->signal_size)); -} - -/* - * Write the contents of a specific field within a SIGNAL_QUEUE_HEADER back into - * host memory - */ -#define SIG_WRITE_FIELD(channel, queue, sig_hdr, FIELD) \ - visorchannel_write(channel, \ - sig_queue_offset(&channel->chan_hdr, queue) + \ - offsetof(struct signal_queue_header, FIELD), \ - &((sig_hdr)->FIELD), \ - sizeof((sig_hdr)->FIELD)) - -static int sig_read_header(struct visorchannel *channel, u32 queue, - struct signal_queue_header *sig_hdr) -{ - if (channel->chan_hdr.ch_space_offset < sizeof(struct channel_header)) - return -EINVAL; - - /* Read the appropriate SIGNAL_QUEUE_HEADER into local memory. */ - return visorchannel_read(channel, - sig_queue_offset(&channel->chan_hdr, queue), - sig_hdr, sizeof(struct signal_queue_header)); -} - -static int sig_read_data(struct visorchannel *channel, u32 queue, - struct signal_queue_header *sig_hdr, u32 slot, - void *data) -{ - int signal_data_offset = sig_data_offset(&channel->chan_hdr, queue, - sig_hdr, slot); - - return visorchannel_read(channel, signal_data_offset, - data, sig_hdr->signal_size); -} - -static int sig_write_data(struct visorchannel *channel, u32 queue, - struct signal_queue_header *sig_hdr, u32 slot, - void *data) -{ - int signal_data_offset = sig_data_offset(&channel->chan_hdr, queue, - sig_hdr, slot); - - return visorchannel_write(channel, signal_data_offset, - data, sig_hdr->signal_size); -} - -static int signalremove_inner(struct visorchannel *channel, u32 queue, - void *msg) -{ - struct signal_queue_header sig_hdr; - int error; - - error = sig_read_header(channel, queue, &sig_hdr); - if (error) - return error; - /* No signals to remove; have caller try again. */ - if (sig_hdr.head == sig_hdr.tail) - return -EAGAIN; - sig_hdr.tail = (sig_hdr.tail + 1) % sig_hdr.max_slots; - error = sig_read_data(channel, queue, &sig_hdr, sig_hdr.tail, msg); - if (error) - return error; - sig_hdr.num_received++; - /* - * For each data field in SIGNAL_QUEUE_HEADER that was modified, update - * host memory. Required for channel sync. - */ - mb(); - error = SIG_WRITE_FIELD(channel, queue, &sig_hdr, tail); - if (error) - return error; - error = SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_received); - if (error) - return error; - return 0; -} - -/** - * visorchannel_signalremove() - removes a message from the designated - * channel/queue - * @channel: the channel the message will be removed from - * @queue: the queue the message will be removed from - * @msg: the message to remove - * - * Return: integer error code indicating the status of the removal - */ -int visorchannel_signalremove(struct visorchannel *channel, u32 queue, - void *msg) -{ - int rc; - unsigned long flags; - - if (channel->needs_lock) { - spin_lock_irqsave(&channel->remove_lock, flags); - rc = signalremove_inner(channel, queue, msg); - spin_unlock_irqrestore(&channel->remove_lock, flags); - } else { - rc = signalremove_inner(channel, queue, msg); - } - - return rc; -} -EXPORT_SYMBOL_GPL(visorchannel_signalremove); - -static bool queue_empty(struct visorchannel *channel, u32 queue) -{ - struct signal_queue_header sig_hdr; - - if (sig_read_header(channel, queue, &sig_hdr)) - return true; - return (sig_hdr.head == sig_hdr.tail); -} - -/** - * visorchannel_signalempty() - checks if the designated channel/queue contains - * any messages - * @channel: the channel to query - * @queue: the queue in the channel to query - * - * Return: boolean indicating whether any messages in the designated - * channel/queue are present - */ -bool visorchannel_signalempty(struct visorchannel *channel, u32 queue) -{ - bool rc; - unsigned long flags; - - if (!channel->needs_lock) - return queue_empty(channel, queue); - spin_lock_irqsave(&channel->remove_lock, flags); - rc = queue_empty(channel, queue); - spin_unlock_irqrestore(&channel->remove_lock, flags); - return rc; -} -EXPORT_SYMBOL_GPL(visorchannel_signalempty); - -static int signalinsert_inner(struct visorchannel *channel, u32 queue, - void *msg) -{ - struct signal_queue_header sig_hdr; - int err; - - err = sig_read_header(channel, queue, &sig_hdr); - if (err) - return err; - sig_hdr.head = (sig_hdr.head + 1) % sig_hdr.max_slots; - if (sig_hdr.head == sig_hdr.tail) { - sig_hdr.num_overflows++; - err = SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_overflows); - if (err) - return err; - return -EIO; - } - err = sig_write_data(channel, queue, &sig_hdr, sig_hdr.head, msg); - if (err) - return err; - sig_hdr.num_sent++; - /* - * For each data field in SIGNAL_QUEUE_HEADER that was modified, update - * host memory. Required for channel sync. - */ - mb(); - err = SIG_WRITE_FIELD(channel, queue, &sig_hdr, head); - if (err) - return err; - err = SIG_WRITE_FIELD(channel, queue, &sig_hdr, num_sent); - if (err) - return err; - return 0; -} - -/* - * visorchannel_create() - creates the struct visorchannel abstraction for a - * data area in memory, but does NOT modify this data - * area - * @physaddr: physical address of start of channel - * @gfp: gfp_t to use when allocating memory for the data struct - * @guid: GUID that identifies channel type; - * @needs_lock: must specify true if you have multiple threads of execution - * that will be calling visorchannel methods of this - * visorchannel at the same time - * - * Return: pointer to visorchannel that was created if successful, - * otherwise NULL - */ -struct visorchannel *visorchannel_create(u64 physaddr, gfp_t gfp, - const guid_t *guid, bool needs_lock) -{ - struct visorchannel *channel; - int err; - size_t size = sizeof(struct channel_header); - - if (physaddr == 0) - return NULL; - - channel = kzalloc(sizeof(*channel), gfp); - if (!channel) - return NULL; - channel->needs_lock = needs_lock; - spin_lock_init(&channel->insert_lock); - spin_lock_init(&channel->remove_lock); - /* - * Video driver constains the efi framebuffer so it will get a conflict - * resource when requesting its full mem region. Since we are only - * using the efi framebuffer for video we can ignore this. Remember that - * we haven't requested it so we don't try to release later on. - */ - channel->requested = request_mem_region(physaddr, size, VISOR_DRV_NAME); - if (!channel->requested && !guid_equal(guid, &visor_video_guid)) - /* we only care about errors if this is not the video channel */ - goto err_destroy_channel; - channel->mapped = memremap(physaddr, size, MEMREMAP_WB); - if (!channel->mapped) { - release_mem_region(physaddr, size); - goto err_destroy_channel; - } - channel->physaddr = physaddr; - channel->nbytes = size; - err = visorchannel_read(channel, 0, &channel->chan_hdr, size); - if (err) - goto err_destroy_channel; - size = (ulong)channel->chan_hdr.size; - memunmap(channel->mapped); - if (channel->requested) - release_mem_region(channel->physaddr, channel->nbytes); - channel->mapped = NULL; - channel->requested = request_mem_region(channel->physaddr, size, - VISOR_DRV_NAME); - if (!channel->requested && !guid_equal(guid, &visor_video_guid)) - /* we only care about errors if this is not the video channel */ - goto err_destroy_channel; - channel->mapped = memremap(channel->physaddr, size, MEMREMAP_WB); - if (!channel->mapped) { - release_mem_region(channel->physaddr, size); - goto err_destroy_channel; - } - channel->nbytes = size; - guid_copy(&channel->guid, guid); - return channel; - -err_destroy_channel: - visorchannel_destroy(channel); - return NULL; -} - -/** - * visorchannel_signalinsert() - inserts a message into the designated - * channel/queue - * @channel: the channel the message will be added to - * @queue: the queue the message will be added to - * @msg: the message to insert - * - * Return: integer error code indicating the status of the insertion - */ -int visorchannel_signalinsert(struct visorchannel *channel, u32 queue, - void *msg) -{ - int rc; - unsigned long flags; - - if (channel->needs_lock) { - spin_lock_irqsave(&channel->insert_lock, flags); - rc = signalinsert_inner(channel, queue, msg); - spin_unlock_irqrestore(&channel->insert_lock, flags); - } else { - rc = signalinsert_inner(channel, queue, msg); - } - - return rc; -} -EXPORT_SYMBOL_GPL(visorchannel_signalinsert); diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c deleted file mode 100644 index fed554a43151..000000000000 --- a/drivers/staging/unisys/visorbus/visorchipset.c +++ /dev/null @@ -1,1694 +0,0 @@ -/* - * Copyright (C) 2010 - 2015 UNISYS CORPORATION - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - */ - -#include <linux/acpi.h> -#include <linux/crash_dump.h> - -#include "visorbus.h" -#include "visorbus_private.h" - -/* {72120008-4AAB-11DC-8530-444553544200} */ -#define VISOR_SIOVM_GUID GUID_INIT(0x72120008, 0x4AAB, 0x11DC, 0x85, 0x30, \ - 0x44, 0x45, 0x53, 0x54, 0x42, 0x00) - -static const guid_t visor_vhba_channel_guid = VISOR_VHBA_CHANNEL_GUID; -static const guid_t visor_siovm_guid = VISOR_SIOVM_GUID; -static const guid_t visor_controlvm_channel_guid = VISOR_CONTROLVM_CHANNEL_GUID; - -#define POLLJIFFIES_CONTROLVM_FAST 1 -#define POLLJIFFIES_CONTROLVM_SLOW 100 - -#define MAX_CONTROLVM_PAYLOAD_BYTES (1024 * 128) - -#define UNISYS_VISOR_LEAF_ID 0x40000000 - -/* The s-Par leaf ID returns "UnisysSpar64" encoded across ebx, ecx, edx */ -#define UNISYS_VISOR_ID_EBX 0x73696e55 -#define UNISYS_VISOR_ID_ECX 0x70537379 -#define UNISYS_VISOR_ID_EDX 0x34367261 - -/* - * When the controlvm channel is idle for at least MIN_IDLE_SECONDS, we switch - * to slow polling mode. As soon as we get a controlvm message, we switch back - * to fast polling mode. - */ -#define MIN_IDLE_SECONDS 10 - -struct parser_context { - unsigned long allocbytes; - unsigned long param_bytes; - u8 *curr; - unsigned long bytes_remaining; - bool byte_stream; - struct visor_controlvm_parameters_header data; -}; - -/* VMCALL_CONTROLVM_ADDR: Used by all guests, not just IO. */ -#define VMCALL_CONTROLVM_ADDR 0x0501 - -enum vmcall_result { - VMCALL_RESULT_SUCCESS = 0, - VMCALL_RESULT_INVALID_PARAM = 1, - VMCALL_RESULT_DATA_UNAVAILABLE = 2, - VMCALL_RESULT_FAILURE_UNAVAILABLE = 3, - VMCALL_RESULT_DEVICE_ERROR = 4, - VMCALL_RESULT_DEVICE_NOT_READY = 5 -}; - -/* - * struct vmcall_io_controlvm_addr_params - Structure for IO VMCALLS. Has - * parameters to VMCALL_CONTROLVM_ADDR - * interface. - * @address: The Guest-relative physical address of the ControlVm channel. - * This VMCall fills this in with the appropriate address. - * Contents provided by this VMCALL (OUT). - * @channel_bytes: The size of the ControlVm channel in bytes This VMCall fills - * this in with the appropriate address. Contents provided by - * this VMCALL (OUT). - * @unused: Unused Bytes in the 64-Bit Aligned Struct. - */ -struct vmcall_io_controlvm_addr_params { - u64 address; - u32 channel_bytes; - u8 unused[4]; -} __packed; - -struct visorchipset_device { - struct acpi_device *acpi_device; - unsigned long poll_jiffies; - /* when we got our last controlvm message */ - unsigned long most_recent_message_jiffies; - struct delayed_work periodic_controlvm_work; - struct visorchannel *controlvm_channel; - unsigned long controlvm_payload_bytes_buffered; - /* - * The following variables are used to handle the scenario where we are - * unable to offload the payload from a controlvm message due to memory - * requirements. In this scenario, we simply stash the controlvm - * message, then attempt to process it again the next time - * controlvm_periodic_work() runs. - */ - struct controlvm_message controlvm_pending_msg; - bool controlvm_pending_msg_valid; - struct vmcall_io_controlvm_addr_params controlvm_params; -}; - -static struct visorchipset_device *chipset_dev; - -struct parahotplug_request { - struct list_head list; - int id; - unsigned long expiration; - struct controlvm_message msg; -}; - -/* prototypes for attributes */ -static ssize_t toolaction_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - u8 tool_action = 0; - int err; - - err = visorchannel_read(chipset_dev->controlvm_channel, - offsetof(struct visor_controlvm_channel, - tool_action), - &tool_action, sizeof(u8)); - if (err) - return err; - return sprintf(buf, "%u\n", tool_action); -} - -static ssize_t toolaction_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - u8 tool_action; - int err; - - if (kstrtou8(buf, 10, &tool_action)) - return -EINVAL; - err = visorchannel_write(chipset_dev->controlvm_channel, - offsetof(struct visor_controlvm_channel, - tool_action), - &tool_action, sizeof(u8)); - if (err) - return err; - return count; -} -static DEVICE_ATTR_RW(toolaction); - -static ssize_t boottotool_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct efi_visor_indication efi_visor_indication; - int err; - - err = visorchannel_read(chipset_dev->controlvm_channel, - offsetof(struct visor_controlvm_channel, - efi_visor_ind), - &efi_visor_indication, - sizeof(struct efi_visor_indication)); - if (err) - return err; - return sprintf(buf, "%u\n", efi_visor_indication.boot_to_tool); -} - -static ssize_t boottotool_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - int val, err; - struct efi_visor_indication efi_visor_indication; - - if (kstrtoint(buf, 10, &val)) - return -EINVAL; - efi_visor_indication.boot_to_tool = val; - err = visorchannel_write(chipset_dev->controlvm_channel, - offsetof(struct visor_controlvm_channel, - efi_visor_ind), - &(efi_visor_indication), - sizeof(struct efi_visor_indication)); - if (err) - return err; - return count; -} -static DEVICE_ATTR_RW(boottotool); - -static ssize_t error_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - u32 error = 0; - int err; - - err = visorchannel_read(chipset_dev->controlvm_channel, - offsetof(struct visor_controlvm_channel, - installation_error), - &error, sizeof(u32)); - if (err) - return err; - return sprintf(buf, "%u\n", error); -} - -static ssize_t error_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - u32 error; - int err; - - if (kstrtou32(buf, 10, &error)) - return -EINVAL; - err = visorchannel_write(chipset_dev->controlvm_channel, - offsetof(struct visor_controlvm_channel, - installation_error), - &error, sizeof(u32)); - if (err) - return err; - return count; -} -static DEVICE_ATTR_RW(error); - -static ssize_t textid_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - u32 text_id = 0; - int err; - - err = visorchannel_read(chipset_dev->controlvm_channel, - offsetof(struct visor_controlvm_channel, - installation_text_id), - &text_id, sizeof(u32)); - if (err) - return err; - return sprintf(buf, "%u\n", text_id); -} - -static ssize_t textid_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - u32 text_id; - int err; - - if (kstrtou32(buf, 10, &text_id)) - return -EINVAL; - err = visorchannel_write(chipset_dev->controlvm_channel, - offsetof(struct visor_controlvm_channel, - installation_text_id), - &text_id, sizeof(u32)); - if (err) - return err; - return count; -} -static DEVICE_ATTR_RW(textid); - -static ssize_t remaining_steps_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - u16 remaining_steps = 0; - int err; - - err = visorchannel_read(chipset_dev->controlvm_channel, - offsetof(struct visor_controlvm_channel, - installation_remaining_steps), - &remaining_steps, sizeof(u16)); - if (err) - return err; - return sprintf(buf, "%hu\n", remaining_steps); -} - -static ssize_t remaining_steps_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - u16 remaining_steps; - int err; - - if (kstrtou16(buf, 10, &remaining_steps)) - return -EINVAL; - err = visorchannel_write(chipset_dev->controlvm_channel, - offsetof(struct visor_controlvm_channel, - installation_remaining_steps), - &remaining_steps, sizeof(u16)); - if (err) - return err; - return count; -} -static DEVICE_ATTR_RW(remaining_steps); - -static void controlvm_init_response(struct controlvm_message *msg, - struct controlvm_message_header *msg_hdr, - int response) -{ - memset(msg, 0, sizeof(struct controlvm_message)); - memcpy(&msg->hdr, msg_hdr, sizeof(struct controlvm_message_header)); - msg->hdr.payload_bytes = 0; - msg->hdr.payload_vm_offset = 0; - msg->hdr.payload_max_bytes = 0; - if (response < 0) { - msg->hdr.flags.failed = 1; - msg->hdr.completion_status = (u32)(-response); - } -} - -static int controlvm_respond_chipset_init( - struct controlvm_message_header *msg_hdr, - int response, - enum visor_chipset_feature features) -{ - struct controlvm_message outmsg; - - controlvm_init_response(&outmsg, msg_hdr, response); - outmsg.cmd.init_chipset.features = features; - return visorchannel_signalinsert(chipset_dev->controlvm_channel, - CONTROLVM_QUEUE_REQUEST, &outmsg); -} - -static int chipset_init(struct controlvm_message *inmsg) -{ - static int chipset_inited; - enum visor_chipset_feature features = 0; - int rc = CONTROLVM_RESP_SUCCESS; - int res = 0; - - if (chipset_inited) { - rc = -CONTROLVM_RESP_ALREADY_DONE; - res = -EIO; - goto out_respond; - } - chipset_inited = 1; - /* - * Set features to indicate we support parahotplug (if Command also - * supports it). Set the "reply" bit so Command knows this is a - * features-aware driver. - */ - features = inmsg->cmd.init_chipset.features & - VISOR_CHIPSET_FEATURE_PARA_HOTPLUG; - features |= VISOR_CHIPSET_FEATURE_REPLY; - -out_respond: - if (inmsg->hdr.flags.response_expected) - res = controlvm_respond_chipset_init(&inmsg->hdr, rc, features); - - return res; -} - -static int controlvm_respond(struct controlvm_message_header *msg_hdr, - int response, struct visor_segment_state *state) -{ - struct controlvm_message outmsg; - - controlvm_init_response(&outmsg, msg_hdr, response); - if (outmsg.hdr.flags.test_message == 1) - return -EINVAL; - if (state) { - outmsg.cmd.device_change_state.state = *state; - outmsg.cmd.device_change_state.flags.phys_device = 1; - } - return visorchannel_signalinsert(chipset_dev->controlvm_channel, - CONTROLVM_QUEUE_REQUEST, &outmsg); -} - -enum crash_obj_type { - CRASH_DEV, - CRASH_BUS, -}; - -static int save_crash_message(struct controlvm_message *msg, - enum crash_obj_type cr_type) -{ - u32 local_crash_msg_offset; - u16 local_crash_msg_count; - int err; - - err = visorchannel_read(chipset_dev->controlvm_channel, - offsetof(struct visor_controlvm_channel, - saved_crash_message_count), - &local_crash_msg_count, sizeof(u16)); - if (err) { - dev_err(&chipset_dev->acpi_device->dev, - "failed to read message count\n"); - return err; - } - if (local_crash_msg_count != CONTROLVM_CRASHMSG_MAX) { - dev_err(&chipset_dev->acpi_device->dev, - "invalid number of messages\n"); - return -EIO; - } - err = visorchannel_read(chipset_dev->controlvm_channel, - offsetof(struct visor_controlvm_channel, - saved_crash_message_offset), - &local_crash_msg_offset, sizeof(u32)); - if (err) { - dev_err(&chipset_dev->acpi_device->dev, - "failed to read offset\n"); - return err; - } - switch (cr_type) { - case CRASH_DEV: - local_crash_msg_offset += sizeof(struct controlvm_message); - err = visorchannel_write(chipset_dev->controlvm_channel, - local_crash_msg_offset, msg, - sizeof(struct controlvm_message)); - if (err) { - dev_err(&chipset_dev->acpi_device->dev, - "failed to write dev msg\n"); - return err; - } - break; - case CRASH_BUS: - err = visorchannel_write(chipset_dev->controlvm_channel, - local_crash_msg_offset, msg, - sizeof(struct controlvm_message)); - if (err) { - dev_err(&chipset_dev->acpi_device->dev, - "failed to write bus msg\n"); - return err; - } - break; - default: - dev_err(&chipset_dev->acpi_device->dev, - "Invalid crash_obj_type\n"); - break; - } - return 0; -} - -static int controlvm_responder(enum controlvm_id cmd_id, - struct controlvm_message_header *pending_msg_hdr, - int response) -{ - if (pending_msg_hdr->id != (u32)cmd_id) - return -EINVAL; - - return controlvm_respond(pending_msg_hdr, response, NULL); -} - -static int device_changestate_responder(enum controlvm_id cmd_id, - struct visor_device *p, int response, - struct visor_segment_state state) -{ - struct controlvm_message outmsg; - - if (p->pending_msg_hdr->id != cmd_id) - return -EINVAL; - - controlvm_init_response(&outmsg, p->pending_msg_hdr, response); - outmsg.cmd.device_change_state.bus_no = p->chipset_bus_no; - outmsg.cmd.device_change_state.dev_no = p->chipset_dev_no; - outmsg.cmd.device_change_state.state = state; - return visorchannel_signalinsert(chipset_dev->controlvm_channel, - CONTROLVM_QUEUE_REQUEST, &outmsg); -} - -static int visorbus_create(struct controlvm_message *inmsg) -{ - struct controlvm_message_packet *cmd = &inmsg->cmd; - struct controlvm_message_header *pmsg_hdr; - u32 bus_no = cmd->create_bus.bus_no; - struct visor_device *bus_info; - struct visorchannel *visorchannel; - int err; - - bus_info = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL); - if (bus_info && bus_info->state.created == 1) { - dev_err(&chipset_dev->acpi_device->dev, - "failed %s: already exists\n", __func__); - err = -EEXIST; - goto err_respond; - } - bus_info = kzalloc(sizeof(*bus_info), GFP_KERNEL); - if (!bus_info) { - err = -ENOMEM; - goto err_respond; - } - INIT_LIST_HEAD(&bus_info->list_all); - bus_info->chipset_bus_no = bus_no; - bus_info->chipset_dev_no = BUS_ROOT_DEVICE; - if (guid_equal(&cmd->create_bus.bus_inst_guid, &visor_siovm_guid)) { - err = save_crash_message(inmsg, CRASH_BUS); - if (err) - goto err_free_bus_info; - } - if (inmsg->hdr.flags.response_expected == 1) { - pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), GFP_KERNEL); - if (!pmsg_hdr) { - err = -ENOMEM; - goto err_free_bus_info; - } - memcpy(pmsg_hdr, &inmsg->hdr, - sizeof(struct controlvm_message_header)); - bus_info->pending_msg_hdr = pmsg_hdr; - } - visorchannel = visorchannel_create(cmd->create_bus.channel_addr, - GFP_KERNEL, - &cmd->create_bus.bus_data_type_guid, - false); - if (!visorchannel) { - err = -ENOMEM; - goto err_free_pending_msg; - } - bus_info->visorchannel = visorchannel; - /* Response will be handled by visorbus_create_instance on success */ - err = visorbus_create_instance(bus_info); - if (err) - goto err_destroy_channel; - return 0; - -err_destroy_channel: - visorchannel_destroy(visorchannel); - -err_free_pending_msg: - kfree(bus_info->pending_msg_hdr); - -err_free_bus_info: - kfree(bus_info); - -err_respond: - if (inmsg->hdr.flags.response_expected == 1) - controlvm_responder(inmsg->hdr.id, &inmsg->hdr, err); - return err; -} - -static int visorbus_destroy(struct controlvm_message *inmsg) -{ - struct controlvm_message_header *pmsg_hdr; - u32 bus_no = inmsg->cmd.destroy_bus.bus_no; - struct visor_device *bus_info; - int err; - - bus_info = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL); - if (!bus_info) { - err = -ENODEV; - goto err_respond; - } - if (bus_info->state.created == 0) { - err = -ENOENT; - goto err_respond; - } - if (bus_info->pending_msg_hdr) { - /* only non-NULL if dev is still waiting on a response */ - err = -EEXIST; - goto err_respond; - } - if (inmsg->hdr.flags.response_expected == 1) { - pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), GFP_KERNEL); - if (!pmsg_hdr) { - err = -ENOMEM; - goto err_respond; - } - memcpy(pmsg_hdr, &inmsg->hdr, - sizeof(struct controlvm_message_header)); - bus_info->pending_msg_hdr = pmsg_hdr; - } - /* Response will be handled by visorbus_remove_instance */ - visorbus_remove_instance(bus_info); - return 0; - -err_respond: - if (inmsg->hdr.flags.response_expected == 1) - controlvm_responder(inmsg->hdr.id, &inmsg->hdr, err); - return err; -} - -static const guid_t *parser_id_get(struct parser_context *ctx) -{ - return &ctx->data.id; -} - -static void *parser_string_get(u8 *pscan, int nscan) -{ - int value_length; - void *value; - - if (nscan == 0) - return NULL; - - value_length = strnlen(pscan, nscan); - value = kzalloc(value_length + 1, GFP_KERNEL); - if (!value) - return NULL; - if (value_length > 0) - memcpy(value, pscan, value_length); - return value; -} - -static void *parser_name_get(struct parser_context *ctx) -{ - struct visor_controlvm_parameters_header *phdr; - - phdr = &ctx->data; - if (phdr->name_offset + phdr->name_length > ctx->param_bytes) - return NULL; - ctx->curr = (char *)&phdr + phdr->name_offset; - ctx->bytes_remaining = phdr->name_length; - return parser_string_get(ctx->curr, phdr->name_length); -} - -static int visorbus_configure(struct controlvm_message *inmsg, - struct parser_context *parser_ctx) -{ - struct controlvm_message_packet *cmd = &inmsg->cmd; - u32 bus_no; - struct visor_device *bus_info; - int err = 0; - - bus_no = cmd->configure_bus.bus_no; - bus_info = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL); - if (!bus_info) { - err = -EINVAL; - goto err_respond; - } - if (bus_info->state.created == 0) { - err = -EINVAL; - goto err_respond; - } - if (bus_info->pending_msg_hdr) { - err = -EIO; - goto err_respond; - } - err = visorchannel_set_clientpartition(bus_info->visorchannel, - cmd->configure_bus.guest_handle); - if (err) - goto err_respond; - if (parser_ctx) { - const guid_t *partition_guid = parser_id_get(parser_ctx); - - guid_copy(&bus_info->partition_guid, partition_guid); - bus_info->name = parser_name_get(parser_ctx); - } - if (inmsg->hdr.flags.response_expected == 1) - controlvm_responder(inmsg->hdr.id, &inmsg->hdr, err); - return 0; - -err_respond: - dev_err(&chipset_dev->acpi_device->dev, - "%s exited with err: %d\n", __func__, err); - if (inmsg->hdr.flags.response_expected == 1) - controlvm_responder(inmsg->hdr.id, &inmsg->hdr, err); - return err; -} - -static int visorbus_device_create(struct controlvm_message *inmsg) -{ - struct controlvm_message_packet *cmd = &inmsg->cmd; - struct controlvm_message_header *pmsg_hdr; - u32 bus_no = cmd->create_device.bus_no; - u32 dev_no = cmd->create_device.dev_no; - struct visor_device *dev_info; - struct visor_device *bus_info; - struct visorchannel *visorchannel; - int err; - - bus_info = visorbus_get_device_by_id(bus_no, BUS_ROOT_DEVICE, NULL); - if (!bus_info) { - dev_err(&chipset_dev->acpi_device->dev, - "failed to get bus by id: %d\n", bus_no); - err = -ENODEV; - goto err_respond; - } - if (bus_info->state.created == 0) { - dev_err(&chipset_dev->acpi_device->dev, - "bus not created, id: %d\n", bus_no); - err = -EINVAL; - goto err_respond; - } - dev_info = visorbus_get_device_by_id(bus_no, dev_no, NULL); - if (dev_info && dev_info->state.created == 1) { - dev_err(&chipset_dev->acpi_device->dev, - "failed to get bus by id: %d/%d\n", bus_no, dev_no); - err = -EEXIST; - goto err_respond; - } - - dev_info = kzalloc(sizeof(*dev_info), GFP_KERNEL); - if (!dev_info) { - err = -ENOMEM; - goto err_respond; - } - dev_info->chipset_bus_no = bus_no; - dev_info->chipset_dev_no = dev_no; - guid_copy(&dev_info->inst, &cmd->create_device.dev_inst_guid); - dev_info->device.parent = &bus_info->device; - visorchannel = visorchannel_create(cmd->create_device.channel_addr, - GFP_KERNEL, - &cmd->create_device.data_type_guid, - true); - if (!visorchannel) { - dev_err(&chipset_dev->acpi_device->dev, - "failed to create visorchannel: %d/%d\n", - bus_no, dev_no); - err = -ENOMEM; - goto err_free_dev_info; - } - dev_info->visorchannel = visorchannel; - guid_copy(&dev_info->channel_type_guid, - &cmd->create_device.data_type_guid); - if (guid_equal(&cmd->create_device.data_type_guid, - &visor_vhba_channel_guid)) { - err = save_crash_message(inmsg, CRASH_DEV); - if (err) - goto err_destroy_visorchannel; - } - if (inmsg->hdr.flags.response_expected == 1) { - pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), GFP_KERNEL); - if (!pmsg_hdr) { - err = -ENOMEM; - goto err_destroy_visorchannel; - } - memcpy(pmsg_hdr, &inmsg->hdr, - sizeof(struct controlvm_message_header)); - dev_info->pending_msg_hdr = pmsg_hdr; - } - /* create_visor_device will send response */ - err = create_visor_device(dev_info); - if (err) - goto err_destroy_visorchannel; - - return 0; - -err_destroy_visorchannel: - visorchannel_destroy(visorchannel); - -err_free_dev_info: - kfree(dev_info); - -err_respond: - if (inmsg->hdr.flags.response_expected == 1) - controlvm_responder(inmsg->hdr.id, &inmsg->hdr, err); - return err; -} - -static int visorbus_device_changestate(struct controlvm_message *inmsg) -{ - struct controlvm_message_packet *cmd = &inmsg->cmd; - struct controlvm_message_header *pmsg_hdr; - u32 bus_no = cmd->device_change_state.bus_no; - u32 dev_no = cmd->device_change_state.dev_no; - struct visor_segment_state state = cmd->device_change_state.state; - struct visor_device *dev_info; - int err = 0; - - dev_info = visorbus_get_device_by_id(bus_no, dev_no, NULL); - if (!dev_info) { - err = -ENODEV; - goto err_respond; - } - if (dev_info->state.created == 0) { - err = -EINVAL; - goto err_respond; - } - if (dev_info->pending_msg_hdr) { - /* only non-NULL if dev is still waiting on a response */ - err = -EIO; - goto err_respond; - } - - if (inmsg->hdr.flags.response_expected == 1) { - pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), GFP_KERNEL); - if (!pmsg_hdr) { - err = -ENOMEM; - goto err_respond; - } - memcpy(pmsg_hdr, &inmsg->hdr, - sizeof(struct controlvm_message_header)); - dev_info->pending_msg_hdr = pmsg_hdr; - } - if (state.alive == segment_state_running.alive && - state.operating == segment_state_running.operating) - /* Response will be sent from visorchipset_device_resume */ - err = visorchipset_device_resume(dev_info); - /* ServerNotReady / ServerLost / SegmentStateStandby */ - else if (state.alive == segment_state_standby.alive && - state.operating == segment_state_standby.operating) - /* - * technically this is standby case where server is lost. - * Response will be sent from visorchipset_device_pause. - */ - err = visorchipset_device_pause(dev_info); - if (err) - goto err_respond; - return 0; - -err_respond: - dev_err(&chipset_dev->acpi_device->dev, "failed: %d\n", err); - if (inmsg->hdr.flags.response_expected == 1) - controlvm_responder(inmsg->hdr.id, &inmsg->hdr, err); - return err; -} - -static int visorbus_device_destroy(struct controlvm_message *inmsg) -{ - struct controlvm_message_packet *cmd = &inmsg->cmd; - struct controlvm_message_header *pmsg_hdr; - u32 bus_no = cmd->destroy_device.bus_no; - u32 dev_no = cmd->destroy_device.dev_no; - struct visor_device *dev_info; - int err; - - dev_info = visorbus_get_device_by_id(bus_no, dev_no, NULL); - if (!dev_info) { - err = -ENODEV; - goto err_respond; - } - if (dev_info->state.created == 0) { - err = -EINVAL; - goto err_respond; - } - if (dev_info->pending_msg_hdr) { - /* only non-NULL if dev is still waiting on a response */ - err = -EIO; - goto err_respond; - } - if (inmsg->hdr.flags.response_expected == 1) { - pmsg_hdr = kzalloc(sizeof(*pmsg_hdr), GFP_KERNEL); - if (!pmsg_hdr) { - err = -ENOMEM; - goto err_respond; - } - - memcpy(pmsg_hdr, &inmsg->hdr, - sizeof(struct controlvm_message_header)); - dev_info->pending_msg_hdr = pmsg_hdr; - } - kfree(dev_info->name); - remove_visor_device(dev_info); - return 0; - -err_respond: - if (inmsg->hdr.flags.response_expected == 1) - controlvm_responder(inmsg->hdr.id, &inmsg->hdr, err); - return err; -} - -/* - * The general parahotplug flow works as follows. The visorchipset receives - * a DEVICE_CHANGESTATE message from Command specifying a physical device - * to enable or disable. The CONTROLVM message handler calls - * parahotplug_process_message, which then adds the message to a global list - * and kicks off a udev event which causes a user level script to enable or - * disable the specified device. The udev script then writes to - * /sys/devices/platform/visorchipset/parahotplug, which causes the - * parahotplug store functions to get called, at which point the - * appropriate CONTROLVM message is retrieved from the list and responded to. - */ - -#define PARAHOTPLUG_TIMEOUT_MS 2000 - -/* - * parahotplug_next_id() - generate unique int to match an outstanding - * CONTROLVM message with a udev script /sys - * response - * - * Return: a unique integer value - */ -static int parahotplug_next_id(void) -{ - static atomic_t id = ATOMIC_INIT(0); - - return atomic_inc_return(&id); -} - -/* - * parahotplug_next_expiration() - returns the time (in jiffies) when a - * CONTROLVM message on the list should expire - * -- PARAHOTPLUG_TIMEOUT_MS in the future - * - * Return: expected expiration time (in jiffies) - */ -static unsigned long parahotplug_next_expiration(void) -{ - return jiffies + msecs_to_jiffies(PARAHOTPLUG_TIMEOUT_MS); -} - -/* - * parahotplug_request_create() - create a parahotplug_request, which is - * basically a wrapper for a CONTROLVM_MESSAGE - * that we can stick on a list - * @msg: the message to insert in the request - * - * Return: the request containing the provided message - */ -static struct parahotplug_request *parahotplug_request_create( - struct controlvm_message *msg) -{ - struct parahotplug_request *req; - - req = kmalloc(sizeof(*req), GFP_KERNEL); - if (!req) - return NULL; - req->id = parahotplug_next_id(); - req->expiration = parahotplug_next_expiration(); - req->msg = *msg; - return req; -} - -/* - * parahotplug_request_destroy() - free a parahotplug_request - * @req: the request to deallocate - */ -static void parahotplug_request_destroy(struct parahotplug_request *req) -{ - kfree(req); -} - -static LIST_HEAD(parahotplug_request_list); -/* lock for above */ -static DEFINE_SPINLOCK(parahotplug_request_list_lock); - -/* - * parahotplug_request_complete() - mark request as complete - * @id: the id of the request - * @active: indicates whether the request is assigned to active partition - * - * Called from the /sys handler, which means the user script has - * finished the enable/disable. Find the matching identifier, and - * respond to the CONTROLVM message with success. - * - * Return: 0 on success or -EINVAL on failure - */ -static int parahotplug_request_complete(int id, u16 active) -{ - struct list_head *pos; - struct list_head *tmp; - struct parahotplug_request *req; - - spin_lock(¶hotplug_request_list_lock); - /* Look for a request matching "id". */ - list_for_each_safe(pos, tmp, ¶hotplug_request_list) { - req = list_entry(pos, struct parahotplug_request, list); - if (req->id == id) { - /* - * Found a match. Remove it from the list and - * respond. - */ - list_del(pos); - spin_unlock(¶hotplug_request_list_lock); - req->msg.cmd.device_change_state.state.active = active; - if (req->msg.hdr.flags.response_expected) - controlvm_respond( - &req->msg.hdr, CONTROLVM_RESP_SUCCESS, - &req->msg.cmd.device_change_state.state); - parahotplug_request_destroy(req); - return 0; - } - } - spin_unlock(¶hotplug_request_list_lock); - return -EINVAL; -} - -/* - * devicedisabled_store() - disables the hotplug device - * @dev: sysfs interface variable not utilized in this function - * @attr: sysfs interface variable not utilized in this function - * @buf: buffer containing the device id - * @count: the size of the buffer - * - * The parahotplug/devicedisabled interface gets called by our support script - * when an SR-IOV device has been shut down. The ID is passed to the script - * and then passed back when the device has been removed. - * - * Return: the size of the buffer for success or negative for error - */ -static ssize_t devicedisabled_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned int id; - int err; - - if (kstrtouint(buf, 10, &id)) - return -EINVAL; - err = parahotplug_request_complete(id, 0); - if (err < 0) - return err; - return count; -} -static DEVICE_ATTR_WO(devicedisabled); - -/* - * deviceenabled_store() - enables the hotplug device - * @dev: sysfs interface variable not utilized in this function - * @attr: sysfs interface variable not utilized in this function - * @buf: buffer containing the device id - * @count: the size of the buffer - * - * The parahotplug/deviceenabled interface gets called by our support script - * when an SR-IOV device has been recovered. The ID is passed to the script - * and then passed back when the device has been brought back up. - * - * Return: the size of the buffer for success or negative for error - */ -static ssize_t deviceenabled_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned int id; - - if (kstrtouint(buf, 10, &id)) - return -EINVAL; - parahotplug_request_complete(id, 1); - return count; -} -static DEVICE_ATTR_WO(deviceenabled); - -static struct attribute *visorchipset_install_attrs[] = { - &dev_attr_toolaction.attr, - &dev_attr_boottotool.attr, - &dev_attr_error.attr, - &dev_attr_textid.attr, - &dev_attr_remaining_steps.attr, - NULL -}; - -static const struct attribute_group visorchipset_install_group = { - .name = "install", - .attrs = visorchipset_install_attrs -}; - -static struct attribute *visorchipset_parahotplug_attrs[] = { - &dev_attr_devicedisabled.attr, - &dev_attr_deviceenabled.attr, - NULL -}; - -static const struct attribute_group visorchipset_parahotplug_group = { - .name = "parahotplug", - .attrs = visorchipset_parahotplug_attrs -}; - -static const struct attribute_group *visorchipset_dev_groups[] = { - &visorchipset_install_group, - &visorchipset_parahotplug_group, - NULL -}; - -/* - * parahotplug_request_kickoff() - initiate parahotplug request - * @req: the request to initiate - * - * Cause uevent to run the user level script to do the disable/enable specified - * in the parahotplug_request. - */ -static int parahotplug_request_kickoff(struct parahotplug_request *req) -{ - struct controlvm_message_packet *cmd = &req->msg.cmd; - char env_cmd[40], env_id[40], env_state[40], env_bus[40], env_dev[40], - env_func[40]; - char *envp[] = { env_cmd, env_id, env_state, env_bus, env_dev, - env_func, NULL - }; - - sprintf(env_cmd, "VISOR_PARAHOTPLUG=1"); - sprintf(env_id, "VISOR_PARAHOTPLUG_ID=%d", req->id); - sprintf(env_state, "VISOR_PARAHOTPLUG_STATE=%d", - cmd->device_change_state.state.active); - sprintf(env_bus, "VISOR_PARAHOTPLUG_BUS=%d", - cmd->device_change_state.bus_no); - sprintf(env_dev, "VISOR_PARAHOTPLUG_DEVICE=%d", - cmd->device_change_state.dev_no >> 3); - sprintf(env_func, "VISOR_PARAHOTPLUG_FUNCTION=%d", - cmd->device_change_state.dev_no & 0x7); - return kobject_uevent_env(&chipset_dev->acpi_device->dev.kobj, - KOBJ_CHANGE, envp); -} - -/* - * parahotplug_process_message() - enables or disables a PCI device by kicking - * off a udev script - * @inmsg: the message indicating whether to enable or disable - */ -static int parahotplug_process_message(struct controlvm_message *inmsg) -{ - struct parahotplug_request *req; - int err; - - req = parahotplug_request_create(inmsg); - if (!req) - return -ENOMEM; - /* - * For enable messages, just respond with success right away, we don't - * need to wait to see if the enable was successful. - */ - if (inmsg->cmd.device_change_state.state.active) { - err = parahotplug_request_kickoff(req); - if (err) - goto err_respond; - controlvm_respond(&inmsg->hdr, CONTROLVM_RESP_SUCCESS, - &inmsg->cmd.device_change_state.state); - parahotplug_request_destroy(req); - return 0; - } - /* - * For disable messages, add the request to the request list before - * kicking off the udev script. It won't get responded to until the - * script has indicated it's done. - */ - spin_lock(¶hotplug_request_list_lock); - list_add_tail(&req->list, ¶hotplug_request_list); - spin_unlock(¶hotplug_request_list_lock); - err = parahotplug_request_kickoff(req); - if (err) - goto err_respond; - return 0; - -err_respond: - controlvm_respond(&inmsg->hdr, err, - &inmsg->cmd.device_change_state.state); - return err; -} - -/* - * chipset_ready_uevent() - sends chipset_ready action - * - * Send ACTION=online for DEVPATH=/sys/devices/platform/visorchipset. - * - * Return: 0 on success, negative on failure - */ -static int chipset_ready_uevent(struct controlvm_message_header *msg_hdr) -{ - int res; - - res = kobject_uevent(&chipset_dev->acpi_device->dev.kobj, KOBJ_ONLINE); - if (msg_hdr->flags.response_expected) - controlvm_respond(msg_hdr, res, NULL); - return res; -} - -/* - * chipset_selftest_uevent() - sends chipset_selftest action - * - * Send ACTION=online for DEVPATH=/sys/devices/platform/visorchipset. - * - * Return: 0 on success, negative on failure - */ -static int chipset_selftest_uevent(struct controlvm_message_header *msg_hdr) -{ - char env_selftest[20]; - char *envp[] = { env_selftest, NULL }; - int res; - - sprintf(env_selftest, "SPARSP_SELFTEST=%d", 1); - res = kobject_uevent_env(&chipset_dev->acpi_device->dev.kobj, - KOBJ_CHANGE, envp); - if (msg_hdr->flags.response_expected) - controlvm_respond(msg_hdr, res, NULL); - return res; -} - -/* - * chipset_notready_uevent() - sends chipset_notready action - * - * Send ACTION=offline for DEVPATH=/sys/devices/platform/visorchipset. - * - * Return: 0 on success, negative on failure - */ -static int chipset_notready_uevent(struct controlvm_message_header *msg_hdr) -{ - int res = kobject_uevent(&chipset_dev->acpi_device->dev.kobj, - KOBJ_OFFLINE); - - if (msg_hdr->flags.response_expected) - controlvm_respond(msg_hdr, res, NULL); - return res; -} - -static int unisys_vmcall(unsigned long tuple, unsigned long param) -{ - int result = 0; - unsigned int cpuid_eax, cpuid_ebx, cpuid_ecx, cpuid_edx; - unsigned long reg_ebx; - unsigned long reg_ecx; - - reg_ebx = param & 0xFFFFFFFF; - reg_ecx = param >> 32; - cpuid(0x00000001, &cpuid_eax, &cpuid_ebx, &cpuid_ecx, &cpuid_edx); - if (!(cpuid_ecx & 0x80000000)) - return -EPERM; - __asm__ __volatile__(".byte 0x00f, 0x001, 0x0c1" : "=a"(result) : - "a"(tuple), "b"(reg_ebx), "c"(reg_ecx)); - if (result) - goto error; - return 0; - -/* Need to convert from VMCALL error codes to Linux */ -error: - switch (result) { - case VMCALL_RESULT_INVALID_PARAM: - return -EINVAL; - case VMCALL_RESULT_DATA_UNAVAILABLE: - return -ENODEV; - default: - return -EFAULT; - } -} - -static int controlvm_channel_create(struct visorchipset_device *dev) -{ - struct visorchannel *chan; - u64 addr; - int err; - - err = unisys_vmcall(VMCALL_CONTROLVM_ADDR, - virt_to_phys(&dev->controlvm_params)); - if (err) - return err; - addr = dev->controlvm_params.address; - chan = visorchannel_create(addr, GFP_KERNEL, - &visor_controlvm_channel_guid, true); - if (!chan) - return -ENOMEM; - dev->controlvm_channel = chan; - return 0; -} - -static void setup_crash_devices_work_queue(struct work_struct *work) -{ - struct controlvm_message local_crash_bus_msg; - struct controlvm_message local_crash_dev_msg; - struct controlvm_message msg; - u32 local_crash_msg_offset; - u16 local_crash_msg_count; - - /* send init chipset msg */ - msg.hdr.id = CONTROLVM_CHIPSET_INIT; - msg.cmd.init_chipset.bus_count = 23; - msg.cmd.init_chipset.switch_count = 0; - chipset_init(&msg); - /* get saved message count */ - if (visorchannel_read(chipset_dev->controlvm_channel, - offsetof(struct visor_controlvm_channel, - saved_crash_message_count), - &local_crash_msg_count, sizeof(u16)) < 0) { - dev_err(&chipset_dev->acpi_device->dev, - "failed to read channel\n"); - return; - } - if (local_crash_msg_count != CONTROLVM_CRASHMSG_MAX) { - dev_err(&chipset_dev->acpi_device->dev, "invalid count\n"); - return; - } - /* get saved crash message offset */ - if (visorchannel_read(chipset_dev->controlvm_channel, - offsetof(struct visor_controlvm_channel, - saved_crash_message_offset), - &local_crash_msg_offset, sizeof(u32)) < 0) { - dev_err(&chipset_dev->acpi_device->dev, - "failed to read channel\n"); - return; - } - /* read create device message for storage bus offset */ - if (visorchannel_read(chipset_dev->controlvm_channel, - local_crash_msg_offset, - &local_crash_bus_msg, - sizeof(struct controlvm_message)) < 0) { - dev_err(&chipset_dev->acpi_device->dev, - "failed to read channel\n"); - return; - } - /* read create device message for storage device */ - if (visorchannel_read(chipset_dev->controlvm_channel, - local_crash_msg_offset + - sizeof(struct controlvm_message), - &local_crash_dev_msg, - sizeof(struct controlvm_message)) < 0) { - dev_err(&chipset_dev->acpi_device->dev, - "failed to read channel\n"); - return; - } - /* reuse IOVM create bus message */ - if (!local_crash_bus_msg.cmd.create_bus.channel_addr) { - dev_err(&chipset_dev->acpi_device->dev, - "no valid create_bus message\n"); - return; - } - visorbus_create(&local_crash_bus_msg); - /* reuse create device message for storage device */ - if (!local_crash_dev_msg.cmd.create_device.channel_addr) { - dev_err(&chipset_dev->acpi_device->dev, - "no valid create_device message\n"); - return; - } - visorbus_device_create(&local_crash_dev_msg); -} - -void visorbus_response(struct visor_device *bus_info, int response, - int controlvm_id) -{ - if (!bus_info->pending_msg_hdr) - return; - - controlvm_responder(controlvm_id, bus_info->pending_msg_hdr, response); - kfree(bus_info->pending_msg_hdr); - bus_info->pending_msg_hdr = NULL; -} - -void visorbus_device_changestate_response(struct visor_device *dev_info, - int response, - struct visor_segment_state state) -{ - if (!dev_info->pending_msg_hdr) - return; - - device_changestate_responder(CONTROLVM_DEVICE_CHANGESTATE, dev_info, - response, state); - kfree(dev_info->pending_msg_hdr); - dev_info->pending_msg_hdr = NULL; -} - -static void parser_done(struct parser_context *ctx) -{ - chipset_dev->controlvm_payload_bytes_buffered -= ctx->param_bytes; - kfree(ctx); -} - -static struct parser_context *parser_init_stream(u64 addr, u32 bytes, - bool *retry) -{ - int allocbytes; - struct parser_context *ctx; - void *mapping; - - *retry = false; - /* alloc an extra byte to ensure payload is \0 terminated */ - allocbytes = bytes + 1 + (sizeof(struct parser_context) - - sizeof(struct visor_controlvm_parameters_header)); - if ((chipset_dev->controlvm_payload_bytes_buffered + bytes) > - MAX_CONTROLVM_PAYLOAD_BYTES) { - *retry = true; - return NULL; - } - ctx = kzalloc(allocbytes, GFP_KERNEL); - if (!ctx) { - *retry = true; - return NULL; - } - ctx->allocbytes = allocbytes; - ctx->param_bytes = bytes; - mapping = memremap(addr, bytes, MEMREMAP_WB); - if (!mapping) - goto err_finish_ctx; - memcpy(&ctx->data, mapping, bytes); - memunmap(mapping); - ctx->byte_stream = true; - chipset_dev->controlvm_payload_bytes_buffered += ctx->param_bytes; - return ctx; - -err_finish_ctx: - kfree(ctx); - return NULL; -} - -/* - * handle_command() - process a controlvm message - * @inmsg: the message to process - * @channel_addr: address of the controlvm channel - * - * Return: - * 0 - Successfully processed the message - * -EAGAIN - ControlVM message was not processed and should be retried - * reading the next controlvm message; a scenario where this can - * occur is when we need to throttle the allocation of memory in - * which to copy out controlvm payload data. - * < 0 - error: ControlVM message was processed but an error occurred. - */ -static int handle_command(struct controlvm_message inmsg, u64 channel_addr) -{ - struct controlvm_message_packet *cmd = &inmsg.cmd; - u64 parm_addr; - u32 parm_bytes; - struct parser_context *parser_ctx = NULL; - struct controlvm_message ackmsg; - int err = 0; - - /* create parsing context if necessary */ - parm_addr = channel_addr + inmsg.hdr.payload_vm_offset; - parm_bytes = inmsg.hdr.payload_bytes; - /* - * Parameter and channel addresses within test messages actually lie - * within our OS-controlled memory. We need to know that, because it - * makes a difference in how we compute the virtual address. - */ - if (parm_bytes) { - bool retry; - - parser_ctx = parser_init_stream(parm_addr, parm_bytes, &retry); - if (!parser_ctx && retry) - return -EAGAIN; - } - controlvm_init_response(&ackmsg, &inmsg.hdr, CONTROLVM_RESP_SUCCESS); - err = visorchannel_signalinsert(chipset_dev->controlvm_channel, - CONTROLVM_QUEUE_ACK, &ackmsg); - if (err) - return err; - switch (inmsg.hdr.id) { - case CONTROLVM_CHIPSET_INIT: - err = chipset_init(&inmsg); - break; - case CONTROLVM_BUS_CREATE: - err = visorbus_create(&inmsg); - break; - case CONTROLVM_BUS_DESTROY: - err = visorbus_destroy(&inmsg); - break; - case CONTROLVM_BUS_CONFIGURE: - err = visorbus_configure(&inmsg, parser_ctx); - break; - case CONTROLVM_DEVICE_CREATE: - err = visorbus_device_create(&inmsg); - break; - case CONTROLVM_DEVICE_CHANGESTATE: - if (cmd->device_change_state.flags.phys_device) { - err = parahotplug_process_message(&inmsg); - } else { - /* - * save the hdr and cmd structures for later use when - * sending back the response to Command - */ - err = visorbus_device_changestate(&inmsg); - break; - } - break; - case CONTROLVM_DEVICE_DESTROY: - err = visorbus_device_destroy(&inmsg); - break; - case CONTROLVM_DEVICE_CONFIGURE: - /* no op just send a respond that we passed */ - if (inmsg.hdr.flags.response_expected) - controlvm_respond(&inmsg.hdr, CONTROLVM_RESP_SUCCESS, - NULL); - break; - case CONTROLVM_CHIPSET_READY: - err = chipset_ready_uevent(&inmsg.hdr); - break; - case CONTROLVM_CHIPSET_SELFTEST: - err = chipset_selftest_uevent(&inmsg.hdr); - break; - case CONTROLVM_CHIPSET_STOP: - err = chipset_notready_uevent(&inmsg.hdr); - break; - default: - err = -ENOMSG; - if (inmsg.hdr.flags.response_expected) - controlvm_respond(&inmsg.hdr, - -CONTROLVM_RESP_ID_UNKNOWN, NULL); - break; - } - if (parser_ctx) { - parser_done(parser_ctx); - parser_ctx = NULL; - } - return err; -} - -/* - * read_controlvm_event() - retreives the next message from the - * CONTROLVM_QUEUE_EVENT queue in the controlvm - * channel - * @msg: pointer to the retrieved message - * - * Return: 0 if valid message was retrieved or -error - */ -static int read_controlvm_event(struct controlvm_message *msg) -{ - int err = visorchannel_signalremove(chipset_dev->controlvm_channel, - CONTROLVM_QUEUE_EVENT, msg); - - if (err) - return err; - /* got a message */ - if (msg->hdr.flags.test_message == 1) - return -EINVAL; - return 0; -} - -/* - * parahotplug_process_list() - remove any request from the list that's been on - * there too long and respond with an error - */ -static void parahotplug_process_list(void) -{ - struct list_head *pos; - struct list_head *tmp; - - spin_lock(¶hotplug_request_list_lock); - list_for_each_safe(pos, tmp, ¶hotplug_request_list) { - struct parahotplug_request *req = - list_entry(pos, struct parahotplug_request, list); - - if (!time_after_eq(jiffies, req->expiration)) - continue; - list_del(pos); - if (req->msg.hdr.flags.response_expected) - controlvm_respond( - &req->msg.hdr, - CONTROLVM_RESP_DEVICE_UDEV_TIMEOUT, - &req->msg.cmd.device_change_state.state); - parahotplug_request_destroy(req); - } - spin_unlock(¶hotplug_request_list_lock); -} - -static void controlvm_periodic_work(struct work_struct *work) -{ - struct controlvm_message inmsg; - int count = 0; - int err; - - /* Drain the RESPONSE queue make it empty */ - do { - err = visorchannel_signalremove(chipset_dev->controlvm_channel, - CONTROLVM_QUEUE_RESPONSE, - &inmsg); - } while ((!err) && (++count < CONTROLVM_MESSAGE_MAX)); - if (err != -EAGAIN) - goto schedule_out; - if (chipset_dev->controlvm_pending_msg_valid) { - /* - * we throttled processing of a prior msg, so try to process - * it again rather than reading a new one - */ - inmsg = chipset_dev->controlvm_pending_msg; - chipset_dev->controlvm_pending_msg_valid = false; - err = 0; - } else { - err = read_controlvm_event(&inmsg); - } - while (!err) { - chipset_dev->most_recent_message_jiffies = jiffies; - err = handle_command(inmsg, - visorchannel_get_physaddr - (chipset_dev->controlvm_channel)); - if (err == -EAGAIN) { - chipset_dev->controlvm_pending_msg = inmsg; - chipset_dev->controlvm_pending_msg_valid = true; - break; - } - - err = read_controlvm_event(&inmsg); - } - /* parahotplug_worker */ - parahotplug_process_list(); - -/* - * The controlvm messages are sent in a bulk. If we start receiving messages, we - * want the polling to be fast. If we do not receive any message for - * MIN_IDLE_SECONDS, we can slow down the polling. - */ -schedule_out: - if (time_after(jiffies, chipset_dev->most_recent_message_jiffies + - (HZ * MIN_IDLE_SECONDS))) { - /* - * it's been longer than MIN_IDLE_SECONDS since we processed - * our last controlvm message; slow down the polling - */ - if (chipset_dev->poll_jiffies != POLLJIFFIES_CONTROLVM_SLOW) - chipset_dev->poll_jiffies = POLLJIFFIES_CONTROLVM_SLOW; - } else { - if (chipset_dev->poll_jiffies != POLLJIFFIES_CONTROLVM_FAST) - chipset_dev->poll_jiffies = POLLJIFFIES_CONTROLVM_FAST; - } - schedule_delayed_work(&chipset_dev->periodic_controlvm_work, - chipset_dev->poll_jiffies); -} - -static int visorchipset_init(struct acpi_device *acpi_device) -{ - int err = -ENODEV; - struct visorchannel *controlvm_channel; - - chipset_dev = kzalloc(sizeof(*chipset_dev), GFP_KERNEL); - if (!chipset_dev) - goto error; - err = controlvm_channel_create(chipset_dev); - if (err) - goto error_free_chipset_dev; - acpi_device->driver_data = chipset_dev; - chipset_dev->acpi_device = acpi_device; - chipset_dev->poll_jiffies = POLLJIFFIES_CONTROLVM_FAST; - err = sysfs_create_groups(&chipset_dev->acpi_device->dev.kobj, - visorchipset_dev_groups); - if (err < 0) - goto error_destroy_channel; - controlvm_channel = chipset_dev->controlvm_channel; - if (!visor_check_channel(visorchannel_get_header(controlvm_channel), - &chipset_dev->acpi_device->dev, - &visor_controlvm_channel_guid, - "controlvm", - sizeof(struct visor_controlvm_channel), - VISOR_CONTROLVM_CHANNEL_VERSIONID, - VISOR_CHANNEL_SIGNATURE)) - goto error_delete_groups; - /* if booting in a crash kernel */ - if (is_kdump_kernel()) - INIT_DELAYED_WORK(&chipset_dev->periodic_controlvm_work, - setup_crash_devices_work_queue); - else - INIT_DELAYED_WORK(&chipset_dev->periodic_controlvm_work, - controlvm_periodic_work); - chipset_dev->most_recent_message_jiffies = jiffies; - chipset_dev->poll_jiffies = POLLJIFFIES_CONTROLVM_FAST; - schedule_delayed_work(&chipset_dev->periodic_controlvm_work, - chipset_dev->poll_jiffies); - err = visorbus_init(); - if (err < 0) - goto error_cancel_work; - return 0; - -error_cancel_work: - cancel_delayed_work_sync(&chipset_dev->periodic_controlvm_work); - -error_delete_groups: - sysfs_remove_groups(&chipset_dev->acpi_device->dev.kobj, - visorchipset_dev_groups); - -error_destroy_channel: - visorchannel_destroy(chipset_dev->controlvm_channel); - -error_free_chipset_dev: - kfree(chipset_dev); - -error: - dev_err(&acpi_device->dev, "failed with error %d\n", err); - return err; -} - -static int visorchipset_exit(struct acpi_device *acpi_device) -{ - visorbus_exit(); - cancel_delayed_work_sync(&chipset_dev->periodic_controlvm_work); - sysfs_remove_groups(&chipset_dev->acpi_device->dev.kobj, - visorchipset_dev_groups); - visorchannel_destroy(chipset_dev->controlvm_channel); - kfree(chipset_dev); - return 0; -} - -static const struct acpi_device_id unisys_device_ids[] = { - {"PNP0A07", 0}, - {"", 0}, -}; - -static struct acpi_driver unisys_acpi_driver = { - .name = "unisys_acpi", - .class = "unisys_acpi_class", - .owner = THIS_MODULE, - .ids = unisys_device_ids, - .ops = { - .add = visorchipset_init, - .remove = visorchipset_exit, - }, -}; - -MODULE_DEVICE_TABLE(acpi, unisys_device_ids); - -static __init int visorutil_spar_detect(void) -{ - unsigned int eax, ebx, ecx, edx; - - if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) { - /* check the ID */ - cpuid(UNISYS_VISOR_LEAF_ID, &eax, &ebx, &ecx, &edx); - return (ebx == UNISYS_VISOR_ID_EBX) && - (ecx == UNISYS_VISOR_ID_ECX) && - (edx == UNISYS_VISOR_ID_EDX); - } - return 0; -} - -static int __init init_unisys(void) -{ - int result; - - if (!visorutil_spar_detect()) - return -ENODEV; - result = acpi_bus_register_driver(&unisys_acpi_driver); - if (result) - return -ENODEV; - pr_info("Unisys Visorchipset Driver Loaded.\n"); - return 0; -}; - -static void __exit exit_unisys(void) -{ - acpi_bus_unregister_driver(&unisys_acpi_driver); -} - -module_init(init_unisys); -module_exit(exit_unisys); - -MODULE_AUTHOR("Unisys"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("s-Par visorbus driver for virtual device buses"); diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c b/drivers/staging/unisys/visorhba/visorhba_main.c index 0bcd3acb7b0c..167e98f8688e 100644 --- a/drivers/staging/unisys/visorhba/visorhba_main.c +++ b/drivers/staging/unisys/visorhba/visorhba_main.c @@ -1,17 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 2012 - 2015 UNISYS CORPORATION * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. */ #include <linux/debugfs.h> @@ -19,12 +9,12 @@ #include <linux/idr.h> #include <linux/module.h> #include <linux/seq_file.h> +#include <linux/visorbus.h> #include <scsi/scsi.h> #include <scsi/scsi_host.h> #include <scsi/scsi_cmnd.h> #include <scsi/scsi_device.h> -#include "visorbus.h" #include "iochannel.h" /* The Send and Receive Buffers of the IO Queue may both be full */ diff --git a/drivers/staging/unisys/visorinput/ultrainputreport.h b/drivers/staging/unisys/visorinput/ultrainputreport.h index 53975a09535f..67dac430ce0c 100644 --- a/drivers/staging/unisys/visorinput/ultrainputreport.h +++ b/drivers/staging/unisys/visorinput/ultrainputreport.h @@ -1,16 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2010 - 2015 UNISYS CORPORATION * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. */ #ifndef __SPAR_ULTRAINPUTREPORT_H__ diff --git a/drivers/staging/unisys/visorinput/visorinput.c b/drivers/staging/unisys/visorinput/visorinput.c index 450f003743c0..d8048e48658f 100644 --- a/drivers/staging/unisys/visorinput/visorinput.c +++ b/drivers/staging/unisys/visorinput/visorinput.c @@ -1,16 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2011 - 2015 UNISYS CORPORATION * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. */ /* @@ -25,8 +16,8 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/uuid.h> +#include <linux/visorbus.h> -#include "visorbus.h" #include "ultrainputreport.h" /* Keyboard channel {c73416d0-b0b8-44af-b304-9d2ae99f1b3d} */ diff --git a/drivers/staging/unisys/visornic/visornic_main.c b/drivers/staging/unisys/visornic/visornic_main.c index 6d8239163ba5..92dceb557886 100644 --- a/drivers/staging/unisys/visornic/visornic_main.c +++ b/drivers/staging/unisys/visornic/visornic_main.c @@ -1,15 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2012 - 2015 UNISYS CORPORATION * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. */ /* This driver lives in a spar partition, and registers to ethernet io @@ -25,8 +16,8 @@ #include <linux/kthread.h> #include <linux/skbuff.h> #include <linux/rtnetlink.h> +#include <linux/visorbus.h> -#include "visorbus.h" #include "iochannel.h" #define VISORNIC_INFINITE_RSP_WAIT 0 diff --git a/drivers/staging/vboxvideo/vbox_fb.c b/drivers/staging/vboxvideo/vbox_fb.c index 8aed248db6e2..43c39eca4ae1 100644 --- a/drivers/staging/vboxvideo/vbox_fb.c +++ b/drivers/staging/vboxvideo/vbox_fb.c @@ -170,7 +170,7 @@ static int vboxfb_create(struct drm_fb_helper *helper, drm_fb_helper_fill_var(info, &fbdev->helper, sizes->fb_width, sizes->fb_height); - info->screen_base = bo->kmap.virtual; + info->screen_base = (char __iomem *)bo->kmap.virtual; info->screen_size = size; #ifdef CONFIG_DRM_KMS_FB_HELPER diff --git a/drivers/staging/vboxvideo/vbox_main.c b/drivers/staging/vboxvideo/vbox_main.c index 80bd039fa08e..973b3bcc04b1 100644 --- a/drivers/staging/vboxvideo/vbox_main.c +++ b/drivers/staging/vboxvideo/vbox_main.c @@ -61,7 +61,7 @@ void vbox_enable_accel(struct vbox_private *vbox) if (vbox->vbva_info[i].vbva) continue; - vbva = (void *)vbox->vbva_buffers + i * VBVA_MIN_BUFFER_SIZE; + vbva = (void __force *)vbox->vbva_buffers + i * VBVA_MIN_BUFFER_SIZE; if (!vbva_enable(&vbox->vbva_info[i], vbox->guest_pool, vbva, i)) { /* very old host or driver error. */ diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c index f484bb055df7..ec468d5719b1 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-ctl.c @@ -1,16 +1,5 @@ -/***************************************************************************** - * Copyright 2011 Broadcom Corporation. All rights reserved. - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2, available at - * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a - * license other than the GPL, without Broadcom's express prior written - * consent. - *****************************************************************************/ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright 2011 Broadcom Corporation. All rights reserved. */ #include <linux/platform_device.h> #include <linux/init.h> diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c index 7e68b3e28246..5f7551fbf5cf 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c @@ -1,16 +1,5 @@ -/***************************************************************************** - * Copyright 2011 Broadcom Corporation. All rights reserved. - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2, available at - * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a - * license other than the GPL, without Broadcom's express prior written - * consent. - *****************************************************************************/ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright 2011 Broadcom Corporation. All rights reserved. */ #include <linux/interrupt.h> #include <linux/slab.h> diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c index 3c6f1d91d22d..a4a48f31f1a3 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c @@ -1,16 +1,5 @@ -/***************************************************************************** - * Copyright 2011 Broadcom Corporation. All rights reserved. - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2, available at - * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a - * license other than the GPL, without Broadcom's express prior written - * consent. - *****************************************************************************/ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright 2011 Broadcom Corporation. All rights reserved. */ #include <linux/device.h> #include <sound/core.h> diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c index 8f2d508183b2..045d577fe4f8 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c @@ -1,16 +1,5 @@ -/***************************************************************************** - * Copyright 2011 Broadcom Corporation. All rights reserved. - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2, available at - * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a - * license other than the GPL, without Broadcom's express prior written - * consent. - *****************************************************************************/ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright 2011 Broadcom Corporation. All rights reserved. */ #include <linux/platform_device.h> @@ -443,7 +432,6 @@ static struct platform_driver bcm2835_alsa0_driver = { #endif .driver = { .name = "bcm2835_audio", - .owner = THIS_MODULE, .of_match_table = snd_bcm2835_of_match_table, }, }; diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h index f1e43e45fd67..dc6ec915f9f5 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.h @@ -1,16 +1,5 @@ -/***************************************************************************** - * Copyright 2011 Broadcom Corporation. All rights reserved. - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2, available at - * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a - * license other than the GPL, without Broadcom's express prior written - * consent. - *****************************************************************************/ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright 2011 Broadcom Corporation. All rights reserved. */ #ifndef __SOUND_ARM_BCM2835_H #define __SOUND_ARM_BCM2835_H diff --git a/drivers/staging/vc04_services/bcm2835-audio/vc_vchi_audioserv_defs.h b/drivers/staging/vc04_services/bcm2835-audio/vc_vchi_audioserv_defs.h index da96f1bc2516..1a7f0884ac9c 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/vc_vchi_audioserv_defs.h +++ b/drivers/staging/vc04_services/bcm2835-audio/vc_vchi_audioserv_defs.h @@ -1,16 +1,5 @@ -/***************************************************************************** - * Copyright 2011 Broadcom Corporation. All rights reserved. - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2, available at - * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a - * license other than the GPL, without Broadcom's express prior written - * consent. - *****************************************************************************/ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright 2011 Broadcom Corporation. All rights reserved. */ #ifndef _VC_AUDIO_DEFS_H_ #define _VC_AUDIO_DEFS_H_ diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c index be936b8fe317..d2262275a870 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c +++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Broadcom BM2835 V4L2 driver * * Copyright © 2013 Raspberry Pi (Trading) Ltd. * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - * * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> * Dave Stevenson <dsteve@broadcom.com> * Simon Mellor <simellor@broadcom.com> @@ -328,11 +325,9 @@ static void buffer_cb(struct vchiq_mmal_instance *instance, pr_debug("Grab another frame"); vchiq_mmal_port_parameter_set( instance, - dev->capture. - camera_port, + dev->capture.camera_port, MMAL_PARAMETER_CAPTURE, - &dev->capture. - frame_count, + &dev->capture.frame_count, sizeof(dev->capture.frame_count)); } } else { @@ -343,37 +338,17 @@ static void buffer_cb(struct vchiq_mmal_instance *instance, if (dev->capture.frame_count) { if (dev->capture.vc_start_timestamp != -1 && pts != 0) { - struct timeval timestamp; + ktime_t timestamp; s64 runtime_us = pts - dev->capture.vc_start_timestamp; - u32 div = 0; - u32 rem = 0; - - div = - div_u64_rem(runtime_us, USEC_PER_SEC, &rem); - timestamp.tv_sec = - dev->capture.kernel_start_ts.tv_sec + div; - timestamp.tv_usec = - dev->capture.kernel_start_ts.tv_usec + rem; - - if (timestamp.tv_usec >= - USEC_PER_SEC) { - timestamp.tv_sec++; - timestamp.tv_usec -= - USEC_PER_SEC; - } + timestamp = ktime_add_us(dev->capture.kernel_start_ts, + runtime_us); v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, - "Convert start time %d.%06d and %llu " - "with offset %llu to %d.%06d\n", - (int)dev->capture.kernel_start_ts. - tv_sec, - (int)dev->capture.kernel_start_ts. - tv_usec, + "Convert start time %llu and %llu with offset %llu to %llu\n", + ktime_to_ns(dev->capture.kernel_start_ts), dev->capture.vc_start_timestamp, pts, - (int)timestamp.tv_sec, - (int)timestamp.tv_usec); - buf->vb.vb2_buf.timestamp = timestamp.tv_sec * 1000000000ULL + - timestamp.tv_usec * 1000ULL; + ktime_to_ns(timestamp)); + buf->vb.vb2_buf.timestamp = ktime_to_ns(timestamp); } else { buf->vb.vb2_buf.timestamp = ktime_get_ns(); } @@ -387,11 +362,9 @@ static void buffer_cb(struct vchiq_mmal_instance *instance, "Grab another frame as buffer has EOS"); vchiq_mmal_port_parameter_set( instance, - dev->capture. - camera_port, + dev->capture.camera_port, MMAL_PARAMETER_CAPTURE, - &dev->capture. - frame_count, + &dev->capture.frame_count, sizeof(dev->capture.frame_count)); } } else { @@ -547,7 +520,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) "Start time %lld size %d\n", dev->capture.vc_start_timestamp, parameter_size); - v4l2_get_timestamp(&dev->capture.kernel_start_ts); + dev->capture.kernel_start_ts = ktime_get(); /* enable the camera port */ dev->capture.port->cb_ctx = dev; @@ -555,8 +528,8 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) vchiq_mmal_port_enable(dev->instance, dev->capture.port, buffer_cb); if (ret) { v4l2_err(&dev->v4l2_dev, - "Failed to enable capture port - error %d. " - "Disabling camera port again\n", ret); + "Failed to enable capture port - error %d. Disabling camera port again\n", + ret); vchiq_mmal_port_disable(dev->instance, dev->capture.camera_port); @@ -1213,8 +1186,8 @@ static int mmal_setup_components(struct bm2835_mmal_dev *dev, port->current_buffer.size = (f->fmt.pix.sizeimage < (100 << 10)) - ? (100 << 10) : f->fmt.pix. - sizeimage; + ? (100 << 10) + : f->fmt.pix.sizeimage; } v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h index 404037476bc5..2b5679eb5b4a 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h +++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h @@ -1,12 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Broadcom BM2835 V4L2 driver * * Copyright © 2013 Raspberry Pi (Trading) Ltd. * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - * * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> * Dave Stevenson <dsteve@broadcom.com> * Simon Mellor <simellor@broadcom.com> @@ -92,7 +89,7 @@ struct bm2835_mmal_dev { /* VC start timestamp for streaming */ s64 vc_start_timestamp; /* Kernel start timestamp for streaming */ - struct timeval kernel_start_ts; + ktime_t kernel_start_ts; struct vchiq_mmal_port *port; /* port being used for capture */ /* camera port being used for capture */ diff --git a/drivers/staging/vc04_services/bcm2835-camera/controls.c b/drivers/staging/vc04_services/bcm2835-camera/controls.c index 77a5d6f4e1eb..0736214e1422 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/controls.c +++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Broadcom BM2835 V4L2 driver * * Copyright © 2013 Raspberry Pi (Trading) Ltd. * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - * * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> * Dave Stevenson <dsteve@broadcom.com> * Simon Mellor <simellor@broadcom.com> diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h b/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h index 840fd139e033..800e4e7e5f96 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h +++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-common.h @@ -1,12 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Broadcom BM2835 V4L2 driver * * Copyright © 2013 Raspberry Pi (Trading) Ltd. * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - * * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> * Dave Stevenson <dsteve@broadcom.com> * Simon Mellor <simellor@broadcom.com> diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-encodings.h b/drivers/staging/vc04_services/bcm2835-camera/mmal-encodings.h index e71d9600b278..129203597f91 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-encodings.h +++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-encodings.h @@ -1,12 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Broadcom BM2835 V4L2 driver * * Copyright © 2013 Raspberry Pi (Trading) Ltd. * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - * * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> * Dave Stevenson <dsteve@broadcom.com> * Simon Mellor <simellor@broadcom.com> diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-common.h b/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-common.h index 66e8a6edf628..ec8455639d49 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-common.h +++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-common.h @@ -1,12 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Broadcom BM2835 V4L2 driver * * Copyright © 2013 Raspberry Pi (Trading) Ltd. * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - * * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> * Dave Stevenson <dsteve@broadcom.com> * Simon Mellor <simellor@broadcom.com> diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-format.h b/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-format.h index 24b002e8df0c..c9d6fbe25fe4 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-format.h +++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-format.h @@ -1,12 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Broadcom BM2835 V4L2 driver * * Copyright © 2013 Raspberry Pi (Trading) Ltd. * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - * * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> * Dave Stevenson <dsteve@broadcom.com> * Simon Mellor <simellor@broadcom.com> diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-port.h b/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-port.h index 84a0f4b717ef..dd4b4ce72081 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-port.h +++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-msg-port.h @@ -1,12 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Broadcom BM2835 V4L2 driver * * Copyright © 2013 Raspberry Pi (Trading) Ltd. * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - * * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> * Dave Stevenson <dsteve@broadcom.com> * Simon Mellor <simellor@broadcom.com> diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg.h b/drivers/staging/vc04_services/bcm2835-camera/mmal-msg.h index 5a1b2a7d8eb0..d1c57edbe2b8 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-msg.h +++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-msg.h @@ -1,12 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Broadcom BM2835 V4L2 driver * * Copyright © 2013 Raspberry Pi (Trading) Ltd. * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - * * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> * Dave Stevenson <dsteve@broadcom.com> * Simon Mellor <simellor@broadcom.com> diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-parameters.h b/drivers/staging/vc04_services/bcm2835-camera/mmal-parameters.h index e7300229842d..1607bc4c0347 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-parameters.h +++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-parameters.h @@ -1,12 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Broadcom BM2835 V4L2 driver * * Copyright © 2013 Raspberry Pi (Trading) Ltd. * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - * * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> * Dave Stevenson <dsteve@broadcom.com> * Simon Mellor <simellor@broadcom.com> diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c index 6ea7fb0ea50e..a91ef6ea29ce 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c +++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Broadcom BM2835 V4L2 driver * * Copyright © 2013 Raspberry Pi (Trading) Ltd. * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - * * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> * Dave Stevenson <dsteve@broadcom.com> * Simon Mellor <simellor@broadcom.com> @@ -618,8 +615,8 @@ static void buffer_to_host_cb(struct vchiq_mmal_instance *instance, struct mmal_msg_context *msg_context; u32 handle; - pr_debug("buffer_to_host_cb: instance:%p msg:%p msg_len:%d\n", - instance, msg, msg_len); + pr_debug("%s: instance:%p msg:%p msg_len:%d\n", + __func__, instance, msg, msg_len); if (msg->u.buffer_from_host.drvbuf.magic == MMAL_MAGIC) { handle = msg->u.buffer_from_host.drvbuf.client_context; @@ -1360,8 +1357,7 @@ static int port_action_handle(struct vchiq_mmal_instance *instance, ret = -rmsg->u.port_action_reply.status; - pr_debug("%s:result:%d component:0x%x port:%d action:%s(%d)" \ - " connect component:0x%x connect port:%d\n", + pr_debug("%s:result:%d component:0x%x port:%d action:%s(%d) connect component:0x%x connect port:%d\n", __func__, ret, port->component->handle, port->handle, port_action_type_names[action_type], diff --git a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h index db39900c9d91..b1f22b6dca10 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h +++ b/drivers/staging/vc04_services/bcm2835-camera/mmal-vchiq.h @@ -1,12 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Broadcom BM2835 V4L2 driver * * Copyright © 2013 Raspberry Pi (Trading) Ltd. * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - * * Authors: Vincent Sanders <vincent.sanders@collabora.co.uk> * Dave Stevenson <dsteve@broadcom.com> * Simon Mellor <simellor@broadcom.com> diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c index 315b49c1de3b..b59ef14890aa 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c @@ -224,8 +224,7 @@ vchiq_platform_get_arm_state(VCHIQ_STATE_T *state) platform_state = (struct vchiq_2835_state *)state->platform_state; - if (!platform_state->inited) - BUG(); + WARN_ON_ONCE(!platform_state->inited); return &platform_state->arm_state; } @@ -485,8 +484,7 @@ create_pagelist(char __user *buf, size_t count, unsigned short type) __func__, actual_pages, num_pages); /* This is probably due to the process being killed */ - while (actual_pages > 0) - { + while (actual_pages > 0) { actual_pages--; put_page(pages[actual_pages]); } diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c index 411539f8ff8c..c2c440009cac 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c @@ -682,8 +682,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (user_service->close_pending && down_interruptible(&user_service->close_event)) status = VCHIQ_RETRY; - } - else + } else ret = -EINVAL; } break; @@ -708,8 +707,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (user_service->close_pending && down_interruptible(&user_service->close_event)) status = VCHIQ_RETRY; - } - else + } else ret = -EINVAL; } break; @@ -1171,8 +1169,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) USER_SERVICE_T *user_service = (USER_SERVICE_T *)service->base.userdata; close_delivered(user_service); - } - else + } else ret = -EINVAL; } break; @@ -1810,8 +1807,7 @@ vchiq_release(struct inode *inode, struct file *file) instance->completion_remove & (MAX_COMPLETIONS - 1)]; service = completion->service_userdata; - if (completion->reason == VCHIQ_SERVICE_CLOSED) - { + if (completion->reason == VCHIQ_SERVICE_CLOSED) { USER_SERVICE_T *user_service = service->base.userdata; diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c index ecff92bae200..5d28fff46557 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c @@ -66,8 +66,7 @@ struct vchiq_openack_payload { short version; }; -enum -{ +enum { QMFLAGS_IS_BLOCKING = (1 << 0), QMFLAGS_NO_MUTEX_LOCK = (1 << 1), QMFLAGS_NO_MUTEX_UNLOCK = (1 << 2) @@ -212,7 +211,8 @@ find_service_by_port(VCHIQ_STATE_T *state, int localport) VCHIQ_SERVICE_T * find_service_for_instance(VCHIQ_INSTANCE_T instance, - VCHIQ_SERVICE_HANDLE_T handle) { + VCHIQ_SERVICE_HANDLE_T handle) +{ VCHIQ_SERVICE_T *service; spin_lock(&service_spinlock); @@ -235,7 +235,8 @@ find_service_for_instance(VCHIQ_INSTANCE_T instance, VCHIQ_SERVICE_T * find_closed_service_for_instance(VCHIQ_INSTANCE_T instance, - VCHIQ_SERVICE_HANDLE_T handle) { + VCHIQ_SERVICE_HANDLE_T handle) +{ VCHIQ_SERVICE_T *service; spin_lock(&service_spinlock); diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c index 34f746db19cd..43c89a08bda9 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_kern_lib.c @@ -64,11 +64,6 @@ static VCHIQ_STATUS_T vchiq_blocking_bulk_transfer(VCHIQ_SERVICE_HANDLE_T handle, void *data, unsigned int size, VCHIQ_BULK_DIR_T dir); -/**************************************************************************** -* -* vchiq_initialise -* -***************************************************************************/ #define VCHIQ_INIT_RETRIES 10 VCHIQ_STATUS_T vchiq_initialise(VCHIQ_INSTANCE_T *instance_out) { @@ -80,7 +75,9 @@ VCHIQ_STATUS_T vchiq_initialise(VCHIQ_INSTANCE_T *instance_out) vchiq_log_trace(vchiq_core_log_level, "%s called", __func__); /* VideoCore may not be ready due to boot up timing. - It may never be ready if kernel and firmware are mismatched, so don't block forever. */ + * It may never be ready if kernel and firmware are mismatched,so don't + * block forever. + */ for (i = 0; i < VCHIQ_INIT_RETRIES; i++) { state = vchiq_get_state(); if (state) @@ -93,7 +90,8 @@ VCHIQ_STATUS_T vchiq_initialise(VCHIQ_INSTANCE_T *instance_out) goto failed; } else if (i > 0) { vchiq_log_warning(vchiq_core_log_level, - "%s: videocore initialized after %d retries\n", __func__, i); + "%s: videocore initialized after %d retries\n", + __func__, i); } instance = kzalloc(sizeof(*instance), GFP_KERNEL); @@ -120,12 +118,6 @@ failed: } EXPORT_SYMBOL(vchiq_initialise); -/**************************************************************************** -* -* vchiq_shutdown -* -***************************************************************************/ - VCHIQ_STATUS_T vchiq_shutdown(VCHIQ_INSTANCE_T instance) { VCHIQ_STATUS_T status; @@ -168,23 +160,11 @@ VCHIQ_STATUS_T vchiq_shutdown(VCHIQ_INSTANCE_T instance) } EXPORT_SYMBOL(vchiq_shutdown); -/**************************************************************************** -* -* vchiq_is_connected -* -***************************************************************************/ - static int vchiq_is_connected(VCHIQ_INSTANCE_T instance) { return instance->connected; } -/**************************************************************************** -* -* vchiq_connect -* -***************************************************************************/ - VCHIQ_STATUS_T vchiq_connect(VCHIQ_INSTANCE_T instance) { VCHIQ_STATUS_T status; @@ -214,12 +194,6 @@ failed: } EXPORT_SYMBOL(vchiq_connect); -/**************************************************************************** -* -* vchiq_add_service -* -***************************************************************************/ - VCHIQ_STATUS_T vchiq_add_service( VCHIQ_INSTANCE_T instance, const VCHIQ_SERVICE_PARAMS_T *params, @@ -259,12 +233,6 @@ VCHIQ_STATUS_T vchiq_add_service( } EXPORT_SYMBOL(vchiq_add_service); -/**************************************************************************** -* -* vchiq_open_service -* -***************************************************************************/ - VCHIQ_STATUS_T vchiq_open_service( VCHIQ_INSTANCE_T instance, const VCHIQ_SERVICE_PARAMS_T *params, @@ -414,8 +382,9 @@ vchiq_blocking_bulk_transfer(VCHIQ_SERVICE_HANDLE_T handle, void *data, if ((bulk->data != data) || (bulk->size != size)) { /* This is not a retry of the previous one. - ** Cancel the signal when the transfer - ** completes. */ + * Cancel the signal when the transfer + * completes. + */ spin_lock(&bulk_waiter_spinlock); bulk->userdata = NULL; spin_unlock(&bulk_waiter_spinlock); @@ -441,7 +410,8 @@ vchiq_blocking_bulk_transfer(VCHIQ_SERVICE_HANDLE_T handle, void *data, if (bulk) { /* Cancel the signal when the transfer - ** completes. */ + * completes. + */ spin_lock(&bulk_waiter_spinlock); bulk->userdata = NULL; spin_unlock(&bulk_waiter_spinlock); diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c index d465e1cf5db9..29984f9795c7 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c @@ -800,8 +800,7 @@ int32_t vchi_get_peer_version(const VCHI_SERVICE_HANDLE_T handle, short *peer_ve int32_t ret = -1; struct shim_service *service = (struct shim_service *)handle; - if (service) - { + if (service) { VCHIQ_STATUS_T status; status = vchiq_get_peer_version(service->handle, peer_version); diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index 4c8c6fa0a79f..3242dee8246f 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * VMEbus User access driver * @@ -7,12 +8,6 @@ * Based on work by: * Tom Armistead and Ajit Prem * Copyright 2004 Motorola Inc. - * - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -573,7 +568,7 @@ static int vme_user_probe(struct vme_dev *vdev) * by all windows. */ image[i].resource = vme_slave_request(vme_user_bridge, - VME_A24, VME_SCT); + VME_A24, VME_SCT); if (!image[i].resource) { dev_warn(&vdev->dev, "Unable to allocate slave resource\n"); @@ -582,7 +577,8 @@ static int vme_user_probe(struct vme_dev *vdev) } image[i].size_buf = PCI_BUF_SIZE; image[i].kern_buf = vme_alloc_consistent(image[i].resource, - image[i].size_buf, &image[i].pci_buf); + image[i].size_buf, + &image[i].pci_buf); if (!image[i].kern_buf) { dev_warn(&vdev->dev, "Unable to allocate memory for buffer\n"); @@ -600,7 +596,8 @@ static int vme_user_probe(struct vme_dev *vdev) for (i = MASTER_MINOR; i < (MASTER_MAX + 1); i++) { /* XXX Need to properly request attributes */ image[i].resource = vme_master_request(vme_user_bridge, - VME_A32, VME_SCT, VME_D32); + VME_A32, VME_SCT, + VME_D32); if (!image[i].resource) { dev_warn(&vdev->dev, "Unable to allocate master resource\n"); @@ -645,7 +642,8 @@ static int vme_user_probe(struct vme_dev *vdev) num = (type[i] == SLAVE_MINOR) ? i - (MASTER_MAX + 1) : i; image[i].device = device_create(vme_user_sysfs_class, NULL, - MKDEV(VME_MAJOR, i), NULL, name, num); + MKDEV(VME_MAJOR, i), NULL, + name, num); if (IS_ERR(image[i].device)) { dev_info(&vdev->dev, "Error creating sysfs device\n"); err = PTR_ERR(image[i].device); diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index 44dfa5421374..f0b163473426 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * File: baseband.c * * Purpose: Implement functions to access baseband diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h index feaf222574ee..b8ee33dcb352 100644 --- a/drivers/staging/vt6655/baseband.h +++ b/drivers/staging/vt6655/baseband.h @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * File: baseband.h * * Purpose: Implement functions to access baseband diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index 14034e342aa6..ea0a4b57852c 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * File: card.c * Purpose: Provide functions to setup NIC operation mode * Functions: diff --git a/drivers/staging/vt6655/card.h b/drivers/staging/vt6655/card.h index 1a04dbb57d42..487039a64587 100644 --- a/drivers/staging/vt6655/card.h +++ b/drivers/staging/vt6655/card.h @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * File: card.h * * Purpose: Provide functions to setup NIC operation mode diff --git a/drivers/staging/vt6655/channel.c b/drivers/staging/vt6655/channel.c index ab89956511a0..dec6f0f23b88 100644 --- a/drivers/staging/vt6655/channel.c +++ b/drivers/staging/vt6655/channel.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * File: channel.c * */ diff --git a/drivers/staging/vt6655/channel.h b/drivers/staging/vt6655/channel.h index 8fe70760e548..53f623a4af65 100644 --- a/drivers/staging/vt6655/channel.h +++ b/drivers/staging/vt6655/channel.h @@ -1,19 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * File: channel.h - * */ #ifndef _CHANNEL_H_ diff --git a/drivers/staging/vt6655/desc.h b/drivers/staging/vt6655/desc.h index 2fee6e759ad8..b4a0037b40c1 100644 --- a/drivers/staging/vt6655/desc.h +++ b/drivers/staging/vt6655/desc.h @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * File: desc.h * * Purpose:The header file of descriptor diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index 3ae40d846a09..2f9e9219e8c8 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * File: device.h * * Purpose: MAC Data structure diff --git a/drivers/staging/vt6655/device_cfg.h b/drivers/staging/vt6655/device_cfg.h index 0298ea923f97..73f904b51b96 100644 --- a/drivers/staging/vt6655/device_cfg.h +++ b/drivers/staging/vt6655/device_cfg.h @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * File: device_cfg.h * * Purpose: Driver configuration header diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 1123b4f1e1d6..0dc902022a91 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * File: device_main.c * * Purpose: driver entry for initial, open, close, tx and rx. @@ -547,7 +538,7 @@ static void device_init_rd0_ring(struct vnt_private *priv) for (i = 0; i < priv->opts.rx_descs0; i ++, curr += sizeof(struct vnt_rx_desc)) { desc = &priv->aRD0Ring[i]; - desc->rd_info = kzalloc(sizeof(*desc->rd_info), GFP_ATOMIC); + desc->rd_info = kzalloc(sizeof(*desc->rd_info), GFP_KERNEL); if (!device_alloc_rx_buf(priv, desc)) dev_err(&priv->pcid->dev, "can not alloc rx bufs\n"); @@ -571,7 +562,7 @@ static void device_init_rd1_ring(struct vnt_private *priv) for (i = 0; i < priv->opts.rx_descs1; i ++, curr += sizeof(struct vnt_rx_desc)) { desc = &priv->aRD1Ring[i]; - desc->rd_info = kzalloc(sizeof(*desc->rd_info), GFP_ATOMIC); + desc->rd_info = kzalloc(sizeof(*desc->rd_info), GFP_KERNEL); if (!device_alloc_rx_buf(priv, desc)) dev_err(&priv->pcid->dev, "can not alloc rx bufs\n"); @@ -629,7 +620,7 @@ static void device_init_td0_ring(struct vnt_private *priv) for (i = 0; i < priv->opts.tx_descs[0]; i++, curr += sizeof(struct vnt_tx_desc)) { desc = &priv->apTD0Rings[i]; - desc->td_info = kzalloc(sizeof(*desc->td_info), GFP_ATOMIC); + desc->td_info = kzalloc(sizeof(*desc->td_info), GFP_KERNEL); desc->td_info->buf = priv->tx0_bufs + i * PKT_BUF_SZ; desc->td_info->buf_dma = priv->tx_bufs_dma0 + i * PKT_BUF_SZ; @@ -654,7 +645,7 @@ static void device_init_td1_ring(struct vnt_private *priv) for (i = 0; i < priv->opts.tx_descs[1]; i++, curr += sizeof(struct vnt_tx_desc)) { desc = &priv->apTD1Rings[i]; - desc->td_info = kzalloc(sizeof(*desc->td_info), GFP_ATOMIC); + desc->td_info = kzalloc(sizeof(*desc->td_info), GFP_KERNEL); desc->td_info->buf = priv->tx1_bufs + i * PKT_BUF_SZ; desc->td_info->buf_dma = priv->tx_bufs_dma1 + i * PKT_BUF_SZ; diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c index 9b3fa779258a..088d2d9dbc21 100644 --- a/drivers/staging/vt6655/dpc.c +++ b/drivers/staging/vt6655/dpc.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * File: dpc.c * * Purpose: handle dpc rx functions diff --git a/drivers/staging/vt6655/dpc.h b/drivers/staging/vt6655/dpc.h index 6e75fa9c5618..93af4220605f 100644 --- a/drivers/staging/vt6655/dpc.h +++ b/drivers/staging/vt6655/dpc.h @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * File: dpc.h * * Purpose: diff --git a/drivers/staging/vt6655/key.c b/drivers/staging/vt6655/key.c index d891993b20cf..4d6b48fd119d 100644 --- a/drivers/staging/vt6655/key.c +++ b/drivers/staging/vt6655/key.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * File: key.c * * Purpose: Implement functions for 802.11i Key management diff --git a/drivers/staging/vt6655/key.h b/drivers/staging/vt6655/key.h index a5024611af60..0942d8703f98 100644 --- a/drivers/staging/vt6655/key.h +++ b/drivers/staging/vt6655/key.h @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * File: key.h * * Purpose: Implement functions for 802.11i Key management diff --git a/drivers/staging/vt6655/mac.c b/drivers/staging/vt6655/mac.c index f7550b215f72..4750863c1bb7 100644 --- a/drivers/staging/vt6655/mac.c +++ b/drivers/staging/vt6655/mac.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * File: mac.c * * Purpose: MAC routines diff --git a/drivers/staging/vt6655/mac.h b/drivers/staging/vt6655/mac.h index db401e32ae23..b8ab09434773 100644 --- a/drivers/staging/vt6655/mac.h +++ b/drivers/staging/vt6655/mac.h @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * File: mac.h * * Purpose: MAC routines diff --git a/drivers/staging/vt6655/power.c b/drivers/staging/vt6655/power.c index 716d2a80f840..d6c581b31569 100644 --- a/drivers/staging/vt6655/power.c +++ b/drivers/staging/vt6655/power.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * File: power.c * * Purpose: Handles 802.11 power management functions diff --git a/drivers/staging/vt6655/power.h b/drivers/staging/vt6655/power.h index f360c5966523..2ec40045fddb 100644 --- a/drivers/staging/vt6655/power.h +++ b/drivers/staging/vt6655/power.h @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * File: power.h * * Purpose: Handles 802.11 power management functions diff --git a/drivers/staging/vt6655/rf.c b/drivers/staging/vt6655/rf.c index edf7db9d53b3..03b0d56dbe9e 100644 --- a/drivers/staging/vt6655/rf.c +++ b/drivers/staging/vt6655/rf.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * File: rf.c * * Purpose: rf function code diff --git a/drivers/staging/vt6655/rf.h b/drivers/staging/vt6655/rf.h index ba222301d49d..bfce5a89657d 100644 --- a/drivers/staging/vt6655/rf.h +++ b/drivers/staging/vt6655/rf.h @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * File: rf.h * * Purpose: diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 3efe19a1b13f..9aa4d5262aaa 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * File: rxtx.c * * Purpose: handle WMAC/802.3/802.11 rx & tx functions diff --git a/drivers/staging/vt6655/rxtx.h b/drivers/staging/vt6655/rxtx.h index 095258923ebd..08db848613f0 100644 --- a/drivers/staging/vt6655/rxtx.h +++ b/drivers/staging/vt6655/rxtx.h @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * File: rxtx.h * * Purpose: diff --git a/drivers/staging/vt6655/srom.c b/drivers/staging/vt6655/srom.c index 635f271595f6..df57d120ed30 100644 --- a/drivers/staging/vt6655/srom.c +++ b/drivers/staging/vt6655/srom.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * File: srom.c * * Purpose:Implement functions to access eeprom diff --git a/drivers/staging/vt6655/srom.h b/drivers/staging/vt6655/srom.h index 6e03ab6dfa9d..577f20dc4308 100644 --- a/drivers/staging/vt6655/srom.h +++ b/drivers/staging/vt6655/srom.h @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * File: srom.h * * Purpose: Implement functions to access eeprom diff --git a/drivers/staging/vt6655/tmacro.h b/drivers/staging/vt6655/tmacro.h index d6a0563ad55c..6795b5d74cfc 100644 --- a/drivers/staging/vt6655/tmacro.h +++ b/drivers/staging/vt6655/tmacro.h @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * File: tmacro.h * * Purpose: define basic common types and macros diff --git a/drivers/staging/vt6655/upc.h b/drivers/staging/vt6655/upc.h index 9806b5989014..61b3e568ff9a 100644 --- a/drivers/staging/vt6655/upc.h +++ b/drivers/staging/vt6655/upc.h @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * * File: upc.h * * Purpose: Macros to access device diff --git a/drivers/staging/vt6656/baseband.c b/drivers/staging/vt6656/baseband.c index 882fe54ce41d..b29ba237fa29 100644 --- a/drivers/staging/vt6656/baseband.c +++ b/drivers/staging/vt6656/baseband.c @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: baseband.c * * Purpose: Implement functions to access baseband diff --git a/drivers/staging/vt6656/baseband.h b/drivers/staging/vt6656/baseband.h index fe1c25c64cca..a907e3026012 100644 --- a/drivers/staging/vt6656/baseband.h +++ b/drivers/staging/vt6656/baseband.h @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: baseband.h * * Purpose: Implement functions to access baseband diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c index 4fd9cd64c6e8..501f482b41c4 100644 --- a/drivers/staging/vt6656/card.c +++ b/drivers/staging/vt6656/card.c @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: card.c * Purpose: Provide functions to setup NIC operation mode * Functions: diff --git a/drivers/staging/vt6656/card.h b/drivers/staging/vt6656/card.h index 7f08cda27e2c..0a91d9ba4688 100644 --- a/drivers/staging/vt6656/card.h +++ b/drivers/staging/vt6656/card.h @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: card.h * * Purpose: Provide functions to setup NIC operation mode diff --git a/drivers/staging/vt6656/channel.c b/drivers/staging/vt6656/channel.c index a4299f405d7f..5d57d34577f5 100644 --- a/drivers/staging/vt6656/channel.c +++ b/drivers/staging/vt6656/channel.c @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: channel.c * * Purpose: Channel number mapping diff --git a/drivers/staging/vt6656/channel.h b/drivers/staging/vt6656/channel.h index 62f18a959098..6d0d2825d992 100644 --- a/drivers/staging/vt6656/channel.h +++ b/drivers/staging/vt6656/channel.h @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: channel.h * * Purpose: Country Regulation Rules header file diff --git a/drivers/staging/vt6656/desc.h b/drivers/staging/vt6656/desc.h index 59e3071021bd..ac45ebb71195 100644 --- a/drivers/staging/vt6656/desc.h +++ b/drivers/staging/vt6656/desc.h @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: desc.h * * Purpose:The header file of descriptor diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h index 74715c854856..a2feeb916836 100644 --- a/drivers/staging/vt6656/device.h +++ b/drivers/staging/vt6656/device.h @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: device.h * * Purpose: MAC Data structure diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index 655f0002f880..c3b5b1431048 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: dpc.c * * Purpose: handle dpc rx functions diff --git a/drivers/staging/vt6656/dpc.h b/drivers/staging/vt6656/dpc.h index 5d0454f3af0e..ddd0cb710512 100644 --- a/drivers/staging/vt6656/dpc.h +++ b/drivers/staging/vt6656/dpc.h @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: dpc.h * * Purpose: diff --git a/drivers/staging/vt6656/firmware.c b/drivers/staging/vt6656/firmware.c index 093a6048bd22..38521c338917 100644 --- a/drivers/staging/vt6656/firmware.c +++ b/drivers/staging/vt6656/firmware.c @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: baseband.c * * Purpose: Implement functions to access baseband diff --git a/drivers/staging/vt6656/firmware.h b/drivers/staging/vt6656/firmware.h index f753019c94c9..f30ae90cbb1f 100644 --- a/drivers/staging/vt6656/firmware.h +++ b/drivers/staging/vt6656/firmware.h @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: firmware.h * * Purpose: Version and Release Information diff --git a/drivers/staging/vt6656/int.c b/drivers/staging/vt6656/int.c index c6ffbe0e2728..504424b19fcf 100644 --- a/drivers/staging/vt6656/int.c +++ b/drivers/staging/vt6656/int.c @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: int.c * * Purpose: Handle USB interrupt endpoint diff --git a/drivers/staging/vt6656/int.h b/drivers/staging/vt6656/int.h index b5f1b4b02ce4..1e6ff925701a 100644 --- a/drivers/staging/vt6656/int.h +++ b/drivers/staging/vt6656/int.h @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: int.h * * Purpose: diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c index cc18cb141bff..91dede54cc1f 100644 --- a/drivers/staging/vt6656/key.c +++ b/drivers/staging/vt6656/key.c @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: key.c * * Purpose: Implement functions for 802.11i Key management diff --git a/drivers/staging/vt6656/key.h b/drivers/staging/vt6656/key.h index cfc6c2131536..1306ff441b87 100644 --- a/drivers/staging/vt6656/key.h +++ b/drivers/staging/vt6656/key.h @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: key.h * * Purpose: Implement functions for 802.11i Key management diff --git a/drivers/staging/vt6656/mac.c b/drivers/staging/vt6656/mac.c index 417fdad1f9ae..0b543854ea97 100644 --- a/drivers/staging/vt6656/mac.c +++ b/drivers/staging/vt6656/mac.c @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: mac.c * * Purpose: MAC routines diff --git a/drivers/staging/vt6656/mac.h b/drivers/staging/vt6656/mac.h index 29f37a0ff156..94e700fcd0b6 100644 --- a/drivers/staging/vt6656/mac.h +++ b/drivers/staging/vt6656/mac.h @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: mac.h * * Purpose: MAC routines diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index cc6d8778fe5b..ccafcc2c87ac 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: main_usb.c * * Purpose: driver entry for initial, open, close, tx and rx. @@ -437,11 +427,8 @@ static bool vnt_alloc_bufs(struct vnt_private *priv) for (ii = 0; ii < priv->num_rcb; ii++) { priv->rcb[ii] = kzalloc(sizeof(*priv->rcb[ii]), GFP_KERNEL); - if (!priv->rcb[ii]) { - dev_err(&priv->usb->dev, - "failed to allocate rcb no %d\n", ii); + if (!priv->rcb[ii]) goto free_rx_tx; - } rcb = priv->rcb[ii]; diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c index c466e0614bc4..7a086c72d5a8 100644 --- a/drivers/staging/vt6656/power.c +++ b/drivers/staging/vt6656/power.c @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: power.c * * Purpose: Handles 802.11 power management functions diff --git a/drivers/staging/vt6656/power.h b/drivers/staging/vt6656/power.h index 859e75fc77ac..d5a3198206da 100644 --- a/drivers/staging/vt6656/power.h +++ b/drivers/staging/vt6656/power.h @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: power.h * * Purpose: Handles 802.11 power management functions diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c index 3a9d19a0b842..18f75dcc65d2 100644 --- a/drivers/staging/vt6656/rf.c +++ b/drivers/staging/vt6656/rf.c @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: rf.c * * Purpose: rf function code diff --git a/drivers/staging/vt6656/rf.h b/drivers/staging/vt6656/rf.h index c907a18047d2..f77866a9c177 100644 --- a/drivers/staging/vt6656/rf.h +++ b/drivers/staging/vt6656/rf.h @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: rf.h * * Purpose: diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index a44abcce6fb4..26ca3fa29301 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: rxtx.c * * Purpose: handle WMAC/802.3/802.11 rx & tx functions diff --git a/drivers/staging/vt6656/rxtx.h b/drivers/staging/vt6656/rxtx.h index 1ba8647bea86..44698f41a234 100644 --- a/drivers/staging/vt6656/rxtx.h +++ b/drivers/staging/vt6656/rxtx.h @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: rxtx.h * * Purpose: diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c index 23eaef458556..273176386a51 100644 --- a/drivers/staging/vt6656/usbpipe.c +++ b/drivers/staging/vt6656/usbpipe.c @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: usbpipe.c * * Purpose: Handle USB control endpoint diff --git a/drivers/staging/vt6656/usbpipe.h b/drivers/staging/vt6656/usbpipe.h index 9fc5ac0ef6c1..5d7708fcf557 100644 --- a/drivers/staging/vt6656/usbpipe.h +++ b/drivers/staging/vt6656/usbpipe.h @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: usbpipe.h * * Purpose: diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c index b2fc17f1381b..3eb2f11a5de1 100644 --- a/drivers/staging/vt6656/wcmd.c +++ b/drivers/staging/vt6656/wcmd.c @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: wcmd.c * * Purpose: Handles the management command interface functions diff --git a/drivers/staging/vt6656/wcmd.h b/drivers/staging/vt6656/wcmd.h index 727ec14380c4..4a96f4de980d 100644 --- a/drivers/staging/vt6656/wcmd.h +++ b/drivers/staging/vt6656/wcmd.h @@ -1,18 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. * All rights reserved. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * * File: wcmd.h * * Purpose: Handles the management command interface functions diff --git a/drivers/staging/wilc1000/coreconfigurator.c b/drivers/staging/wilc1000/coreconfigurator.c index 8cf886d32afb..e98fc8e93011 100644 --- a/drivers/staging/wilc1000/coreconfigurator.c +++ b/drivers/staging/wilc1000/coreconfigurator.c @@ -201,7 +201,7 @@ static inline u16 get_cap_info(u8 *data) st = get_sub_type(data); - if ((st == BEACON) || (st == PROBE_RSP)) + if (st == BEACON || st == PROBE_RSP) index += TIME_STAMP_LEN + BEACON_INTERVAL_LEN; cap_info = data[index]; diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c index d69248a8c7b5..358354b3a2b4 100644 --- a/drivers/staging/wilc1000/host_interface.c +++ b/drivers/staging/wilc1000/host_interface.c @@ -202,7 +202,7 @@ struct host_if_msg { }; struct join_bss_param { - BSSTYPE_T bss_type; + enum bss_types bss_type; u8 dtim_period; u16 beacon_period; u16 cap_info; @@ -394,7 +394,7 @@ static void handle_set_operation_mode(struct wilc_vif *vif, ret = wilc_send_config_pkt(vif, SET_CFG, &wid, 1, wilc_get_vif_idx(vif)); - if ((hif_op_mode->mode) == IDLE_MODE) + if (hif_op_mode->mode == IDLE_MODE) complete(&hif_driver_comp); if (ret) @@ -760,8 +760,8 @@ static s32 handle_scan(struct wilc_vif *vif, struct scan_attr *scan_info) hif_drv->usr_scan_req.scan_result = scan_info->result; hif_drv->usr_scan_req.arg = scan_info->arg; - if ((hif_drv->hif_state >= HOST_IF_SCANNING) && - (hif_drv->hif_state < HOST_IF_CONNECTED)) { + if (hif_drv->hif_state >= HOST_IF_SCANNING && + hif_drv->hif_state < HOST_IF_CONNECTED) { netdev_err(vif->ndev, "Already scan\n"); result = -EBUSY; goto ERRORHANDLER; @@ -1025,7 +1025,7 @@ static s32 Handle_Connect(struct wilc_vif *vif, pu8CurrByte += MAX_SSID_LEN; *(pu8CurrByte++) = INFRASTRUCTURE; - if ((pstrHostIFconnectAttr->ch >= 1) && (pstrHostIFconnectAttr->ch <= 14)) { + if (pstrHostIFconnectAttr->ch >= 1 && pstrHostIFconnectAttr->ch <= 14) { *(pu8CurrByte++) = pstrHostIFconnectAttr->ch; } else { netdev_err(vif->ndev, "Channel out of range\n"); @@ -1258,8 +1258,8 @@ static s32 Handle_RcvdNtwrkInfo(struct wilc_vif *vif, if (hif_drv->usr_scan_req.scan_result) { wilc_parse_network_info(pstrRcvdNetworkInfo->buffer, &pstrNetworkInfo); - if ((!pstrNetworkInfo) || - (!hif_drv->usr_scan_req.scan_result)) { + if (!pstrNetworkInfo || + !hif_drv->usr_scan_req.scan_result) { netdev_err(vif->ndev, "driver is null\n"); result = -EINVAL; goto done; @@ -1340,8 +1340,8 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct wilc_vif *vif, return -ENODEV; } - if ((hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) || - (hif_drv->hif_state == HOST_IF_CONNECTED) || + if (hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP || + hif_drv->hif_state == HOST_IF_CONNECTED || hif_drv->usr_scan_req.scan_result) { if (!pstrRcvdGnrlAsyncInfo->buffer || !hif_drv->usr_conn_req.conn_result) { @@ -1400,8 +1400,8 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct wilc_vif *vif, } } - if ((u8MacStatus == MAC_CONNECTED) && - (strConnectInfo.status != SUCCESSFUL_STATUSCODE)) { + if (u8MacStatus == MAC_CONNECTED && + strConnectInfo.status != SUCCESSFUL_STATUSCODE) { netdev_err(vif->ndev, "Received MAC status is MAC_CONNECTED while the received status code in Asoc Resp is not SUCCESSFUL_STATUSCODE\n"); eth_zero_addr(wilc_connected_ssid); } else if (u8MacStatus == MAC_DISCONNECTED) { @@ -1412,8 +1412,8 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct wilc_vif *vif, if (hif_drv->usr_conn_req.bssid) { memcpy(strConnectInfo.bssid, hif_drv->usr_conn_req.bssid, 6); - if ((u8MacStatus == MAC_CONNECTED) && - (strConnectInfo.status == SUCCESSFUL_STATUSCODE)) { + if (u8MacStatus == MAC_CONNECTED && + strConnectInfo.status == SUCCESSFUL_STATUSCODE) { memcpy(hif_drv->assoc_bssid, hif_drv->usr_conn_req.bssid, ETH_ALEN); } @@ -1434,8 +1434,8 @@ static s32 Handle_RcvdGnrlAsyncInfo(struct wilc_vif *vif, NULL, hif_drv->usr_conn_req.arg); - if ((u8MacStatus == MAC_CONNECTED) && - (strConnectInfo.status == SUCCESSFUL_STATUSCODE)) { + if (u8MacStatus == MAC_CONNECTED && + strConnectInfo.status == SUCCESSFUL_STATUSCODE) { wilc_set_power_mgmt(vif, 0, 0); hif_drv->hif_state = HOST_IF_CONNECTED; @@ -1864,8 +1864,8 @@ void wilc_resolve_disconnect_aberration(struct wilc_vif *vif) { if (!vif->hif_drv) return; - if ((vif->hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP) || - (vif->hif_drv->hif_state == HOST_IF_CONNECTING)) + if (vif->hif_drv->hif_state == HOST_IF_WAITING_CONN_RESP || + vif->hif_drv->hif_state == HOST_IF_CONNECTING) wilc_disconnect(vif, 1); } @@ -2414,7 +2414,7 @@ static void Handle_SetMulticastFilter(struct wilc_vif *vif, wid.id = (u16)WID_SETUP_MULTICAST_FILTER; wid.type = WID_BIN; - wid.size = sizeof(struct set_multicast) + ((strHostIfSetMulti->cnt) * ETH_ALEN); + wid.size = sizeof(struct set_multicast) + (strHostIfSetMulti->cnt * ETH_ALEN); wid.val = kmalloc(wid.size, GFP_KERNEL); if (!wid.val) goto ERRORHANDLER; @@ -3730,8 +3730,8 @@ int wilc_add_station(struct wilc_vif *vif, struct add_sta_param *sta_param) memcpy(add_sta_info, sta_param, sizeof(struct add_sta_param)); if (add_sta_info->rates_len > 0) { add_sta_info->rates = kmemdup(sta_param->rates, - add_sta_info->rates_len, - GFP_KERNEL); + add_sta_info->rates_len, + GFP_KERNEL); if (!add_sta_info->rates) return -ENOMEM; } diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 119f3459b5bb..d9725efe0537 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #include "wilc_wfi_cfgoperations.h" #include "wilc_wlan_if.h" #include "wilc_wlan.h" @@ -694,7 +695,7 @@ static int wlan_initialize_threads(struct net_device *dev) wilc = vif->wilc; wilc->txq_thread = kthread_run(linux_wlan_txq_task, (void *)dev, - "K_TXQ_TASK"); + "K_TXQ_TASK"); if (IS_ERR(wilc->txq_thread)) { netdev_err(dev, "couldn't create TXQ thread\n"); wilc->close = 0; @@ -910,13 +911,13 @@ static void wilc_set_multicast_list(struct net_device *dev) if (dev->flags & IFF_PROMISC) return; - if ((dev->flags & IFF_ALLMULTI) || - (dev->mc.count) > WILC_MULTICAST_TABLE_SIZE) { + if (dev->flags & IFF_ALLMULTI || + dev->mc.count > WILC_MULTICAST_TABLE_SIZE) { wilc_setup_multicast_filter(vif, false, 0); return; } - if ((dev->mc.count) == 0) { + if (dev->mc.count == 0) { wilc_setup_multicast_filter(vif, true, 0); return; } @@ -1029,7 +1030,7 @@ static int wilc_mac_close(struct net_device *ndev) if (!hif_drv) return 0; - if ((wl->open_ifcs) > 0) + if (wl->open_ifcs > 0) wl->open_ifcs--; else return 0; diff --git a/drivers/staging/wilc1000/wilc_debugfs.c b/drivers/staging/wilc1000/wilc_debugfs.c index ce54864569c7..0deb61a21b27 100644 --- a/drivers/staging/wilc1000/wilc_debugfs.c +++ b/drivers/staging/wilc1000/wilc_debugfs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * NewportMedia WiFi chipset driver test tools - wilc-debug * Copyright (c) 2012 NewportMedia Inc. diff --git a/drivers/staging/wilc1000/wilc_sdio.c b/drivers/staging/wilc1000/wilc_sdio.c index 0189e3edbbbe..bb65b374c1ce 100644 --- a/drivers/staging/wilc1000/wilc_sdio.c +++ b/drivers/staging/wilc1000/wilc_sdio.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) Atmel Corporation. All rights reserved. * @@ -374,7 +375,7 @@ static int sdio_write_reg(struct wilc *wilc, u32 addr, u32 data) data = cpu_to_le32(data); - if ((addr >= 0xf0) && (addr <= 0xff)) { + if (addr >= 0xf0 && addr <= 0xff) { struct sdio_cmd52 cmd; cmd.read_write = 1; @@ -514,7 +515,7 @@ static int sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data) struct sdio_func *func = dev_to_sdio_func(wilc->dev); int ret; - if ((addr >= 0xf0) && (addr <= 0xff)) { + if (addr >= 0xf0 && addr <= 0xff) { struct sdio_cmd52 cmd; cmd.read_write = 0; diff --git a/drivers/staging/wilc1000/wilc_spi.c b/drivers/staging/wilc1000/wilc_spi.c index 5ef84410e0f2..8f71a6022721 100644 --- a/drivers/staging/wilc1000/wilc_spi.c +++ b/drivers/staging/wilc1000/wilc_spi.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) Atmel Corporation. All rights reserved. * @@ -389,11 +390,11 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, #define NUM_DATA_BYTES (4) #define NUM_CRC_BYTES (2) #define NUM_DUMMY_BYTES (3) - if ((cmd == CMD_RESET) || - (cmd == CMD_TERMINATE) || - (cmd == CMD_REPEAT)) { + if (cmd == CMD_RESET || + cmd == CMD_TERMINATE || + cmd == CMD_REPEAT) { len2 = len + (NUM_SKIP_BYTES + NUM_RSP_BYTES + NUM_DUMMY_BYTES); - } else if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)) { + } else if (cmd == CMD_INTERNAL_READ || cmd == CMD_SINGLE_READ) { if (!g_spi.crc_off) { len2 = len + (NUM_RSP_BYTES + NUM_DATA_HDR_BYTES + NUM_DATA_BYTES + NUM_CRC_BYTES + NUM_DUMMY_BYTES); @@ -424,9 +425,9 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, /** * Command/Control response **/ - if ((cmd == CMD_RESET) || - (cmd == CMD_TERMINATE) || - (cmd == CMD_REPEAT)) { + if (cmd == CMD_RESET || + cmd == CMD_TERMINATE || + cmd == CMD_REPEAT) { rix++; /* skip 1 byte */ } @@ -452,8 +453,8 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, return N_FAIL; } - if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ) || - (cmd == CMD_DMA_READ) || (cmd == CMD_DMA_EXT_READ)) { + if (cmd == CMD_INTERNAL_READ || cmd == CMD_SINGLE_READ || + cmd == CMD_DMA_READ || cmd == CMD_DMA_EXT_READ) { int retry; /* u16 crc1, crc2; */ u8 crc[2]; @@ -479,7 +480,7 @@ static int spi_cmd_complete(struct wilc *wilc, u8 cmd, u32 adr, u8 *b, u32 sz, return N_RESET; } - if ((cmd == CMD_INTERNAL_READ) || (cmd == CMD_SINGLE_READ)) { + if (cmd == CMD_INTERNAL_READ || cmd == CMD_SINGLE_READ) { /** * Read bytes **/ diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index 028da1dc1b81..621810d70450 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -379,7 +379,7 @@ static void CfgScanResult(enum scan_event scan_event, struct cfg80211_bss *bss = NULL; priv = user_void; - if (priv->bCfgScanning) { + if (priv->cfg_scanning) { if (scan_event == SCAN_EVENT_NETWORK_FOUND) { wiphy = priv->dev->ieee80211_ptr->wiphy; @@ -399,8 +399,8 @@ static void CfgScanResult(enum scan_event scan_event, return; if (network_info->new_network) { - if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { - priv->u32RcvdChCount++; + if (priv->rcvd_ch_cnt < MAX_NUM_SCANNED_NETWORKS) { + priv->rcvd_ch_cnt++; add_network_to_shadow(network_info, priv, join_params); @@ -422,7 +422,7 @@ static void CfgScanResult(enum scan_event scan_event, } else { u32 i; - for (i = 0; i < priv->u32RcvdChCount; i++) { + for (i = 0; i < priv->rcvd_ch_cnt; i++) { if (memcmp(last_scanned_shadow[i].bssid, network_info->bssid, 6) == 0) { last_scanned_shadow[i].rssi = network_info->rssi; last_scanned_shadow[i].time_scan = jiffies; @@ -436,21 +436,21 @@ static void CfgScanResult(enum scan_event scan_event, mutex_lock(&priv->scan_req_lock); - if (priv->pstrScanReq) { + if (priv->scan_req) { struct cfg80211_scan_info info = { .aborted = false, }; - cfg80211_scan_done(priv->pstrScanReq, &info); - priv->u32RcvdChCount = 0; - priv->bCfgScanning = false; - priv->pstrScanReq = NULL; + cfg80211_scan_done(priv->scan_req, &info); + priv->rcvd_ch_cnt = 0; + priv->cfg_scanning = false; + priv->scan_req = NULL; } mutex_unlock(&priv->scan_req_lock); } else if (scan_event == SCAN_EVENT_ABORTED) { mutex_lock(&priv->scan_req_lock); - if (priv->pstrScanReq) { + if (priv->scan_req) { struct cfg80211_scan_info info = { .aborted = false, }; @@ -458,9 +458,9 @@ static void CfgScanResult(enum scan_event scan_event, update_scan_time(); refresh_scan(priv, false); - cfg80211_scan_done(priv->pstrScanReq, &info); - priv->bCfgScanning = false; - priv->pstrScanReq = NULL; + cfg80211_scan_done(priv->scan_req, &info); + priv->cfg_scanning = false; + priv->scan_req = NULL; } mutex_unlock(&priv->scan_req_lock); } @@ -469,92 +469,92 @@ static void CfgScanResult(enum scan_event scan_event, int wilc_connecting; -static void CfgConnectResult(enum conn_event enuConnDisconnEvent, - struct connect_info *pstrConnectInfo, - u8 u8MacStatus, - struct disconnect_info *pstrDisconnectNotifInfo, - void *pUserVoid) +static void cfg_connect_result(enum conn_event conn_disconn_evt, + struct connect_info *conn_info, + u8 mac_status, + struct disconnect_info *disconn_info, + void *priv_data) { struct wilc_priv *priv; struct net_device *dev; - struct host_if_drv *pstrWFIDrv; - u8 NullBssid[ETH_ALEN] = {0}; + struct host_if_drv *wfi_drv; + u8 null_bssid[ETH_ALEN] = {0}; struct wilc *wl; struct wilc_vif *vif; wilc_connecting = 0; - priv = pUserVoid; + priv = priv_data; dev = priv->dev; vif = netdev_priv(dev); wl = vif->wilc; - pstrWFIDrv = (struct host_if_drv *)priv->hif_drv; + wfi_drv = (struct host_if_drv *)priv->hif_drv; - if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) { - u16 u16ConnectStatus; + if (conn_disconn_evt == CONN_DISCONN_EVENT_CONN_RESP) { + u16 connect_status; - u16ConnectStatus = pstrConnectInfo->status; + connect_status = conn_info->status; - if ((u8MacStatus == MAC_DISCONNECTED) && - (pstrConnectInfo->status == SUCCESSFUL_STATUSCODE)) { - u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE; - wilc_wlan_set_bssid(priv->dev, NullBssid, + if (mac_status == MAC_DISCONNECTED && + conn_info->status == SUCCESSFUL_STATUSCODE) { + connect_status = WLAN_STATUS_UNSPECIFIED_FAILURE; + wilc_wlan_set_bssid(priv->dev, null_bssid, STATION_MODE); eth_zero_addr(wilc_connected_ssid); - if (!pstrWFIDrv->p2p_connect) + if (!wfi_drv->p2p_connect) wlan_channel = INVALID_CHANNEL; netdev_err(dev, "Unspecified failure\n"); } - if (u16ConnectStatus == WLAN_STATUS_SUCCESS) { - bool bNeedScanRefresh = false; + if (connect_status == WLAN_STATUS_SUCCESS) { + bool scan_refresh = false; u32 i; - memcpy(priv->au8AssociatedBss, pstrConnectInfo->bssid, ETH_ALEN); + memcpy(priv->associated_bss, conn_info->bssid, ETH_ALEN); for (i = 0; i < last_scanned_cnt; i++) { if (memcmp(last_scanned_shadow[i].bssid, - pstrConnectInfo->bssid, + conn_info->bssid, ETH_ALEN) == 0) { unsigned long now = jiffies; if (time_after(now, last_scanned_shadow[i].time_scan_cached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) - bNeedScanRefresh = true; + scan_refresh = true; break; } } - if (bNeedScanRefresh) + if (scan_refresh) refresh_scan(priv, true); } - cfg80211_connect_result(dev, pstrConnectInfo->bssid, - pstrConnectInfo->req_ies, pstrConnectInfo->req_ies_len, - pstrConnectInfo->resp_ies, pstrConnectInfo->resp_ies_len, - u16ConnectStatus, GFP_KERNEL); - } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) { + cfg80211_connect_result(dev, conn_info->bssid, + conn_info->req_ies, conn_info->req_ies_len, + conn_info->resp_ies, conn_info->resp_ies_len, + connect_status, GFP_KERNEL); + } else if (conn_disconn_evt == CONN_DISCONN_EVENT_DISCONN_NOTIF) { wilc_optaining_ip = false; p2p_local_random = 0x01; p2p_recv_random = 0x00; wilc_ie = false; - eth_zero_addr(priv->au8AssociatedBss); - wilc_wlan_set_bssid(priv->dev, NullBssid, STATION_MODE); + eth_zero_addr(priv->associated_bss); + wilc_wlan_set_bssid(priv->dev, null_bssid, STATION_MODE); eth_zero_addr(wilc_connected_ssid); - if (!pstrWFIDrv->p2p_connect) + if (!wfi_drv->p2p_connect) wlan_channel = INVALID_CHANNEL; - if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev)) - pstrDisconnectNotifInfo->reason = 3; - else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev)) - pstrDisconnectNotifInfo->reason = 1; + if (wfi_drv->IFC_UP && dev == wl->vif[1]->ndev) + disconn_info->reason = 3; + else if (!wfi_drv->IFC_UP && dev == wl->vif[1]->ndev) + disconn_info->reason = 1; - cfg80211_disconnected(dev, pstrDisconnectNotifInfo->reason, pstrDisconnectNotifInfo->ie, - pstrDisconnectNotifInfo->ie_len, false, + cfg80211_disconnected(dev, disconn_info->reason, disconn_info->ie, + disconn_info->ie_len, false, GFP_KERNEL); } } @@ -585,7 +585,7 @@ static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) { struct wilc_priv *priv; u32 i; - s32 s32Error = 0; + s32 ret = 0; u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS]; struct hidden_network strHiddenNetwork; struct wilc_vif *vif; @@ -593,13 +593,13 @@ static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) priv = wiphy_priv(wiphy); vif = netdev_priv(priv->dev); - priv->pstrScanReq = request; + priv->scan_req = request; - priv->u32RcvdChCount = 0; + priv->rcvd_ch_cnt = 0; reset_shadow_found(); - priv->bCfgScanning = true; + priv->cfg_scanning = true; if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) { for (i = 0; i < request->n_channels; i++) au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq); @@ -622,56 +622,56 @@ static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) strHiddenNetwork.n_ssids -= 1; } } - s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN, - au8ScanChanList, - request->n_channels, - (const u8 *)request->ie, - request->ie_len, CfgScanResult, - (void *)priv, &strHiddenNetwork); + ret = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN, + au8ScanChanList, + request->n_channels, + (const u8 *)request->ie, + request->ie_len, CfgScanResult, + (void *)priv, &strHiddenNetwork); } else { - s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN, - au8ScanChanList, - request->n_channels, - (const u8 *)request->ie, - request->ie_len, CfgScanResult, - (void *)priv, NULL); + ret = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN, + au8ScanChanList, + request->n_channels, + (const u8 *)request->ie, + request->ie_len, CfgScanResult, + (void *)priv, NULL); } } else { netdev_err(priv->dev, "Requested scanned channels over\n"); } - if (s32Error != 0) - s32Error = -EBUSY; + if (ret != 0) + ret = -EBUSY; - return s32Error; + return ret; } static int connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme) { - s32 s32Error = 0; + s32 ret = 0; u32 i; u32 sel_bssi_idx = UINT_MAX; u8 u8security = NO_ENCRYPT; - enum AUTHTYPE tenuAuth_type = ANY; + enum AUTHTYPE auth_type = ANY; struct wilc_priv *priv; - struct host_if_drv *pstrWFIDrv; + struct host_if_drv *wfi_drv; struct network_info *pstrNetworkInfo = NULL; struct wilc_vif *vif; wilc_connecting = 1; priv = wiphy_priv(wiphy); vif = netdev_priv(priv->dev); - pstrWFIDrv = (struct host_if_drv *)priv->hif_drv; + wfi_drv = (struct host_if_drv *)priv->hif_drv; if (!(strncmp(sme->ssid, "DIRECT-", 7))) - pstrWFIDrv->p2p_connect = 1; + wfi_drv->p2p_connect = 1; else - pstrWFIDrv->p2p_connect = 0; + wfi_drv->p2p_connect = 0; for (i = 0; i < last_scanned_cnt; i++) { - if ((sme->ssid_len == last_scanned_shadow[i].ssid_len) && + if (sme->ssid_len == last_scanned_shadow[i].ssid_len && memcmp(last_scanned_shadow[i].ssid, sme->ssid, sme->ssid_len) == 0) { @@ -694,9 +694,9 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, if (sel_bssi_idx < last_scanned_cnt) { pstrNetworkInfo = &last_scanned_shadow[sel_bssi_idx]; } else { - s32Error = -ENOENT; + ret = -ENOENT; wilc_connecting = 0; - return s32Error; + return ret; } memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key)); @@ -744,10 +744,10 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, else u8security = ENCRYPT_ENABLED | WPA | AES; } else { - s32Error = -ENOTSUPP; + ret = -ENOTSUPP; netdev_err(dev, "Not supported cipher\n"); wilc_connecting = 0; - return s32Error; + return ret; } } @@ -763,11 +763,11 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, switch (sme->auth_type) { case NL80211_AUTHTYPE_OPEN_SYSTEM: - tenuAuth_type = OPEN_SYSTEM; + auth_type = OPEN_SYSTEM; break; case NL80211_AUTHTYPE_SHARED_KEY: - tenuAuth_type = SHARED_KEY; + auth_type = SHARED_KEY; break; default: @@ -777,7 +777,7 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, if (sme->crypto.n_akm_suites) { switch (sme->crypto.akm_suites[0]) { case WLAN_AKM_SUITE_8021X: - tenuAuth_type = IEEE8021; + auth_type = IEEE8021; break; default: @@ -787,35 +787,35 @@ static int connect(struct wiphy *wiphy, struct net_device *dev, curr_channel = pstrNetworkInfo->ch; - if (!pstrWFIDrv->p2p_connect) + if (!wfi_drv->p2p_connect) wlan_channel = pstrNetworkInfo->ch; wilc_wlan_set_bssid(dev, pstrNetworkInfo->bssid, STATION_MODE); - s32Error = wilc_set_join_req(vif, pstrNetworkInfo->bssid, sme->ssid, - sme->ssid_len, sme->ie, sme->ie_len, - CfgConnectResult, (void *)priv, - u8security, tenuAuth_type, - pstrNetworkInfo->ch, - pstrNetworkInfo->join_params); - if (s32Error != 0) { + ret = wilc_set_join_req(vif, pstrNetworkInfo->bssid, sme->ssid, + sme->ssid_len, sme->ie, sme->ie_len, + cfg_connect_result, (void *)priv, + u8security, auth_type, + pstrNetworkInfo->ch, + pstrNetworkInfo->join_params); + if (ret != 0) { netdev_err(dev, "wilc_set_join_req(): Error\n"); - s32Error = -ENOENT; + ret = -ENOENT; wilc_connecting = 0; - return s32Error; + return ret; } - return s32Error; + return ret; } static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code) { - s32 s32Error = 0; + s32 ret = 0; struct wilc_priv *priv; - struct host_if_drv *pstrWFIDrv; + struct host_if_drv *wfi_drv; struct wilc_vif *vif; struct wilc *wilc; - u8 NullBssid[ETH_ALEN] = {0}; + u8 null_bssid[ETH_ALEN] = {0}; wilc_connecting = 0; priv = wiphy_priv(wiphy); @@ -831,23 +831,23 @@ static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_co return 0; } - pstrWFIDrv = (struct host_if_drv *)priv->hif_drv; - if (!pstrWFIDrv->p2p_connect) + wfi_drv = (struct host_if_drv *)priv->hif_drv; + if (!wfi_drv->p2p_connect) wlan_channel = INVALID_CHANNEL; - wilc_wlan_set_bssid(priv->dev, NullBssid, STATION_MODE); + wilc_wlan_set_bssid(priv->dev, null_bssid, STATION_MODE); p2p_local_random = 0x01; p2p_recv_random = 0x00; wilc_ie = false; - pstrWFIDrv->p2p_timeout = 0; + wfi_drv->p2p_timeout = 0; - s32Error = wilc_disconnect(vif, reason_code); - if (s32Error != 0) { + ret = wilc_disconnect(vif, reason_code); + if (ret != 0) { netdev_err(priv->dev, "Error in disconnecting\n"); - s32Error = -EINVAL; + ret = -EINVAL; } - return s32Error; + return ret; } static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, @@ -855,14 +855,14 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, const u8 *mac_addr, struct key_params *params) { - s32 s32Error = 0, KeyLen = params->key_len; + s32 ret = 0, keylen = params->key_len; struct wilc_priv *priv; - const u8 *pu8RxMic = NULL; - const u8 *pu8TxMic = NULL; + const u8 *rx_mic = NULL; + const u8 *tx_mic = NULL; u8 u8mode = NO_ENCRYPT; u8 u8gmode = NO_ENCRYPT; u8 u8pmode = NO_ENCRYPT; - enum AUTHTYPE tenuAuth_type = ANY; + enum AUTHTYPE auth_type = ANY; struct wilc *wl; struct wilc_vif *vif; @@ -877,7 +877,7 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, priv->WILC_WFI_wep_key_len[key_index] = params->key_len; memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len); - tenuAuth_type = OPEN_SYSTEM; + auth_type = OPEN_SYSTEM; if (params->cipher == WLAN_CIPHER_SUITE_WEP40) u8mode = ENCRYPT_ENABLED | WEP; @@ -886,7 +886,7 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, wilc_add_wep_key_bss_ap(vif, params->key, params->key_len, key_index, - u8mode, tenuAuth_type); + u8mode, auth_type); break; } if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) { @@ -922,9 +922,9 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, priv->wilc_groupkey = u8gmode; if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) { - pu8TxMic = params->key + 24; - pu8RxMic = params->key + 16; - KeyLen = params->key_len - 16; + tx_mic = params->key + 24; + rx_mic = params->key + 16; + keylen = params->key_len - 16; } kfree(priv->wilc_gtk[key_index]->key); @@ -932,7 +932,7 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len); kfree(priv->wilc_gtk[key_index]->seq); - if ((params->seq_len) > 0) { + if (params->seq_len > 0) { priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL); memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len); } @@ -941,10 +941,10 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, priv->wilc_gtk[key_index]->key_len = params->key_len; priv->wilc_gtk[key_index]->seq_len = params->seq_len; - wilc_add_rx_gtk(vif, params->key, KeyLen, + wilc_add_rx_gtk(vif, params->key, keylen, key_index, params->seq_len, - params->seq, pu8RxMic, - pu8TxMic, AP_MODE, u8gmode); + params->seq, rx_mic, + tx_mic, AP_MODE, u8gmode); } else { if (params->cipher == WLAN_CIPHER_SUITE_TKIP) @@ -953,9 +953,9 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, u8pmode = priv->wilc_groupkey | AES; if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) { - pu8TxMic = params->key + 24; - pu8RxMic = params->key + 16; - KeyLen = params->key_len - 16; + tx_mic = params->key + 24; + rx_mic = params->key + 16; + keylen = params->key_len - 16; } kfree(priv->wilc_ptk[key_index]->key); @@ -964,20 +964,20 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, kfree(priv->wilc_ptk[key_index]->seq); - if ((params->seq_len) > 0) + if (params->seq_len > 0) priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL); memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len); - if ((params->seq_len) > 0) + if (params->seq_len > 0) memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len); priv->wilc_ptk[key_index]->cipher = params->cipher; priv->wilc_ptk[key_index]->key_len = params->key_len; priv->wilc_ptk[key_index]->seq_len = params->seq_len; - wilc_add_ptk(vif, params->key, KeyLen, - mac_addr, pu8RxMic, pu8TxMic, + wilc_add_ptk(vif, params->key, keylen, + mac_addr, rx_mic, tx_mic, AP_MODE, u8pmode, key_index); } break; @@ -987,9 +987,9 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, u8mode = 0; if (!pairwise) { if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) { - pu8RxMic = params->key + 24; - pu8TxMic = params->key + 16; - KeyLen = params->key_len - 16; + rx_mic = params->key + 24; + tx_mic = params->key + 16; + keylen = params->key_len - 16; } if (!g_gtk_keys_saved && netdev == wl->vif[0]->ndev) { @@ -1013,16 +1013,16 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, g_gtk_keys_saved = true; } - wilc_add_rx_gtk(vif, params->key, KeyLen, + wilc_add_rx_gtk(vif, params->key, keylen, key_index, params->seq_len, - params->seq, pu8RxMic, - pu8TxMic, STATION_MODE, + params->seq, rx_mic, + tx_mic, STATION_MODE, u8mode); } else { if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) { - pu8RxMic = params->key + 24; - pu8TxMic = params->key + 16; - KeyLen = params->key_len - 16; + rx_mic = params->key + 24; + tx_mic = params->key + 16; + keylen = params->key_len - 16; } if (!g_ptk_keys_saved && netdev == wl->vif[0]->ndev) { @@ -1046,8 +1046,8 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, g_ptk_keys_saved = true; } - wilc_add_ptk(vif, params->key, KeyLen, - mac_addr, pu8RxMic, pu8TxMic, + wilc_add_ptk(vif, params->key, keylen, + mac_addr, rx_mic, tx_mic, STATION_MODE, u8mode, key_index); } } @@ -1055,10 +1055,10 @@ static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, default: netdev_err(netdev, "Not supported cipher\n"); - s32Error = -ENOTSUPP; + ret = -ENOTSUPP; } - return s32Error; + return ret; } static int del_key(struct wiphy *wiphy, struct net_device *netdev, @@ -1082,7 +1082,7 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev, kfree(g_key_wep_params.key); g_key_wep_params.key = NULL; - if ((priv->wilc_gtk[key_index]) != NULL) { + if (priv->wilc_gtk[key_index] != NULL) { kfree(priv->wilc_gtk[key_index]->key); priv->wilc_gtk[key_index]->key = NULL; kfree(priv->wilc_gtk[key_index]->seq); @@ -1092,7 +1092,7 @@ static int del_key(struct wiphy *wiphy, struct net_device *netdev, priv->wilc_gtk[key_index] = NULL; } - if ((priv->wilc_ptk[key_index]) != NULL) { + if (priv->wilc_ptk[key_index] != NULL) { kfree(priv->wilc_ptk[key_index]->key); priv->wilc_ptk[key_index]->key = NULL; kfree(priv->wilc_ptk[key_index]->seq); @@ -1182,7 +1182,7 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev, if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) { for (i = 0; i < NUM_STA_ASSOCIATED; i++) { - if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) { + if (!(memcmp(mac, priv->assoc_stainfo.sta_associated_bss[i], ETH_ALEN))) { associatedsta = i; break; } @@ -1200,9 +1200,9 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev, } if (vif->iftype == STATION_MODE) { - struct rf_info strStatistics; + struct rf_info stats; - wilc_get_statistics(vif, &strStatistics); + wilc_get_statistics(vif, &stats); sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) | BIT(NL80211_STA_INFO_RX_PACKETS) | @@ -1210,16 +1210,16 @@ static int get_station(struct wiphy *wiphy, struct net_device *dev, BIT(NL80211_STA_INFO_TX_FAILED) | BIT(NL80211_STA_INFO_TX_BITRATE); - sinfo->signal = strStatistics.rssi; - sinfo->rx_packets = strStatistics.rx_cnt; - sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt; - sinfo->tx_failed = strStatistics.tx_fail_cnt; - sinfo->txrate.legacy = strStatistics.link_speed * 10; + sinfo->signal = stats.rssi; + sinfo->rx_packets = stats.rx_cnt; + sinfo->tx_packets = stats.tx_cnt + stats.tx_fail_cnt; + sinfo->tx_failed = stats.tx_fail_cnt; + sinfo->txrate.legacy = stats.link_speed * 10; - if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) && - (strStatistics.link_speed != DEFAULT_LINK_SPEED)) + if (stats.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH && + stats.link_speed != DEFAULT_LINK_SPEED) wilc_enable_tcp_ack_filter(true); - else if (strStatistics.link_speed != DEFAULT_LINK_SPEED) + else if (stats.link_speed != DEFAULT_LINK_SPEED) wilc_enable_tcp_ack_filter(false); } return 0; @@ -1233,46 +1233,46 @@ static int change_bss(struct wiphy *wiphy, struct net_device *dev, static int set_wiphy_params(struct wiphy *wiphy, u32 changed) { - s32 s32Error = 0; - struct cfg_param_attr pstrCfgParamVal; + s32 ret = 0; + struct cfg_param_attr cfg_param_val; struct wilc_priv *priv; struct wilc_vif *vif; priv = wiphy_priv(wiphy); vif = netdev_priv(priv->dev); - pstrCfgParamVal.flag = 0; + cfg_param_val.flag = 0; if (changed & WIPHY_PARAM_RETRY_SHORT) { - pstrCfgParamVal.flag |= RETRY_SHORT; - pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short; + cfg_param_val.flag |= RETRY_SHORT; + cfg_param_val.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short; } if (changed & WIPHY_PARAM_RETRY_LONG) { - pstrCfgParamVal.flag |= RETRY_LONG; - pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long; + cfg_param_val.flag |= RETRY_LONG; + cfg_param_val.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long; } if (changed & WIPHY_PARAM_FRAG_THRESHOLD) { - pstrCfgParamVal.flag |= FRAG_THRESHOLD; - pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold; + cfg_param_val.flag |= FRAG_THRESHOLD; + cfg_param_val.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold; } if (changed & WIPHY_PARAM_RTS_THRESHOLD) { - pstrCfgParamVal.flag |= RTS_THRESHOLD; - pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold; + cfg_param_val.flag |= RTS_THRESHOLD; + cfg_param_val.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold; } - s32Error = wilc_hif_set_cfg(vif, &pstrCfgParamVal); - if (s32Error) + ret = wilc_hif_set_cfg(vif, &cfg_param_val); + if (ret) netdev_err(priv->dev, "Error in setting WIPHY PARAMS\n"); - return s32Error; + return ret; } static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev, struct cfg80211_pmksa *pmksa) { u32 i; - s32 s32Error = 0; + s32 ret = 0; u8 flag = 0; struct wilc_vif *vif; struct wilc_priv *priv = wiphy_priv(wiphy); @@ -1295,20 +1295,20 @@ static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev, priv->pmkid_list.numpmkid++; } else { netdev_err(netdev, "Invalid PMKID index\n"); - s32Error = -EINVAL; + ret = -EINVAL; } - if (!s32Error) - s32Error = wilc_set_pmkid_info(vif, &priv->pmkid_list); + if (!ret) + ret = wilc_set_pmkid_info(vif, &priv->pmkid_list); - return s32Error; + return ret; } static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev, struct cfg80211_pmksa *pmksa) { u32 i; - s32 s32Error = 0; + s32 ret = 0; struct wilc_priv *priv = wiphy_priv(wiphy); @@ -1331,10 +1331,10 @@ static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev, } priv->pmkid_list.numpmkid--; } else { - s32Error = -EINVAL; + ret = -EINVAL; } - return s32Error; + return ret; } static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) @@ -1346,7 +1346,7 @@ static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) return 0; } -static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len) +static void wilc_wfi_cfg_parse_rx_action(u8 *buf, u32 len) { u32 index = 0; u32 i = 0, j = 0; @@ -1382,7 +1382,7 @@ static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len) } } -static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype) +static void wilc_wfi_cfg_parse_tx_action(u8 *buf, u32 len, bool oper_ch, u8 iftype) { u32 index = 0; u32 i = 0, j = 0; @@ -1403,7 +1403,7 @@ static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftyp op_channel_attr_index = index; index += buf[index + 1] + 3; } - if (wlan_channel != INVALID_CHANNEL && bOperChan) { + if (wlan_channel != INVALID_CHANNEL && oper_ch) { if (channel_list_attr_index) { for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) { if (buf[i] == 0x51) { @@ -1425,12 +1425,12 @@ void WILC_WFI_p2p_rx(struct net_device *dev, u8 *buff, u32 size) { struct wilc_priv *priv; u32 header, pkt_offset; - struct host_if_drv *pstrWFIDrv; + struct host_if_drv *wfi_drv; u32 i = 0; s32 s32Freq; priv = wiphy_priv(dev->ieee80211_ptr->wiphy); - pstrWFIDrv = (struct host_if_drv *)priv->hif_drv; + wfi_drv = (struct host_if_drv *)priv->hif_drv; memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET); @@ -1438,20 +1438,20 @@ void WILC_WFI_p2p_rx(struct net_device *dev, u8 *buff, u32 size) if (pkt_offset & IS_MANAGMEMENT_CALLBACK) { if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) { - cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL); + cfg80211_mgmt_tx_status(priv->wdev, priv->tx_cookie, buff, size, true, GFP_KERNEL); return; } else { if (pkt_offset & IS_MGMT_STATUS_SUCCES) - cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL); + cfg80211_mgmt_tx_status(priv->wdev, priv->tx_cookie, buff, size, true, GFP_KERNEL); else - cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL); + cfg80211_mgmt_tx_status(priv->wdev, priv->tx_cookie, buff, size, false, GFP_KERNEL); return; } } else { s32Freq = ieee80211_channel_to_frequency(curr_channel, NL80211_BAND_2GHZ); if (ieee80211_is_action(buff[FRAME_TYPE_ID])) { - if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) { + if (priv->cfg_scanning && time_after_eq(jiffies, (unsigned long)wfi_drv->p2p_timeout)) { netdev_dbg(dev, "Receiving action wrong ch\n"); return; } @@ -1481,7 +1481,7 @@ void WILC_WFI_p2p_rx(struct net_device *dev, u8 *buff, u32 size) buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) { for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) { if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) { - WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6)); + wilc_wfi_cfg_parse_rx_action(&buff[i + 6], size - (i + 6)); break; } } @@ -1508,7 +1508,7 @@ void WILC_WFI_p2p_rx(struct net_device *dev, u8 *buff, u32 size) } } -static void WILC_WFI_mgmt_tx_complete(void *priv, int status) +static void wilc_wfi_mgmt_tx_complete(void *priv, int status) { struct p2p_mgmt_data *pv_data = priv; @@ -1516,33 +1516,33 @@ static void WILC_WFI_mgmt_tx_complete(void *priv, int status) kfree(pv_data); } -static void WILC_WFI_RemainOnChannelReady(void *pUserVoid) +static void wilc_wfi_remain_on_channel_ready(void *priv_data) { struct wilc_priv *priv; - priv = pUserVoid; + priv = priv_data; - priv->bInP2PlistenState = true; + priv->p2p_listen_state = true; cfg80211_ready_on_channel(priv->wdev, - priv->strRemainOnChanParams.u64ListenCookie, - priv->strRemainOnChanParams.pstrListenChan, - priv->strRemainOnChanParams.u32ListenDuration, + priv->remain_on_ch_params.listen_cookie, + priv->remain_on_ch_params.listen_ch, + priv->remain_on_ch_params.listen_duration, GFP_KERNEL); } -static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID) +static void wilc_wfi_remain_on_channel_expired(void *data, u32 session_id) { struct wilc_priv *priv; - priv = pUserVoid; + priv = data; - if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) { - priv->bInP2PlistenState = false; + if (session_id == priv->remain_on_ch_params.listen_session_id) { + priv->p2p_listen_state = false; cfg80211_remain_on_channel_expired(priv->wdev, - priv->strRemainOnChanParams.u64ListenCookie, - priv->strRemainOnChanParams.pstrListenChan, + priv->remain_on_ch_params.listen_cookie, + priv->remain_on_ch_params.listen_ch, GFP_KERNEL); } } @@ -1552,7 +1552,7 @@ static int remain_on_channel(struct wiphy *wiphy, struct ieee80211_channel *chan, unsigned int duration, u64 *cookie) { - s32 s32Error = 0; + s32 ret = 0; struct wilc_priv *priv; struct wilc_vif *vif; @@ -1561,21 +1561,21 @@ static int remain_on_channel(struct wiphy *wiphy, if (wdev->iftype == NL80211_IFTYPE_AP) { netdev_dbg(vif->ndev, "Required while in AP mode\n"); - return s32Error; + return ret; } curr_channel = chan->hw_value; - priv->strRemainOnChanParams.pstrListenChan = chan; - priv->strRemainOnChanParams.u64ListenCookie = *cookie; - priv->strRemainOnChanParams.u32ListenDuration = duration; - priv->strRemainOnChanParams.u32ListenSessionID++; + priv->remain_on_ch_params.listen_ch = chan; + priv->remain_on_ch_params.listen_cookie = *cookie; + priv->remain_on_ch_params.listen_duration = duration; + priv->remain_on_ch_params.listen_session_id++; return wilc_remain_on_channel(vif, - priv->strRemainOnChanParams.u32ListenSessionID, + priv->remain_on_ch_params.listen_session_id, duration, chan->hw_value, - WILC_WFI_RemainOnChannelExpired, - WILC_WFI_RemainOnChannelReady, (void *)priv); + wilc_wfi_remain_on_channel_expired, + wilc_wfi_remain_on_channel_ready, (void *)priv); } static int cancel_remain_on_channel(struct wiphy *wiphy, @@ -1589,7 +1589,7 @@ static int cancel_remain_on_channel(struct wiphy *wiphy, vif = netdev_priv(priv->dev); return wilc_listen_state_expired(vif, - priv->strRemainOnChanParams.u32ListenSessionID); + priv->remain_on_ch_params.listen_session_id); } static int mgmt_tx(struct wiphy *wiphy, @@ -1604,17 +1604,17 @@ static int mgmt_tx(struct wiphy *wiphy, const struct ieee80211_mgmt *mgmt; struct p2p_mgmt_data *mgmt_tx; struct wilc_priv *priv; - struct host_if_drv *pstrWFIDrv; + struct host_if_drv *wfi_drv; u32 i; struct wilc_vif *vif; u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random); vif = netdev_priv(wdev->netdev); priv = wiphy_priv(wiphy); - pstrWFIDrv = (struct host_if_drv *)priv->hif_drv; + wfi_drv = (struct host_if_drv *)priv->hif_drv; *cookie = (unsigned long)buf; - priv->u64tx_cookie = *cookie; + priv->tx_cookie = *cookie; mgmt = (const struct ieee80211_mgmt *)buf; if (ieee80211_is_mgmt(mgmt->frame_control)) { @@ -1665,9 +1665,9 @@ static int mgmt_tx(struct wiphy *wiphy, for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) { if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) { if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP) - WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, vif->iftype); + wilc_wfi_cfg_parse_tx_action(&mgmt_tx->buff[i + 6], len - (i + 6), true, vif->iftype); else - WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, vif->iftype); + wilc_wfi_cfg_parse_tx_action(&mgmt_tx->buff[i + 6], len - (i + 6), false, vif->iftype); break; } } @@ -1695,12 +1695,12 @@ static int mgmt_tx(struct wiphy *wiphy, } } - pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait)); + wfi_drv->p2p_timeout = (jiffies + msecs_to_jiffies(wait)); } wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx, mgmt_tx->buff, mgmt_tx->size, - WILC_WFI_mgmt_tx_complete); + wilc_wfi_mgmt_tx_complete); } return 0; } @@ -1710,16 +1710,16 @@ static int mgmt_tx_cancel_wait(struct wiphy *wiphy, u64 cookie) { struct wilc_priv *priv; - struct host_if_drv *pstrWFIDrv; + struct host_if_drv *wfi_drv; priv = wiphy_priv(wiphy); - pstrWFIDrv = (struct host_if_drv *)priv->hif_drv; - pstrWFIDrv->p2p_timeout = jiffies; + wfi_drv = (struct host_if_drv *)priv->hif_drv; + wfi_drv->p2p_timeout = jiffies; - if (!priv->bInP2PlistenState) { + if (!priv->p2p_listen_state) { cfg80211_remain_on_channel_expired(priv->wdev, - priv->strRemainOnChanParams.u64ListenCookie, - priv->strRemainOnChanParams.pstrListenChan, + priv->remain_on_ch_params.listen_cookie, + priv->remain_on_ch_params.listen_ch, GFP_KERNEL); } @@ -1788,7 +1788,7 @@ static int dump_station(struct wiphy *wiphy, struct net_device *dev, wilc_get_rssi(vif, &sinfo->signal); - memcpy(mac, priv->au8AssociatedBss, ETH_ALEN); + memcpy(mac, priv->associated_bss, ETH_ALEN); return 0; } @@ -1837,7 +1837,7 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, vif->iftype = STATION_MODE; wilc_set_operation_mode(vif, STATION_MODE); - memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN); + memset(priv->assoc_stainfo.sta_associated_bss, 0, MAX_NUM_STA * ETH_ALEN); wilc_enable_ps = true; wilc_set_power_mgmt(vif, 1, 0); @@ -1893,9 +1893,9 @@ static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev, static int start_ap(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ap_settings *settings) { - struct cfg80211_beacon_data *beacon = &(settings->beacon); + struct cfg80211_beacon_data *beacon = &settings->beacon; struct wilc_priv *priv; - s32 s32Error = 0; + s32 ret = 0; struct wilc *wl; struct wilc_vif *vif; @@ -1903,9 +1903,9 @@ static int start_ap(struct wiphy *wiphy, struct net_device *dev, vif = netdev_priv(dev); wl = vif->wilc; - s32Error = set_channel(wiphy, &settings->chandef); + ret = set_channel(wiphy, &settings->chandef); - if (s32Error != 0) + if (ret != 0) netdev_err(dev, "Error in setting channel\n"); wilc_wlan_set_bssid(dev, wl->vif[vif->idx]->src_addr, AP_MODE); @@ -1933,10 +1933,10 @@ static int change_beacon(struct wiphy *wiphy, struct net_device *dev, static int stop_ap(struct wiphy *wiphy, struct net_device *dev) { - s32 s32Error = 0; + s32 ret = 0; struct wilc_priv *priv; struct wilc_vif *vif; - u8 NullBssid[ETH_ALEN] = {0}; + u8 null_bssid[ETH_ALEN] = {0}; if (!wiphy) return -EFAULT; @@ -1944,22 +1944,22 @@ static int stop_ap(struct wiphy *wiphy, struct net_device *dev) priv = wiphy_priv(wiphy); vif = netdev_priv(priv->dev); - wilc_wlan_set_bssid(dev, NullBssid, AP_MODE); + wilc_wlan_set_bssid(dev, null_bssid, AP_MODE); - s32Error = wilc_del_beacon(vif); + ret = wilc_del_beacon(vif); - if (s32Error) + if (ret) netdev_err(dev, "Host delete beacon fail\n"); - return s32Error; + return ret; } static int add_station(struct wiphy *wiphy, struct net_device *dev, const u8 *mac, struct station_parameters *params) { - s32 s32Error = 0; + s32 ret = 0; struct wilc_priv *priv; - struct add_sta_param strStaParams = { {0} }; + struct add_sta_param sta_params = { {0} }; struct wilc_vif *vif; if (!wiphy) @@ -1969,35 +1969,35 @@ static int add_station(struct wiphy *wiphy, struct net_device *dev, vif = netdev_priv(dev); if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) { - memcpy(strStaParams.bssid, mac, ETH_ALEN); - memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN); - strStaParams.aid = params->aid; - strStaParams.rates_len = params->supported_rates_len; - strStaParams.rates = params->supported_rates; + memcpy(sta_params.bssid, mac, ETH_ALEN); + memcpy(priv->assoc_stainfo.sta_associated_bss[params->aid], mac, ETH_ALEN); + sta_params.aid = params->aid; + sta_params.rates_len = params->supported_rates_len; + sta_params.rates = params->supported_rates; if (!params->ht_capa) { - strStaParams.ht_supported = false; + sta_params.ht_supported = false; } else { - strStaParams.ht_supported = true; - strStaParams.ht_capa = *params->ht_capa; + sta_params.ht_supported = true; + sta_params.ht_capa = *params->ht_capa; } - strStaParams.flags_mask = params->sta_flags_mask; - strStaParams.flags_set = params->sta_flags_set; + sta_params.flags_mask = params->sta_flags_mask; + sta_params.flags_set = params->sta_flags_set; - s32Error = wilc_add_station(vif, &strStaParams); - if (s32Error) + ret = wilc_add_station(vif, &sta_params); + if (ret) netdev_err(dev, "Host add station fail\n"); } - return s32Error; + return ret; } static int del_station(struct wiphy *wiphy, struct net_device *dev, struct station_del_parameters *params) { const u8 *mac = params->mac; - s32 s32Error = 0; + s32 ret = 0; struct wilc_priv *priv; struct wilc_vif *vif; @@ -2009,23 +2009,23 @@ static int del_station(struct wiphy *wiphy, struct net_device *dev, if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) { if (!mac) - s32Error = wilc_del_allstation(vif, - priv->assoc_stainfo.au8Sta_AssociatedBss); + ret = wilc_del_allstation(vif, + priv->assoc_stainfo.sta_associated_bss); - s32Error = wilc_del_station(vif, mac); + ret = wilc_del_station(vif, mac); - if (s32Error) + if (ret) netdev_err(dev, "Host delete station fail\n"); } - return s32Error; + return ret; } static int change_station(struct wiphy *wiphy, struct net_device *dev, const u8 *mac, struct station_parameters *params) { - s32 s32Error = 0; + s32 ret = 0; struct wilc_priv *priv; - struct add_sta_param strStaParams = { {0} }; + struct add_sta_param sta_params = { {0} }; struct wilc_vif *vif; if (!wiphy) @@ -2035,26 +2035,26 @@ static int change_station(struct wiphy *wiphy, struct net_device *dev, vif = netdev_priv(dev); if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) { - memcpy(strStaParams.bssid, mac, ETH_ALEN); - strStaParams.aid = params->aid; - strStaParams.rates_len = params->supported_rates_len; - strStaParams.rates = params->supported_rates; + memcpy(sta_params.bssid, mac, ETH_ALEN); + sta_params.aid = params->aid; + sta_params.rates_len = params->supported_rates_len; + sta_params.rates = params->supported_rates; if (!params->ht_capa) { - strStaParams.ht_supported = false; + sta_params.ht_supported = false; } else { - strStaParams.ht_supported = true; - strStaParams.ht_capa = *params->ht_capa; + sta_params.ht_supported = true; + sta_params.ht_capa = *params->ht_capa; } - strStaParams.flags_mask = params->sta_flags_mask; - strStaParams.flags_set = params->sta_flags_set; + sta_params.flags_mask = params->sta_flags_mask; + sta_params.flags_set = params->sta_flags_set; - s32Error = wilc_edit_station(vif, &strStaParams); - if (s32Error) + ret = wilc_edit_station(vif, &sta_params); + if (ret) netdev_err(dev, "Host edit station fail\n"); } - return s32Error; + return ret; } static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy, @@ -2198,7 +2198,7 @@ static const struct cfg80211_ops wilc_cfg80211_ops = { }; -static struct wireless_dev *WILC_WFI_CfgAlloc(void) +static struct wireless_dev *wilc_wfi_cfg_alloc(void) { struct wireless_dev *wdev; @@ -2230,9 +2230,9 @@ struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *de { struct wilc_priv *priv; struct wireless_dev *wdev; - s32 s32Error = 0; + s32 ret = 0; - wdev = WILC_WFI_CfgAlloc(); + wdev = wilc_wfi_cfg_alloc(); if (!wdev) { netdev_err(net, "wiphy new allocate failed\n"); return NULL; @@ -2262,8 +2262,8 @@ struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *de set_wiphy_dev(wdev->wiphy, dev); - s32Error = wiphy_register(wdev->wiphy); - if (s32Error) + ret = wiphy_register(wdev->wiphy); + if (ret) netdev_err(net, "Cannot register wiphy device\n"); priv->dev = net; @@ -2272,7 +2272,7 @@ struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *de int wilc_init_host_int(struct net_device *net) { - int s32Error = 0; + int ret = 0; struct wilc_priv *priv; @@ -2283,43 +2283,43 @@ int wilc_init_host_int(struct net_device *net) } op_ifcs++; - priv->gbAutoRateAdjusted = false; + priv->auto_rate_adjusted = false; - priv->bInP2PlistenState = false; + priv->p2p_listen_state = false; mutex_init(&priv->scan_req_lock); - s32Error = wilc_init(net, &priv->hif_drv); - if (s32Error) + ret = wilc_init(net, &priv->hif_drv); + if (ret) netdev_err(net, "Error while initializing hostinterface\n"); - return s32Error; + return ret; } int wilc_deinit_host_int(struct net_device *net) { - int s32Error = 0; + int ret = 0; struct wilc_vif *vif; struct wilc_priv *priv; priv = wdev_priv(net->ieee80211_ptr); vif = netdev_priv(priv->dev); - priv->gbAutoRateAdjusted = false; + priv->auto_rate_adjusted = false; - priv->bInP2PlistenState = false; + priv->p2p_listen_state = false; op_ifcs--; - s32Error = wilc_deinit(vif); + ret = wilc_deinit(vif); clear_shadow_scan(); if (op_ifcs == 0) del_timer_sync(&wilc_during_ip_timer); - if (s32Error) + if (ret) netdev_err(net, "Error while deinitializing host interface\n"); - return s32Error; + return ret; } void wilc_free_wiphy(struct net_device *net) diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h b/drivers/staging/wilc1000/wilc_wfi_netdevice.h index e6f4d84971c3..3337fb26c8e2 100644 --- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h +++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h @@ -86,29 +86,28 @@ struct wilc_wfi_wep_key { }; struct sta_info { - u8 au8Sta_AssociatedBss[MAX_NUM_STA][ETH_ALEN]; + u8 sta_associated_bss[MAX_NUM_STA][ETH_ALEN]; }; /*Parameters needed for host interface for remaining on channel*/ -struct wilc_wfi_p2pListenParams { - struct ieee80211_channel *pstrListenChan; - enum nl80211_channel_type tenuChannelType; - u32 u32ListenDuration; - u64 u64ListenCookie; - u32 u32ListenSessionID; +struct wilc_wfi_p2p_listen_params { + struct ieee80211_channel *listen_ch; + u32 listen_duration; + u64 listen_cookie; + u32 listen_session_id; }; struct wilc_priv { struct wireless_dev *wdev; - struct cfg80211_scan_request *pstrScanReq; + struct cfg80211_scan_request *scan_req; - struct wilc_wfi_p2pListenParams strRemainOnChanParams; - u64 u64tx_cookie; + struct wilc_wfi_p2p_listen_params remain_on_ch_params; + u64 tx_cookie; - bool bCfgScanning; - u32 u32RcvdChCount; + bool cfg_scanning; + u32 rcvd_ch_cnt; - u8 au8AssociatedBss[ETH_ALEN]; + u8 associated_bss[ETH_ALEN]; struct sta_info assoc_stainfo; struct net_device_stats stats; u8 monitor_flag; @@ -135,9 +134,9 @@ struct wilc_priv { /* mutexes */ struct mutex scan_req_lock; /* */ - bool gbAutoRateAdjusted; + bool auto_rate_adjusted; - bool bInP2PlistenState; + bool p2p_listen_state; }; diff --git a/drivers/staging/wilc1000/wilc_wlan.c b/drivers/staging/wilc1000/wilc_wlan.c index f49dfa82f1b8..acaeafc2c350 100644 --- a/drivers/staging/wilc1000/wilc_wlan.c +++ b/drivers/staging/wilc1000/wilc_wlan.c @@ -1,19 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 #include <linux/completion.h> #include "wilc_wlan_if.h" #include "wilc_wlan.h" #include "wilc_wfi_netdevice.h" #include "wilc_wlan_cfg.h" -static CHIP_PS_STATE_T chip_ps_state = CHIP_WAKEDUP; +static enum chip_ps_states chip_ps_state = CHIP_WAKEDUP; -static inline void acquire_bus(struct wilc *wilc, BUS_ACQUIRE_T acquire) +static inline void acquire_bus(struct wilc *wilc, enum bus_acquire acquire) { mutex_lock(&wilc->hif_cs); if (acquire == ACQUIRE_AND_WAKEUP) chip_wakeup(wilc); } -static inline void release_bus(struct wilc *wilc, BUS_RELEASE_T release) +static inline void release_bus(struct wilc *wilc, enum bus_release release) { if (release == RELEASE_ALLOW_SLEEP) chip_allow_sleep(wilc); @@ -692,7 +693,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count) i = 0; do { tqe = wilc_wlan_txq_remove_from_head(dev); - if (tqe && (vmm_table[i] != 0)) { + if (tqe && vmm_table[i] != 0) { u32 header, buffer_offset; vmm_table[i] = cpu_to_le32(vmm_table[i]); diff --git a/drivers/staging/wilc1000/wilc_wlan_cfg.c b/drivers/staging/wilc1000/wilc_wlan_cfg.c index 19e4f85fdd27..aeb5417f3587 100644 --- a/drivers/staging/wilc1000/wilc_wlan_cfg.c +++ b/drivers/staging/wilc1000/wilc_wlan_cfg.c @@ -235,7 +235,7 @@ static int wilc_wlan_cfg_set_str(u8 *frame, u32 offset, u16 id, u8 *str, u32 siz buf[2] = (u8)size; buf[3] = (u8)(size >> 8); - if ((str) && (size != 0)) + if (str && size != 0) memcpy(&buf[4], str, size); return (size + 4); @@ -256,7 +256,7 @@ static int wilc_wlan_cfg_set_bin(u8 *frame, u32 offset, u16 id, u8 *b, u32 size) buf[2] = (u8)size; buf[3] = (u8)(size >> 8); - if ((b) && (size != 0)) { + if ((b) && size != 0) { memcpy(&buf[4], b, size); for (i = 0; i < size; i++) checksum += buf[i + 4]; @@ -370,7 +370,7 @@ static int wilc_wlan_parse_info_frame(u8 *info, int size) len = info[2]; - if ((len == 1) && (wid == WID_STATUS)) { + if (len == 1 && wid == WID_STATUS) { pd->mac_status = info[3]; type = WILC_CFG_RSP_STATUS; } diff --git a/drivers/staging/wilc1000/wilc_wlan_if.h b/drivers/staging/wilc1000/wilc_wlan_if.h index c1693cfc076d..e186509ad334 100644 --- a/drivers/staging/wilc1000/wilc_wlan_if.h +++ b/drivers/staging/wilc1000/wilc_wlan_if.h @@ -75,7 +75,7 @@ typedef void (*wilc_tx_complete_func_t)(void *, int); #define MAX_SSID_LEN 33 #define MAX_RATES_SUPPORTED 12 -typedef enum { +enum { SUPP_RATES_IE = 1, EXT_SUPP_RATES_IE = 50, HT_CAPABILITY_IE = 45, @@ -83,15 +83,15 @@ typedef enum { WPA_IE = 221, WMM_IE = 221, P2P_IE = 221, -} BEACON_IE; +}; -typedef enum { +enum bss_types { INFRASTRUCTURE = 0, INDEPENDENT, AP, -} BSSTYPE_T; +}; -typedef enum { +enum { RATE_AUTO = 0, RATE_1MB = 1, RATE_2MB = 2, @@ -105,55 +105,55 @@ typedef enum { RATE_26MB = 36, RATE_48MB = 48, RATE_54MB = 54 -} TX_RATE_T; +}; -typedef enum { +enum { B_ONLY_MODE = 0, /* 1, 2 M, otherwise 5, 11 M */ G_ONLY_MODE, /* 6,12,24 otherwise 9,18,36,48,54 */ G_MIXED_11B_1_MODE, /* 1,2,5.5,11 otherwise all on */ G_MIXED_11B_2_MODE, /* 1,2,5,11,6,12,24 otherwise all on */ -} G_OPERATING_MODE_T; +}; -typedef enum { +enum { G_SHORT_PREAMBLE = 0, /* Short Preamble */ G_LONG_PREAMBLE = 1, /* Long Preamble */ G_AUTO_PREAMBLE = 2, /* Auto Preamble Selection */ -} G_PREAMBLE_T; +}; #define MAC_CONNECTED 1 #define MAC_DISCONNECTED 0 #define SCAN_DONE TRUE -typedef enum { +enum { PASSIVE_SCAN = 0, ACTIVE_SCAN = 1, -} SCANTYPE_T; +}; -typedef enum { +enum { NO_POWERSAVE = 0, MIN_FAST_PS = 1, MAX_FAST_PS = 2, MIN_PSPOLL_PS = 3, MAX_PSPOLL_PS = 4 -} USER_PS_MODE_T; +}; -typedef enum { +enum chip_ps_states { CHIP_WAKEDUP = 0, CHIP_SLEEPING_AUTO = 1, CHIP_SLEEPING_MANUAL = 2 -} CHIP_PS_STATE_T; +}; -typedef enum { +enum bus_acquire { ACQUIRE_ONLY = 0, ACQUIRE_AND_WAKEUP = 1, -} BUS_ACQUIRE_T; +}; -typedef enum { +enum bus_release { RELEASE_ONLY = 0, RELEASE_ALLOW_SLEEP = 1, -} BUS_RELEASE_T; +}; -typedef enum { +enum { NO_SECURITY = 0, WEP_40 = 0x3, WEP_104 = 0x7, @@ -163,7 +163,7 @@ typedef enum { WPA2_AES = 0x31, WPA2_TKIP = 0x51, WPA2_AES_TKIP = 0x71, /* Aes or Tkip */ -} SECURITY_T; +}; enum AUTHTYPE { OPEN_SYSTEM = 1, @@ -178,88 +178,88 @@ enum SITESURVEY { SITE_SURVEY_OFF = 2 }; -typedef enum { +enum { NORMAL_ACK = 0, NO_ACK, -} ACK_POLICY_T; +}; -typedef enum { +enum { DONT_RESET = 0, DO_RESET = 1, NO_REQUEST = 2, -} RESET_REQ_T; +}; -typedef enum { +enum { REKEY_DISABLE = 1, REKEY_TIME_BASE, REKEY_PKT_BASE, REKEY_TIME_PKT_BASE -} RSNA_REKEY_POLICY_T; +}; -typedef enum { +enum { FILTER_NO = 0x00, FILTER_AP_ONLY = 0x01, FILTER_STA_ONLY = 0x02 -} SCAN_CLASS_FITLER_T; +}; -typedef enum { +enum { PRI_HIGH_RSSI = 0x00, PRI_LOW_RSSI = 0x04, PRI_DETECT = 0x08 -} SCAN_PRI_T; +}; -typedef enum { +enum { CH_FILTER_OFF = 0x00, CH_FILTER_ON = 0x10 -} CH_FILTER_T; +}; -typedef enum { +enum { AUTO_PROT = 0, /* Auto */ NO_PROT, /* Do not use any protection */ ERP_PROT, /* Protect all ERP frame exchanges */ HT_PROT, /* Protect all HT frame exchanges */ GF_PROT, /* Protect all GF frame exchanges */ -} N_PROTECTION_MODE_T; +}; -typedef enum { +enum { G_SELF_CTS_PROT, G_RTS_CTS_PROT, -} G_PROTECTION_MODE_T; +}; -typedef enum { +enum { HT_MIXED_MODE = 1, HT_ONLY_20MHZ_MODE, HT_ONLY_20_40MHZ_MODE, -} N_OPERATING_MODE_T; +}; -typedef enum { +enum { NO_DETECT = 0, DETECT_ONLY = 1, DETECT_PROTECT = 2, DETECT_PROTECT_REPORT = 3, -} N_OBSS_DETECTION_T; +}; -typedef enum { +enum { RTS_CTS_NONHT_PROT = 0, /* RTS-CTS at non-HT rate */ FIRST_FRAME_NONHT_PROT, /* First frame at non-HT rate */ LSIG_TXOP_PROT, /* LSIG TXOP Protection */ FIRST_FRAME_MIXED_PROT, /* First frame at Mixed format */ -} N_PROTECTION_TYPE_T; +}; -typedef enum { +enum { STATIC_MODE = 1, DYNAMIC_MODE = 2, MIMO_MODE = 3, /* power save disable */ -} N_SMPS_MODE_T; +}; -typedef enum { +enum { DISABLE_SELF_CTS, ENABLE_SELF_CTS, DISABLE_TX_ABORT, ENABLE_TX_ABORT, HW_TRIGGER_ABORT, SW_TRIGGER_ABORT, -} TX_ABORT_OPTION_T; +}; enum wid_type { WID_CHAR = 0, @@ -281,7 +281,7 @@ struct wid { s8 *val; }; -typedef enum { +enum { WID_NIL = 0xffff, /* @@ -889,7 +889,7 @@ typedef enum { /* Miscellaneous WIDs */ WID_ALL = 0x7FFE, WID_MAX = 0xFFFF -} WID_T; +}; struct wilc; int wilc_wlan_init(struct net_device *dev); diff --git a/drivers/staging/wlan-ng/hfa384x.h b/drivers/staging/wlan-ng/hfa384x.h index f5a3a1ce21ce..85c3af00abd2 100644 --- a/drivers/staging/wlan-ng/hfa384x.h +++ b/drivers/staging/wlan-ng/hfa384x.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) /* hfa384x.h * * Defines the constants and data structures for the hfa384x diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c index 197f5a914e8f..555711bc12f0 100644 --- a/drivers/staging/wlan-ng/hfa384x_usb.c +++ b/drivers/staging/wlan-ng/hfa384x_usb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) /* src/prism2/driver/hfa384x_usb.c * * Functions that talk to the USB variantof the Intersil hfa384x MAC @@ -2457,7 +2458,8 @@ int hfa384x_drvr_start(struct hfa384x *hw) * ok */ result = - usb_get_std_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_in, &status); + usb_get_std_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_in, + &status); if (result < 0) { netdev_err(hw->wlandev->netdev, "Cannot get bulk in endpoint status.\n"); goto done; @@ -2466,7 +2468,8 @@ int hfa384x_drvr_start(struct hfa384x *hw) netdev_err(hw->wlandev->netdev, "Failed to reset bulk in endpoint.\n"); result = - usb_get_std_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_out, &status); + usb_get_std_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_out, + &status); if (result < 0) { netdev_err(hw->wlandev->netdev, "Cannot get bulk out endpoint status.\n"); goto done; diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c index c1b6d426bcad..855b424f6423 100644 --- a/drivers/staging/wlan-ng/p80211conv.c +++ b/drivers/staging/wlan-ng/p80211conv.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) /* src/p80211/p80211conv.c * * Ether/802.11 conversions and packet buffer routines diff --git a/drivers/staging/wlan-ng/p80211conv.h b/drivers/staging/wlan-ng/p80211conv.h index 66332b1fb6d5..28459dcea4b1 100644 --- a/drivers/staging/wlan-ng/p80211conv.h +++ b/drivers/staging/wlan-ng/p80211conv.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) /* p80211conv.h * * Ether/802.11 conversions and packet buffer routines diff --git a/drivers/staging/wlan-ng/p80211hdr.h b/drivers/staging/wlan-ng/p80211hdr.h index 2c44c613a586..133d70c08ecf 100644 --- a/drivers/staging/wlan-ng/p80211hdr.h +++ b/drivers/staging/wlan-ng/p80211hdr.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) /* p80211hdr.h * * Macros, types, and functions for handling 802.11 MAC headers diff --git a/drivers/staging/wlan-ng/p80211ioctl.h b/drivers/staging/wlan-ng/p80211ioctl.h index ab6067e65050..d8cde1d8870b 100644 --- a/drivers/staging/wlan-ng/p80211ioctl.h +++ b/drivers/staging/wlan-ng/p80211ioctl.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) /* p80211ioctl.h * * Declares constants and types for the p80211 ioctls diff --git a/drivers/staging/wlan-ng/p80211metadef.h b/drivers/staging/wlan-ng/p80211metadef.h index ea3d9ce222b9..4ac2f08a520a 100644 --- a/drivers/staging/wlan-ng/p80211metadef.h +++ b/drivers/staging/wlan-ng/p80211metadef.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) /* This file is GENERATED AUTOMATICALLY. DO NOT EDIT OR MODIFY. * -------------------------------------------------------------------- * diff --git a/drivers/staging/wlan-ng/p80211metastruct.h b/drivers/staging/wlan-ng/p80211metastruct.h index 850d897fc163..15b7c08e210d 100644 --- a/drivers/staging/wlan-ng/p80211metastruct.h +++ b/drivers/staging/wlan-ng/p80211metastruct.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) /* This file is GENERATED AUTOMATICALLY. DO NOT EDIT OR MODIFY. * -------------------------------------------------------------------- * diff --git a/drivers/staging/wlan-ng/p80211mgmt.h b/drivers/staging/wlan-ng/p80211mgmt.h index 653950fd9843..3c12929858cb 100644 --- a/drivers/staging/wlan-ng/p80211mgmt.h +++ b/drivers/staging/wlan-ng/p80211mgmt.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) /* p80211mgmt.h * * Macros, types, and functions to handle 802.11 mgmt frames diff --git a/drivers/staging/wlan-ng/p80211msg.h b/drivers/staging/wlan-ng/p80211msg.h index 40c5cf5997c7..ae119ecd74b0 100644 --- a/drivers/staging/wlan-ng/p80211msg.h +++ b/drivers/staging/wlan-ng/p80211msg.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) /* p80211msg.h * * Macros, constants, types, and funcs for req and ind messages diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c index 0f503652740f..ec9cc00ee241 100644 --- a/drivers/staging/wlan-ng/p80211netdev.c +++ b/drivers/staging/wlan-ng/p80211netdev.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) /* src/p80211/p80211knetdev.c * * Linux Kernel net device interface @@ -640,7 +641,8 @@ static int p80211knetdev_set_mac_address(struct net_device *dev, void *addr) dot11req.msgcode = DIDmsg_dot11req_mibset; dot11req.msglen = sizeof(dot11req); memcpy(dot11req.devname, - ((struct wlandevice *)dev->ml_priv)->name, WLAN_DEVNAMELEN_MAX - 1); + ((struct wlandevice *)dev->ml_priv)->name, + WLAN_DEVNAMELEN_MAX - 1); /* Set up the mibattribute argument */ mibattr->did = DIDmsg_dot11req_mibset_mibattribute; diff --git a/drivers/staging/wlan-ng/p80211netdev.h b/drivers/staging/wlan-ng/p80211netdev.h index 8e0d08298c8b..cebbe746a52f 100644 --- a/drivers/staging/wlan-ng/p80211netdev.h +++ b/drivers/staging/wlan-ng/p80211netdev.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) /* p80211netdev.h * * WLAN net device structure and functions diff --git a/drivers/staging/wlan-ng/p80211req.c b/drivers/staging/wlan-ng/p80211req.c index afe847722cf7..c36d01469afc 100644 --- a/drivers/staging/wlan-ng/p80211req.c +++ b/drivers/staging/wlan-ng/p80211req.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) /* src/p80211/p80211req.c * * Request/Indication/MacMgmt interface handling functions diff --git a/drivers/staging/wlan-ng/p80211req.h b/drivers/staging/wlan-ng/p80211req.h index 6c72f59993e0..20be2c3af4c1 100644 --- a/drivers/staging/wlan-ng/p80211req.h +++ b/drivers/staging/wlan-ng/p80211req.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) /* p80211req.h * * Request handling functions diff --git a/drivers/staging/wlan-ng/p80211types.h b/drivers/staging/wlan-ng/p80211types.h index 263ef2ddb197..94420562c418 100644 --- a/drivers/staging/wlan-ng/p80211types.h +++ b/drivers/staging/wlan-ng/p80211types.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) /* * p80211types.h * diff --git a/drivers/staging/wlan-ng/p80211wep.c b/drivers/staging/wlan-ng/p80211wep.c index 6492ffe59085..8bd92bba0ac1 100644 --- a/drivers/staging/wlan-ng/p80211wep.c +++ b/drivers/staging/wlan-ng/p80211wep.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) /* src/p80211/p80211wep.c * * WEP encode/decode for P80211. diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c index 344bec8cc31b..5860d0d65841 100644 --- a/drivers/staging/wlan-ng/prism2fw.c +++ b/drivers/staging/wlan-ng/prism2fw.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) /* from src/prism2/download/prism2dl.c * * utility for downloading prism2 images moved into kernelspace diff --git a/drivers/staging/wlan-ng/prism2mgmt.c b/drivers/staging/wlan-ng/prism2mgmt.c index 72070593394a..78934e435fcf 100644 --- a/drivers/staging/wlan-ng/prism2mgmt.c +++ b/drivers/staging/wlan-ng/prism2mgmt.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) /* src/prism2/driver/prism2mgmt.c * * Management request handler functions. diff --git a/drivers/staging/wlan-ng/prism2mgmt.h b/drivers/staging/wlan-ng/prism2mgmt.h index c062418f1202..564c3f4a3e03 100644 --- a/drivers/staging/wlan-ng/prism2mgmt.h +++ b/drivers/staging/wlan-ng/prism2mgmt.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) /* prism2mgmt.h * * Declares the mgmt command handler functions diff --git a/drivers/staging/wlan-ng/prism2mib.c b/drivers/staging/wlan-ng/prism2mib.c index e41207d97309..edad299ff5ad 100644 --- a/drivers/staging/wlan-ng/prism2mib.c +++ b/drivers/staging/wlan-ng/prism2mib.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) /* src/prism2/driver/prism2mib.c * * Management request for mibset/mibget diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c index 99316b9a4e49..fed0b8ceca6f 100644 --- a/drivers/staging/wlan-ng/prism2sta.c +++ b/drivers/staging/wlan-ng/prism2sta.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) /* src/prism2/driver/prism2sta.c * * Implements the station functionality for prism2 diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index a3af1cbbf8ee..e19a8291cb2a 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -18,19 +18,6 @@ static const struct pci_device_id xgifb_pci_table[] = { MODULE_DEVICE_TABLE(pci, xgifb_pci_table); -/* To be included in fb.h */ -#define XGISR (xgifb_info->dev_info.P3c4) -#define XGICR (xgifb_info->dev_info.P3d4) -#define XGIDACA (xgifb_info->dev_info.P3c8) -#define XGIDACD (xgifb_info->dev_info.P3c9) -#define XGIPART1 (xgifb_info->dev_info.Part1Port) -#define XGIPART2 (xgifb_info->dev_info.Part2Port) -#define XGIPART3 (xgifb_info->dev_info.Part3Port) -#define XGIPART4 (xgifb_info->dev_info.Part4Port) -#define XGIPART5 (xgifb_info->dev_info.Part5Port) -#define XGIDAC2A XGIPART5 -#define XGIDAC2D (XGIPART5 + 1) - #define IND_XGI_SCRATCH_REG_CR30 0x30 /* CRs */ #define IND_XGI_SCRATCH_REG_CR31 0x31 #define IND_XGI_SCRATCH_REG_CR32 0x32 diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index b813f1d460ce..10107de0119a 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * XG20, XG21, XG40, XG42 frame buffer device * for Linux kernels 2.5.x, 2.6.x @@ -31,18 +32,19 @@ static unsigned int refresh_rate; #ifdef DEBUG static void dumpVGAReg(struct xgifb_video_info *xgifb_info) { + struct vb_device_info *vb = &xgifb_info->dev_info; u8 i, reg; - xgifb_reg_set(XGISR, 0x05, 0x86); + xgifb_reg_set(vb->P3c4, 0x05, 0x86); for (i = 0; i < 0x4f; i++) { - reg = xgifb_reg_get(XGISR, i); + reg = xgifb_reg_get(vb->P3c4, i); pr_debug("o 3c4 %x\n", i); pr_debug("i 3c5 => %x\n", reg); } for (i = 0; i < 0xF0; i++) { - reg = xgifb_reg_get(XGICR, i); + reg = xgifb_reg_get(vb->P3d4, i); pr_debug("o 3d4 %x\n", i); pr_debug("i 3d5 => %x\n", reg); } @@ -644,9 +646,10 @@ static void XGIfb_bpp_to_var(struct xgifb_video_info *xgifb_info, static void XGIfb_pre_setmode(struct xgifb_video_info *xgifb_info) { + struct vb_device_info *vb = &xgifb_info->dev_info; u8 cr30 = 0, cr31 = 0; - cr31 = xgifb_reg_get(XGICR, 0x31); + cr31 = xgifb_reg_get(vb->P3d4, 0x31); cr31 &= ~0x60; switch (xgifb_info->display2) { @@ -683,14 +686,15 @@ static void XGIfb_pre_setmode(struct xgifb_video_info *xgifb_info) cr31 |= (SIS_DRIVER_MODE | SIS_VB_OUTPUT_DISABLE); } - xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30); - xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31); - xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR33, + xgifb_reg_set(vb->P3d4, IND_XGI_SCRATCH_REG_CR30, cr30); + xgifb_reg_set(vb->P3d4, IND_XGI_SCRATCH_REG_CR31, cr31); + xgifb_reg_set(vb->P3d4, IND_XGI_SCRATCH_REG_CR33, (xgifb_info->rate_idx & 0x0F)); } static void XGIfb_post_setmode(struct xgifb_video_info *xgifb_info) { + struct vb_device_info *vb = &xgifb_info->dev_info; u8 reg; unsigned char doit = 1; @@ -713,7 +717,7 @@ static void XGIfb_post_setmode(struct xgifb_video_info *xgifb_info) /* We can't switch off CRT1 if bridge is in slave mode */ if (xgifb_info->hasVB != HASVB_NONE) { - reg = xgifb_reg_get(XGIPART1, 0x00); + reg = xgifb_reg_get(vb->Part1Port, 0x00); if ((reg & 0x50) == 0x10) doit = 0; @@ -722,18 +726,18 @@ static void XGIfb_post_setmode(struct xgifb_video_info *xgifb_info) XGIfb_crt1off = 0; } - reg = xgifb_reg_get(XGICR, 0x17); + reg = xgifb_reg_get(vb->P3d4, 0x17); if ((XGIfb_crt1off) && (doit)) reg &= ~0x80; else reg |= 0x80; - xgifb_reg_set(XGICR, 0x17, reg); + xgifb_reg_set(vb->P3d4, 0x17, reg); - xgifb_reg_and(XGISR, IND_SIS_RAMDAC_CONTROL, ~0x04); + xgifb_reg_and(vb->P3c4, IND_SIS_RAMDAC_CONTROL, ~0x04); if (xgifb_info->display2 == XGIFB_DISP_TV && xgifb_info->hasVB == HASVB_301) { - reg = xgifb_reg_get(XGIPART4, 0x01); + reg = xgifb_reg_get(vb->Part4Port, 0x01); if (reg < 0xB0) { /* Set filter for XGI301 */ int filter_tb; @@ -760,60 +764,58 @@ static void XGIfb_post_setmode(struct xgifb_video_info *xgifb_info) filter = -1; break; } - xgifb_reg_or(XGIPART1, - SIS_CRT2_WENABLE_315, - 0x01); + xgifb_reg_or(vb->Part1Port, SIS_CRT2_WENABLE_315, 0x01); if (xgifb_info->TV_type == TVMODE_NTSC) { - xgifb_reg_and(XGIPART2, 0x3a, 0x1f); + xgifb_reg_and(vb->Part2Port, 0x3a, 0x1f); if (xgifb_info->TV_plug == TVPLUG_SVIDEO) { - xgifb_reg_and(XGIPART2, 0x30, 0xdf); + xgifb_reg_and(vb->Part2Port, 0x30, 0xdf); } else if (xgifb_info->TV_plug == TVPLUG_COMPOSITE) { - xgifb_reg_or(XGIPART2, 0x30, 0x20); + xgifb_reg_or(vb->Part2Port, 0x30, 0x20); switch (xgifb_info->video_width) { case 640: - xgifb_reg_set(XGIPART2, + xgifb_reg_set(vb->Part2Port, 0x35, 0xEB); - xgifb_reg_set(XGIPART2, + xgifb_reg_set(vb->Part2Port, 0x36, 0x04); - xgifb_reg_set(XGIPART2, + xgifb_reg_set(vb->Part2Port, 0x37, 0x25); - xgifb_reg_set(XGIPART2, + xgifb_reg_set(vb->Part2Port, 0x38, 0x18); break; case 720: - xgifb_reg_set(XGIPART2, + xgifb_reg_set(vb->Part2Port, 0x35, 0xEE); - xgifb_reg_set(XGIPART2, + xgifb_reg_set(vb->Part2Port, 0x36, 0x0C); - xgifb_reg_set(XGIPART2, + xgifb_reg_set(vb->Part2Port, 0x37, 0x22); - xgifb_reg_set(XGIPART2, + xgifb_reg_set(vb->Part2Port, 0x38, 0x08); break; case 800: - xgifb_reg_set(XGIPART2, + xgifb_reg_set(vb->Part2Port, 0x35, 0xEB); - xgifb_reg_set(XGIPART2, + xgifb_reg_set(vb->Part2Port, 0x36, 0x15); - xgifb_reg_set(XGIPART2, + xgifb_reg_set(vb->Part2Port, 0x37, 0x25); - xgifb_reg_set(XGIPART2, + xgifb_reg_set(vb->Part2Port, 0x38, 0xF6); break; @@ -821,55 +823,55 @@ static void XGIfb_post_setmode(struct xgifb_video_info *xgifb_info) } } else if (xgifb_info->TV_type == TVMODE_PAL) { - xgifb_reg_and(XGIPART2, 0x3A, 0x1F); + xgifb_reg_and(vb->Part2Port, 0x3A, 0x1F); if (xgifb_info->TV_plug == TVPLUG_SVIDEO) { - xgifb_reg_and(XGIPART2, 0x30, 0xDF); + xgifb_reg_and(vb->Part2Port, 0x30, 0xDF); } else if (xgifb_info->TV_plug == TVPLUG_COMPOSITE) { - xgifb_reg_or(XGIPART2, 0x30, 0x20); + xgifb_reg_or(vb->Part2Port, 0x30, 0x20); switch (xgifb_info->video_width) { case 640: - xgifb_reg_set(XGIPART2, + xgifb_reg_set(vb->Part2Port, 0x35, 0xF1); - xgifb_reg_set(XGIPART2, + xgifb_reg_set(vb->Part2Port, 0x36, 0xF7); - xgifb_reg_set(XGIPART2, + xgifb_reg_set(vb->Part2Port, 0x37, 0x1F); - xgifb_reg_set(XGIPART2, + xgifb_reg_set(vb->Part2Port, 0x38, 0x32); break; case 720: - xgifb_reg_set(XGIPART2, + xgifb_reg_set(vb->Part2Port, 0x35, 0xF3); - xgifb_reg_set(XGIPART2, + xgifb_reg_set(vb->Part2Port, 0x36, 0x00); - xgifb_reg_set(XGIPART2, + xgifb_reg_set(vb->Part2Port, 0x37, 0x1D); - xgifb_reg_set(XGIPART2, + xgifb_reg_set(vb->Part2Port, 0x38, 0x20); break; case 800: - xgifb_reg_set(XGIPART2, + xgifb_reg_set(vb->Part2Port, 0x35, 0xFC); - xgifb_reg_set(XGIPART2, + xgifb_reg_set(vb->Part2Port, 0x36, 0xFB); - xgifb_reg_set(XGIPART2, + xgifb_reg_set(vb->Part2Port, 0x37, 0x14); - xgifb_reg_set(XGIPART2, + xgifb_reg_set(vb->Part2Port, 0x38, 0x2A); break; @@ -882,10 +884,10 @@ static void XGIfb_post_setmode(struct xgifb_video_info *xgifb_info) pr_debug("FilterTable[%d]-%d: %*ph\n", filter_tb, filter, 4, f); - xgifb_reg_set(XGIPART2, 0x35, f[0]); - xgifb_reg_set(XGIPART2, 0x36, f[1]); - xgifb_reg_set(XGIPART2, 0x37, f[2]); - xgifb_reg_set(XGIPART2, 0x38, f[3]); + xgifb_reg_set(vb->Part2Port, 0x35, f[0]); + xgifb_reg_set(vb->Part2Port, 0x36, f[1]); + xgifb_reg_set(vb->Part2Port, 0x37, f[2]); + xgifb_reg_set(vb->Part2Port, 0x38, f[3]); } } } @@ -895,6 +897,7 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, struct fb_info *info) { struct xgifb_video_info *xgifb_info = info->par; + struct vb_device_info *vb = &xgifb_info->dev_info; struct xgi_hw_device_info *hw_info = &xgifb_info->hw_info; unsigned int htotal = var->left_margin + var->xres + var->right_margin + var->hsync_len; @@ -981,11 +984,10 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, info->fix.line_length = (info->var.xres_virtual * info->var.bits_per_pixel) >> 6; - xgifb_reg_set(XGISR, IND_SIS_PASSWORD, SIS_PASSWORD); + xgifb_reg_set(vb->P3c4, IND_SIS_PASSWORD, SIS_PASSWORD); - xgifb_reg_set(XGICR, 0x13, (info->fix.line_length & 0x00ff)); - xgifb_reg_set(XGISR, - 0x0E, + xgifb_reg_set(vb->P3d4, 0x13, (info->fix.line_length & 0x00ff)); + xgifb_reg_set(vb->P3c4, 0x0E, (info->fix.line_length & 0xff00) >> 8); XGIfb_post_setmode(xgifb_info); @@ -1013,16 +1015,16 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, xgifb_info->XGI310_AccelDepth = 0x00000000; xgifb_info->video_cmap_len = 256; #if defined(__BIG_ENDIAN) - cr_data = xgifb_reg_get(XGICR, 0x4D); - xgifb_reg_set(XGICR, 0x4D, (cr_data & 0xE0)); + cr_data = xgifb_reg_get(vb->P3d4, 0x4D); + xgifb_reg_set(vb->P3d4, 0x4D, (cr_data & 0xE0)); #endif break; case 16: xgifb_info->DstColor = 0x8000; xgifb_info->XGI310_AccelDepth = 0x00010000; #if defined(__BIG_ENDIAN) - cr_data = xgifb_reg_get(XGICR, 0x4D); - xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B)); + cr_data = xgifb_reg_get(vb->P3d4, 0x4D); + xgifb_reg_set(vb->P3d4, 0x4D, ((cr_data & 0xE0) | 0x0B)); #endif xgifb_info->video_cmap_len = 16; break; @@ -1031,8 +1033,8 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, xgifb_info->XGI310_AccelDepth = 0x00020000; xgifb_info->video_cmap_len = 16; #if defined(__BIG_ENDIAN) - cr_data = xgifb_reg_get(XGICR, 0x4D); - xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15)); + cr_data = xgifb_reg_get(vb->P3d4, 0x4D); + xgifb_reg_set(vb->P3d4, 0x4D, ((cr_data & 0xE0) | 0x15)); #endif break; default: @@ -1051,6 +1053,7 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, static int XGIfb_pan_var(struct fb_var_screeninfo *var, struct fb_info *info) { struct xgifb_video_info *xgifb_info = info->par; + struct vb_device_info *vb = &xgifb_info->dev_info; unsigned int base; base = var->yoffset * info->var.xres_virtual + var->xoffset; @@ -1068,22 +1071,20 @@ static int XGIfb_pan_var(struct fb_var_screeninfo *var, struct fb_info *info) break; } - xgifb_reg_set(XGISR, IND_SIS_PASSWORD, SIS_PASSWORD); + xgifb_reg_set(vb->P3c4, IND_SIS_PASSWORD, SIS_PASSWORD); - xgifb_reg_set(XGICR, 0x0D, base & 0xFF); - xgifb_reg_set(XGICR, 0x0C, (base >> 8) & 0xFF); - xgifb_reg_set(XGISR, 0x0D, (base >> 16) & 0xFF); - xgifb_reg_set(XGISR, 0x37, (base >> 24) & 0x03); - xgifb_reg_and_or(XGISR, 0x37, 0xDF, (base >> 21) & 0x04); + xgifb_reg_set(vb->P3d4, 0x0D, base & 0xFF); + xgifb_reg_set(vb->P3d4, 0x0C, (base >> 8) & 0xFF); + xgifb_reg_set(vb->P3c4, 0x0D, (base >> 16) & 0xFF); + xgifb_reg_set(vb->P3c4, 0x37, (base >> 24) & 0x03); + xgifb_reg_and_or(vb->P3c4, 0x37, 0xDF, (base >> 21) & 0x04); if (xgifb_info->display2 != XGIFB_DISP_NONE) { - xgifb_reg_or(XGIPART1, SIS_CRT2_WENABLE_315, 0x01); - xgifb_reg_set(XGIPART1, 0x06, (base & 0xFF)); - xgifb_reg_set(XGIPART1, 0x05, ((base >> 8) & 0xFF)); - xgifb_reg_set(XGIPART1, 0x04, ((base >> 16) & 0xFF)); - xgifb_reg_and_or(XGIPART1, - 0x02, - 0x7F, + xgifb_reg_or(vb->Part1Port, SIS_CRT2_WENABLE_315, 0x01); + xgifb_reg_set(vb->Part1Port, 0x06, (base & 0xFF)); + xgifb_reg_set(vb->Part1Port, 0x05, ((base >> 8) & 0xFF)); + xgifb_reg_set(vb->Part1Port, 0x04, ((base >> 16) & 0xFF)); + xgifb_reg_and_or(vb->Part1Port, 0x02, 0x7F, ((base >> 24) & 0x01) << 7); } return 0; @@ -1110,21 +1111,22 @@ static int XGIfb_setcolreg(unsigned int regno, unsigned int red, unsigned int transp, struct fb_info *info) { struct xgifb_video_info *xgifb_info = info->par; + struct vb_device_info *vb = &xgifb_info->dev_info; if (regno >= XGIfb_get_cmap_len(&info->var)) return 1; switch (info->var.bits_per_pixel) { case 8: - outb(regno, XGIDACA); - outb((red >> 10), XGIDACD); - outb((green >> 10), XGIDACD); - outb((blue >> 10), XGIDACD); + outb(regno, vb->P3c8); + outb((red >> 10), vb->P3c9); + outb((green >> 10), vb->P3c9); + outb((blue >> 10), vb->P3c9); if (xgifb_info->display2 != XGIFB_DISP_NONE) { - outb(regno, XGIDAC2A); - outb((red >> 8), XGIDAC2D); - outb((green >> 8), XGIDAC2D); - outb((blue >> 8), XGIDAC2D); + outb(regno, vb->Part5Port); + outb((red >> 8), (vb->Part5Port + 1)); + outb((green >> 8), (vb->Part5Port + 1)); + outb((blue >> 8), (vb->Part5Port + 1)); } break; case 16: @@ -1344,18 +1346,19 @@ static int XGIfb_pan_display(struct fb_var_screeninfo *var, static int XGIfb_blank(int blank, struct fb_info *info) { struct xgifb_video_info *xgifb_info = info->par; + struct vb_device_info *vb = &xgifb_info->dev_info; u8 reg; - reg = xgifb_reg_get(XGICR, 0x17); + reg = xgifb_reg_get(vb->P3d4, 0x17); if (blank > 0) reg &= 0x7f; else reg |= 0x80; - xgifb_reg_set(XGICR, 0x17, reg); - xgifb_reg_set(XGISR, 0x00, 0x01); /* Synchronous Reset */ - xgifb_reg_set(XGISR, 0x00, 0x03); /* End Reset */ + xgifb_reg_set(vb->P3d4, 0x17, reg); + xgifb_reg_set(vb->P3c4, 0x00, 0x01); /* Synchronous Reset */ + xgifb_reg_set(vb->P3c4, 0x00, 0x03); /* End Reset */ return 0; } @@ -1379,14 +1382,15 @@ static struct fb_ops XGIfb_ops = { static int XGIfb_get_dram_size(struct xgifb_video_info *xgifb_info) { + struct vb_device_info *vb = &xgifb_info->dev_info; u8 ChannelNum, tmp; u8 reg = 0; /* xorg driver sets 32MB * 1 channel */ if (xgifb_info->chip == XG27) - xgifb_reg_set(XGISR, IND_SIS_DRAM_SIZE, 0x51); + xgifb_reg_set(vb->P3c4, IND_SIS_DRAM_SIZE, 0x51); - reg = xgifb_reg_get(XGISR, IND_SIS_DRAM_SIZE); + reg = xgifb_reg_get(vb->P3c4, IND_SIS_DRAM_SIZE); if (!reg) return -1; @@ -1457,12 +1461,13 @@ static int XGIfb_get_dram_size(struct xgifb_video_info *xgifb_info) static void XGIfb_detect_VB(struct xgifb_video_info *xgifb_info) { + struct vb_device_info *vb = &xgifb_info->dev_info; u8 cr32, temp = 0; xgifb_info->TV_plug = 0; xgifb_info->TV_type = 0; - cr32 = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR32); + cr32 = xgifb_reg_get(vb->P3d4, IND_XGI_SCRATCH_REG_CR32); if ((cr32 & SIS_CRT1) && !XGIfb_crt1off) { XGIfb_crt1off = 0; @@ -1499,7 +1504,7 @@ static void XGIfb_detect_VB(struct xgifb_video_info *xgifb_info) } if (xgifb_info->TV_type == 0) { - temp = xgifb_reg_get(XGICR, 0x38); + temp = xgifb_reg_get(vb->P3d4, 0x38); if (temp & 0x10) xgifb_info->TV_type = TVMODE_PAL; else @@ -1519,7 +1524,7 @@ static bool XGIfb_has_VB(struct xgifb_video_info *xgifb_info) { u8 vb_chipid; - vb_chipid = xgifb_reg_get(XGIPART4, 0x00); + vb_chipid = xgifb_reg_get(xgifb_info->dev_info.Part4Port, 0x00); switch (vb_chipid) { case 0x01: xgifb_info->hasVB = HASVB_301; @@ -1539,7 +1544,8 @@ static void XGIfb_get_VB_type(struct xgifb_video_info *xgifb_info) u8 reg; if (!XGIfb_has_VB(xgifb_info)) { - reg = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR37); + reg = xgifb_reg_get(xgifb_info->dev_info.P3d4, + IND_XGI_SCRATCH_REG_CR37); switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) { case SIS_EXTERNAL_CHIP_LVDS: xgifb_info->hasVB = HASVB_LVDS; @@ -1617,6 +1623,7 @@ static int xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) int ret; struct fb_info *fb_info; struct xgifb_video_info *xgifb_info; + struct vb_device_info *vb; struct xgi_hw_device_info *hw_info; unsigned long video_size_max; @@ -1625,6 +1632,7 @@ static int xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return -ENOMEM; xgifb_info = fb_info->par; + vb = &xgifb_info->dev_info; hw_info = &xgifb_info->hw_info; xgifb_info->fb_info = fb_info; xgifb_info->chip_id = pdev->device; @@ -1658,10 +1666,11 @@ static int xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) xgifb_info->display2_force = true; } - XGIRegInit(&xgifb_info->dev_info, xgifb_info->vga_base); + XGIRegInit(vb, xgifb_info->vga_base); - xgifb_reg_set(XGISR, IND_SIS_PASSWORD, SIS_PASSWORD); - reg1 = xgifb_reg_get(XGISR, IND_SIS_PASSWORD); + xgifb_reg_set(vb->P3c4, + IND_SIS_PASSWORD, SIS_PASSWORD); + reg1 = xgifb_reg_get(vb->P3c4, IND_SIS_PASSWORD); if (reg1 != 0xa1) { /* I/O error */ dev_err(&pdev->dev, "I/O error\n"); @@ -1671,8 +1680,10 @@ static int xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) switch (xgifb_info->chip_id) { case PCI_DEVICE_ID_XGI_20: - xgifb_reg_or(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN); - CR48 = xgifb_reg_get(XGICR, Index_CR_GPIO_Reg1); + xgifb_reg_or(vb->P3d4, + Index_CR_GPIO_Reg3, GPIOG_EN); + CR48 = xgifb_reg_get(vb->P3d4, + Index_CR_GPIO_Reg1); if (CR48 & GPIOG_READ) xgifb_info->chip = XG21; else @@ -1703,11 +1714,12 @@ static int xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */ - xgifb_reg_or(XGISR, + xgifb_reg_or(vb->P3c4, IND_SIS_PCI_ADDRESS_SET, (SIS_PCI_ADDR_ENABLE | SIS_MEM_MAP_IO_ENABLE)); /* Enable 2D accelerator engine */ - xgifb_reg_or(XGISR, IND_SIS_MODULE_ENABLE, SIS_ENABLE_2D); + xgifb_reg_or(vb->P3c4, + IND_SIS_MODULE_ENABLE, SIS_ENABLE_2D); hw_info->ulVideoMemorySize = xgifb_info->video_size; @@ -1760,7 +1772,7 @@ static int xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) (xgifb_info->chip == XG27)) { xgifb_info->hasVB = HASVB_NONE; } else if (xgifb_info->chip == XG21) { - CR38 = xgifb_reg_get(XGICR, 0x38); + CR38 = xgifb_reg_get(vb->P3d4, 0x38); if ((CR38 & 0xE0) == 0xC0) xgifb_info->display2 = XGIFB_DISP_LCD; else if ((CR38 & 0xE0) == 0x60) @@ -1777,7 +1789,7 @@ static int xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) switch (xgifb_info->hasVB) { case HASVB_301: - reg = xgifb_reg_get(XGIPART4, 0x01); + reg = xgifb_reg_get(vb->Part4Port, 0x01); if (reg >= 0xE0) { hw_info->ujVBChipID = VB_CHIP_302LV; dev_info(&pdev->dev, @@ -1794,7 +1806,7 @@ static int xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } break; case HASVB_302: - reg = xgifb_reg_get(XGIPART4, 0x01); + reg = xgifb_reg_get(vb->Part4Port, 0x01); if (reg >= 0xE0) { hw_info->ujVBChipID = VB_CHIP_302LV; dev_info(&pdev->dev, @@ -1806,7 +1818,8 @@ static int xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) "XGI302LV bridge detected (revision 0x%02x)\n", reg); } else if (reg >= 0xB0) { - reg1 = xgifb_reg_get(XGIPART4, 0x23); + reg1 = xgifb_reg_get(vb->Part4Port, + 0x23); hw_info->ujVBChipID = VB_CHIP_302B; @@ -1844,7 +1857,8 @@ static int xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (xgifb_info->display2 == XGIFB_DISP_LCD) { if (!enable_dstn) { - reg = xgifb_reg_get(XGICR, IND_XGI_LCD_PANEL); + reg = xgifb_reg_get(vb->P3d4, + IND_XGI_LCD_PANEL); reg &= 0x0f; hw_info->ulCRT2LCDType = XGI310paneltype[reg]; } @@ -1940,11 +1954,11 @@ static int xgifb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) XGIfb_bpp_to_var(xgifb_info, &fb_info->var); fb_info->var.pixclock = (u32)(1000000000 / XGIfb_mode_rate_to_dclock - (&xgifb_info->dev_info, hw_info, + (vb, hw_info, XGIbios_mode[xgifb_info->mode_idx].mode_no)); - if (XGIfb_mode_rate_to_ddata(&xgifb_info->dev_info, - hw_info, XGIbios_mode[xgifb_info->mode_idx].mode_no, + if (XGIfb_mode_rate_to_ddata(vb, hw_info, + XGIbios_mode[xgifb_info->mode_idx].mode_no, &fb_info->var.left_margin, &fb_info->var.right_margin, &fb_info->var.upper_margin, diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index e9d930f150cb..1fa0dc66406e 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -74,7 +74,8 @@ static void XGI_SetSeqRegs(struct vb_device_info *pVBInfo) /* Get SR1,2,3,4 from file */ /* SR1 is with screen off 0x20 */ SRdata = XGI330_StandTable.SR[i]; - xgifb_reg_set(pVBInfo->P3c4, i + 1, SRdata); /* Set SR 1 2 3 4 */ + /* Set SR 1 2 3 4 */ + xgifb_reg_set(pVBInfo->P3c4, i + 1, SRdata); } } @@ -628,12 +629,14 @@ static void xgifb_set_lcd(int chip_id, xgifb_reg_and(pVBInfo->P3c4, 0x35, ~0x80); /* Vsync polarity */ temp = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; - if (temp & 0x4000) + if (temp & 0x4000) { /* Hsync polarity */ xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20); - if (temp & 0x8000) + } + if (temp & 0x8000) { /* Vsync polarity */ xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80); + } } /* @@ -1225,9 +1228,10 @@ static void const *XGI_GetLcdPtr(struct XGI330_LCDDataTablStruct const *table, return table[i].DATAPTR; } -static struct SiS_TVData const *XGI_GetTVPtr(unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex, - struct vb_device_info *pVBInfo) +static struct SiS_TVData const *XGI_GetTVPtr( + unsigned short ModeIdIndex, + unsigned short RefreshRateTableIndex, + struct vb_device_info *pVBInfo) { unsigned short i, tempdx, tempal, modeflag; @@ -1480,14 +1484,16 @@ static void XGI_SetLVDSRegs(unsigned short ModeIdIndex, if (tempcx >= tempax) tempcx -= tempax; - xgifb_reg_set(pVBInfo->Part1Port, 0x1b, (unsigned short)(tempbx & 0xff)); - xgifb_reg_set(pVBInfo->Part1Port, 0x1c, (unsigned short)(tempcx & 0xff)); + xgifb_reg_set(pVBInfo->Part1Port, 0x1b, + (unsigned short)(tempbx & 0xff)); + xgifb_reg_set(pVBInfo->Part1Port, 0x1c, + (unsigned short)(tempcx & 0xff)); tempbx = (tempbx >> 8) & 0x07; tempcx = (tempcx >> 8) & 0x07; - xgifb_reg_set(pVBInfo->Part1Port, 0x1d, (unsigned short)((tempcx << 3) | - tempbx)); + xgifb_reg_set(pVBInfo->Part1Port, 0x1d, + (unsigned short)((tempcx << 3) | tempbx)); tempax = pVBInfo->VT; tempbx = LCDPtr1->LCDVRS; @@ -1501,8 +1507,10 @@ static void XGI_SetLVDSRegs(unsigned short ModeIdIndex, if (tempcx >= tempax) tempcx -= tempax; - xgifb_reg_set(pVBInfo->Part1Port, 0x18, (unsigned short)(tempbx & 0xff)); - xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, ~0x0f, (unsigned short)(tempcx & 0x0f)); + xgifb_reg_set(pVBInfo->Part1Port, 0x18, + (unsigned short)(tempbx & 0xff)); + xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, ~0x0f, + (unsigned short)(tempcx & 0x0f)); tempax = ((tempbx >> 8) & 0x07) << 3; @@ -1592,16 +1600,20 @@ static void XGI_SetLVDSRegs(unsigned short ModeIdIndex, tempax = ((tempbx >> 8) & 0xff) << 3; tempax |= (unsigned short)((temp3 >> 8) & 0x07); - xgifb_reg_set(pVBInfo->Part1Port, 0x20, (unsigned short)(tempax & 0xff)); - xgifb_reg_set(pVBInfo->Part1Port, 0x21, (unsigned short)(tempbx & 0xff)); + xgifb_reg_set(pVBInfo->Part1Port, 0x20, + (unsigned short)(tempax & 0xff)); + xgifb_reg_set(pVBInfo->Part1Port, 0x21, + (unsigned short)(tempbx & 0xff)); temp3 >>= 16; if (modeflag & HalfDCLK) temp3 >>= 1; - xgifb_reg_set(pVBInfo->Part1Port, 0x22, (unsigned short)((temp3 >> 8) & 0xff)); - xgifb_reg_set(pVBInfo->Part1Port, 0x23, (unsigned short)(temp3 & 0xff)); + xgifb_reg_set(pVBInfo->Part1Port, 0x22, + (unsigned short)((temp3 >> 8) & 0xff)); + xgifb_reg_set(pVBInfo->Part1Port, 0x23, + (unsigned short)(temp3 & 0xff)); } /* @@ -1760,9 +1772,10 @@ static void XGI_UpdateModeInfo(struct vb_device_info *pVBInfo) temp &= 0x05; - if (!(tempcl & ActiveLCD)) + if (!(tempcl & ActiveLCD)) { if (temp == 0x01) tempcl |= ActiveCRT2; + } if (temp == 0x04) tempcl |= ActiveLCD; @@ -1856,7 +1869,8 @@ finish: pVBInfo->VBType = tempbx; } -static void XGI_GetVBInfo(unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) +static void XGI_GetVBInfo(unsigned short ModeIdIndex, + struct vb_device_info *pVBInfo) { unsigned short tempax, push, tempbx, temp, modeflag; @@ -1981,7 +1995,8 @@ static void XGI_GetVBInfo(unsigned short ModeIdIndex, struct vb_device_info *pVB pVBInfo->VBInfo = tempbx; } -static void XGI_GetTVInfo(unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) +static void XGI_GetTVInfo(unsigned short ModeIdIndex, + struct vb_device_info *pVBInfo) { unsigned short tempbx = 0, resinfo = 0, modeflag, index1; @@ -1998,10 +2013,11 @@ static void XGI_GetTVInfo(unsigned short ModeIdIndex, struct vb_device_info *pVB if (tempbx & TVSetPALM) /* set to NTSC if PAL-M */ tempbx &= ~TVSetPAL; - } else + } else { tempbx &= (SetCHTVOverScan | TVSetNTSCJ | TVSetPAL); + } if (pVBInfo->VBInfo & SetCRT2ToSCART) tempbx |= TVSetPAL; @@ -2026,9 +2042,10 @@ static void XGI_GetTVInfo(unsigned short ModeIdIndex, struct vb_device_info *pVB (!(pVBInfo->VBInfo & SetNotSimuMode))) tempbx |= TVSimuMode; - if (!(tempbx & TVSetPAL) && (modeflag > 13) && (resinfo == 8)) + if (!(tempbx & TVSetPAL) && (modeflag > 13) && (resinfo == 8)) { /* NTSC 1024x768, */ tempbx |= NTSC1024x768; + } tempbx |= RPLLDIV2XO; @@ -2327,9 +2344,10 @@ void XGI_DisplayOff(struct xgifb_video_info *xgifb_info, mdelay(xgifb_info->lvds_data.PSC_S3); } - if (pVBInfo->IF_DEF_LVDS == 0) + if (pVBInfo->IF_DEF_LVDS == 0) { /* DVO/DVI signal off */ XGI_XG27BLSignalVDD(0x20, 0x00, pVBInfo); + } } xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xDF, 0x20); @@ -2688,7 +2706,7 @@ static unsigned short XGI_GetColorDepth(unsigned short ModeIdIndex) static unsigned short XGI_GetOffset(unsigned short ModeNo, unsigned short ModeIdIndex, - unsigned short RefreshRateTableIndex) + unsigned short RefreshRateTableIndex) { unsigned short temp, colordepth, modeinfo, index, infoflag, ColorDepth[] = { 0x01, 0x02, 0x04 }; @@ -3633,7 +3651,8 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, } } -static void XGI_SetLCDRegs(unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) +static void XGI_SetLCDRegs(unsigned short ModeIdIndex, + struct vb_device_info *pVBInfo) { unsigned short pushbx, tempax, tempbx, tempcx, temp, tempah, tempbh, tempch; @@ -4527,8 +4546,10 @@ static unsigned short XGI_GetTVPtrIndex(struct vb_device_info *pVBInfo) * 1 : 301B/302B/301LV/302LV * Description : */ -static void XGI_GetTVPtrIndex2(unsigned short *tempbx, unsigned char *tempcl, - unsigned char *tempch, struct vb_device_info *pVBInfo) +static void XGI_GetTVPtrIndex2(unsigned short *tempbx, + unsigned char *tempcl, + unsigned char *tempch, + struct vb_device_info *pVBInfo) { *tempbx = 0; *tempcl = 0; @@ -4632,13 +4653,14 @@ static void XGI_SetLCDCap_A(unsigned short tempcx, static void XGI_SetLCDCap_B(unsigned short tempcx, struct vb_device_info *pVBInfo) { - if (tempcx & EnableLCD24bpp) /* 24bits */ + if (tempcx & EnableLCD24bpp) { /* 24bits */ xgifb_reg_and_or(pVBInfo->Part2Port, 0x1A, 0xE0, (unsigned short)(((tempcx & 0x00ff) >> 6) | 0x0c)); - else + } else { xgifb_reg_and_or(pVBInfo->Part2Port, 0x1A, 0xE0, (unsigned short)(((tempcx & 0x00ff) >> 6) | 0x18)); /* Enable Dither */ + } } static void XGI_LongWait(struct vb_device_info *pVBInfo) @@ -5461,8 +5483,9 @@ unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info, switch (HwDeviceExtension->ujVBChipID) { case VB_CHIP_301: /* fall through */ case VB_CHIP_302: + /* add for CRT2 */ XGI_SetCRT2Group301(ModeNo, HwDeviceExtension, - pVBInfo); /* add for CRT2 */ + pVBInfo); break; default: diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 0da63e1da32f..42ecf7fe6766 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -2493,7 +2493,7 @@ static const struct XGI301C_Tap4TimingStruct xgifb_ntsc_525_tap4_timing[] = { 0x02, 0x0C, 0x0E, 0x04, 0x01, 0x0B, 0x0E, 0x06, /* ; EA-EF */ 0x01, 0x0B, 0x0E, 0x06, 0x00, 0x0A, 0x0F, 0x07, /* ; F0-F7 */ 0x00, 0x0A, 0x0F, 0x07, 0x00, 0x09, 0x0F, 0x08 /* ; F8-FF */ - } + } } }; @@ -2507,7 +2507,7 @@ static const struct XGI301C_Tap4TimingStruct YPbPr750pTap4Timing[] = { 0x7D, 0x0F, 0x16, 0x7E, 0x7D, 0x0E, 0x17, 0x7E, /* ; EA-EF */ 0x7D, 0x0C, 0x18, 0x7F, 0x7D, 0x0A, 0x18, 0x01, /* ; F0-F7 */ 0x7D, 0x08, 0x19, 0x02, 0x7D, 0x06, 0x19, 0x04 /* F8-FF */ - } + } } }; #endif |