| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Adaptec AAC series RAID controller driver |
|---|
| 3 | 4 | * (c) Copyright 2001 Red Hat Inc. |
|---|
| .. | .. |
|---|
| 9 | 10 | * 2010-2015 PMC-Sierra, Inc. (aacraid@pmc-sierra.com) |
|---|
| 10 | 11 | * 2016-2017 Microsemi Corp. (aacraid@microsemi.com) |
|---|
| 11 | 12 | * |
|---|
| 12 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 13 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 14 | | - * the Free Software Foundation; either version 2, or (at your option) |
|---|
| 15 | | - * any later version. |
|---|
| 16 | | - * |
|---|
| 17 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 18 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 19 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 20 | | - * GNU General Public License for more details. |
|---|
| 21 | | - * |
|---|
| 22 | | - * You should have received a copy of the GNU General Public License |
|---|
| 23 | | - * along with this program; see the file COPYING. If not, write to |
|---|
| 24 | | - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
|---|
| 25 | | - * |
|---|
| 26 | 13 | * Module Name: |
|---|
| 27 | 14 | * commctrl.c |
|---|
| 28 | 15 | * |
|---|
| 29 | 16 | * Abstract: Contains all routines for control of the AFA comm layer |
|---|
| 30 | | - * |
|---|
| 31 | 17 | */ |
|---|
| 32 | 18 | |
|---|
| 33 | 19 | #include <linux/kernel.h> |
|---|
| .. | .. |
|---|
| 39 | 25 | #include <linux/completion.h> |
|---|
| 40 | 26 | #include <linux/dma-mapping.h> |
|---|
| 41 | 27 | #include <linux/blkdev.h> |
|---|
| 28 | +#include <linux/compat.h> |
|---|
| 42 | 29 | #include <linux/delay.h> /* ssleep prototype */ |
|---|
| 43 | 30 | #include <linux/kthread.h> |
|---|
| 44 | | -#include <linux/semaphore.h> |
|---|
| 45 | 31 | #include <linux/uaccess.h> |
|---|
| 46 | 32 | #include <scsi/scsi_host.h> |
|---|
| 47 | 33 | |
|---|
| 48 | 34 | #include "aacraid.h" |
|---|
| 49 | 35 | |
|---|
| 36 | +# define AAC_DEBUG_PREAMBLE KERN_INFO |
|---|
| 37 | +# define AAC_DEBUG_POSTAMBLE |
|---|
| 50 | 38 | /** |
|---|
| 51 | 39 | * ioctl_send_fib - send a FIB from userspace |
|---|
| 52 | 40 | * @dev: adapter is being processed |
|---|
| .. | .. |
|---|
| 55 | 43 | * This routine sends a fib to the adapter on behalf of a user level |
|---|
| 56 | 44 | * program. |
|---|
| 57 | 45 | */ |
|---|
| 58 | | -# define AAC_DEBUG_PREAMBLE KERN_INFO |
|---|
| 59 | | -# define AAC_DEBUG_POSTAMBLE |
|---|
| 60 | | - |
|---|
| 61 | 46 | static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) |
|---|
| 62 | 47 | { |
|---|
| 63 | 48 | struct hw_fib * kfib; |
|---|
| .. | .. |
|---|
| 173 | 158 | |
|---|
| 174 | 159 | /** |
|---|
| 175 | 160 | * open_getadapter_fib - Get the next fib |
|---|
| 161 | + * @dev: adapter is being processed |
|---|
| 162 | + * @arg: arguments to the open call |
|---|
| 176 | 163 | * |
|---|
| 177 | 164 | * This routine will get the next Fib, if available, from the AdapterFibContext |
|---|
| 178 | 165 | * passed in from the user. |
|---|
| 179 | 166 | */ |
|---|
| 180 | | - |
|---|
| 181 | 167 | static int open_getadapter_fib(struct aac_dev * dev, void __user *arg) |
|---|
| 182 | 168 | { |
|---|
| 183 | 169 | struct aac_fib_context * fibctx; |
|---|
| .. | .. |
|---|
| 203 | 189 | /* |
|---|
| 204 | 190 | * Initialize the mutex used to wait for the next AIF. |
|---|
| 205 | 191 | */ |
|---|
| 206 | | - sema_init(&fibctx->wait_sem, 0); |
|---|
| 192 | + init_completion(&fibctx->completion); |
|---|
| 207 | 193 | fibctx->wait = 0; |
|---|
| 208 | 194 | /* |
|---|
| 209 | 195 | * Initialize the fibs and set the count of fibs on |
|---|
| .. | .. |
|---|
| 241 | 227 | return status; |
|---|
| 242 | 228 | } |
|---|
| 243 | 229 | |
|---|
| 230 | +struct compat_fib_ioctl { |
|---|
| 231 | + u32 fibctx; |
|---|
| 232 | + s32 wait; |
|---|
| 233 | + compat_uptr_t fib; |
|---|
| 234 | +}; |
|---|
| 235 | + |
|---|
| 244 | 236 | /** |
|---|
| 245 | 237 | * next_getadapter_fib - get the next fib |
|---|
| 246 | 238 | * @dev: adapter to use |
|---|
| .. | .. |
|---|
| 249 | 241 | * This routine will get the next Fib, if available, from the AdapterFibContext |
|---|
| 250 | 242 | * passed in from the user. |
|---|
| 251 | 243 | */ |
|---|
| 252 | | - |
|---|
| 253 | 244 | static int next_getadapter_fib(struct aac_dev * dev, void __user *arg) |
|---|
| 254 | 245 | { |
|---|
| 255 | 246 | struct fib_ioctl f; |
|---|
| .. | .. |
|---|
| 259 | 250 | struct list_head * entry; |
|---|
| 260 | 251 | unsigned long flags; |
|---|
| 261 | 252 | |
|---|
| 262 | | - if(copy_from_user((void *)&f, arg, sizeof(struct fib_ioctl))) |
|---|
| 263 | | - return -EFAULT; |
|---|
| 253 | + if (in_compat_syscall()) { |
|---|
| 254 | + struct compat_fib_ioctl cf; |
|---|
| 255 | + |
|---|
| 256 | + if (copy_from_user(&cf, arg, sizeof(struct compat_fib_ioctl))) |
|---|
| 257 | + return -EFAULT; |
|---|
| 258 | + |
|---|
| 259 | + f.fibctx = cf.fibctx; |
|---|
| 260 | + f.wait = cf.wait; |
|---|
| 261 | + f.fib = compat_ptr(cf.fib); |
|---|
| 262 | + } else { |
|---|
| 263 | + if (copy_from_user(&f, arg, sizeof(struct fib_ioctl))) |
|---|
| 264 | + return -EFAULT; |
|---|
| 265 | + } |
|---|
| 264 | 266 | /* |
|---|
| 265 | 267 | * Verify that the HANDLE passed in was a valid AdapterFibContext |
|---|
| 266 | 268 | * |
|---|
| .. | .. |
|---|
| 335 | 337 | ssleep(1); |
|---|
| 336 | 338 | } |
|---|
| 337 | 339 | if (f.wait) { |
|---|
| 338 | | - if(down_interruptible(&fibctx->wait_sem) < 0) { |
|---|
| 340 | + if (wait_for_completion_interruptible(&fibctx->completion) < 0) { |
|---|
| 339 | 341 | status = -ERESTARTSYS; |
|---|
| 340 | 342 | } else { |
|---|
| 341 | 343 | /* Lock again and retry */ |
|---|
| .. | .. |
|---|
| 470 | 472 | |
|---|
| 471 | 473 | |
|---|
| 472 | 474 | /** |
|---|
| 473 | | - * |
|---|
| 474 | 475 | * aac_send_raw_scb |
|---|
| 475 | | - * |
|---|
| 476 | + * @dev: adapter is being processed |
|---|
| 477 | + * @arg: arguments to the send call |
|---|
| 476 | 478 | */ |
|---|
| 477 | | - |
|---|
| 478 | 479 | static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) |
|---|
| 479 | 480 | { |
|---|
| 480 | 481 | struct fib* srbfib; |
|---|
| .. | .. |
|---|
| 528 | 529 | goto cleanup; |
|---|
| 529 | 530 | } |
|---|
| 530 | 531 | |
|---|
| 531 | | - user_srbcmd = kmalloc(fibsize, GFP_KERNEL); |
|---|
| 532 | | - if (!user_srbcmd) { |
|---|
| 533 | | - dprintk((KERN_DEBUG"aacraid: Could not make a copy of the srb\n")); |
|---|
| 534 | | - rcode = -ENOMEM; |
|---|
| 535 | | - goto cleanup; |
|---|
| 536 | | - } |
|---|
| 537 | | - if(copy_from_user(user_srbcmd, user_srb,fibsize)){ |
|---|
| 538 | | - dprintk((KERN_DEBUG"aacraid: Could not copy srb from user\n")); |
|---|
| 539 | | - rcode = -EFAULT; |
|---|
| 532 | + user_srbcmd = memdup_user(user_srb, fibsize); |
|---|
| 533 | + if (IS_ERR(user_srbcmd)) { |
|---|
| 534 | + rcode = PTR_ERR(user_srbcmd); |
|---|
| 535 | + user_srbcmd = NULL; |
|---|
| 540 | 536 | goto cleanup; |
|---|
| 541 | 537 | } |
|---|
| 542 | 538 | |
|---|
| .. | .. |
|---|
| 692 | 688 | goto cleanup; |
|---|
| 693 | 689 | } |
|---|
| 694 | 690 | } |
|---|
| 695 | | - addr = pci_map_single(dev->pdev, p, sg_count[i], |
|---|
| 696 | | - data_dir); |
|---|
| 691 | + addr = dma_map_single(&dev->pdev->dev, p, sg_count[i], |
|---|
| 692 | + data_dir); |
|---|
| 697 | 693 | hbacmd->sge[i].addr_hi = cpu_to_le32((u32)(addr>>32)); |
|---|
| 698 | 694 | hbacmd->sge[i].addr_lo = cpu_to_le32( |
|---|
| 699 | 695 | (u32)(addr & 0xffffffff)); |
|---|
| .. | .. |
|---|
| 754 | 750 | goto cleanup; |
|---|
| 755 | 751 | } |
|---|
| 756 | 752 | } |
|---|
| 757 | | - addr = pci_map_single(dev->pdev, p, |
|---|
| 758 | | - sg_count[i], data_dir); |
|---|
| 753 | + addr = dma_map_single(&dev->pdev->dev, p, |
|---|
| 754 | + sg_count[i], data_dir); |
|---|
| 759 | 755 | |
|---|
| 760 | 756 | psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff); |
|---|
| 761 | 757 | psg->sg[i].addr[1] = cpu_to_le32(addr>>32); |
|---|
| .. | .. |
|---|
| 810 | 806 | goto cleanup; |
|---|
| 811 | 807 | } |
|---|
| 812 | 808 | } |
|---|
| 813 | | - addr = pci_map_single(dev->pdev, p, |
|---|
| 814 | | - sg_count[i], data_dir); |
|---|
| 809 | + addr = dma_map_single(&dev->pdev->dev, p, |
|---|
| 810 | + sg_count[i], data_dir); |
|---|
| 815 | 811 | |
|---|
| 816 | 812 | psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff); |
|---|
| 817 | 813 | psg->sg[i].addr[1] = cpu_to_le32(addr>>32); |
|---|
| .. | .. |
|---|
| 866 | 862 | goto cleanup; |
|---|
| 867 | 863 | } |
|---|
| 868 | 864 | } |
|---|
| 869 | | - addr = pci_map_single(dev->pdev, p, usg->sg[i].count, data_dir); |
|---|
| 865 | + addr = dma_map_single(&dev->pdev->dev, p, |
|---|
| 866 | + usg->sg[i].count, |
|---|
| 867 | + data_dir); |
|---|
| 870 | 868 | |
|---|
| 871 | 869 | psg->sg[i].addr = cpu_to_le32(addr & 0xffffffff); |
|---|
| 872 | 870 | byte_count += usg->sg[i].count; |
|---|
| .. | .. |
|---|
| 905 | 903 | goto cleanup; |
|---|
| 906 | 904 | } |
|---|
| 907 | 905 | } |
|---|
| 908 | | - addr = pci_map_single(dev->pdev, p, |
|---|
| 909 | | - sg_count[i], data_dir); |
|---|
| 906 | + addr = dma_map_single(&dev->pdev->dev, p, |
|---|
| 907 | + sg_count[i], data_dir); |
|---|
| 910 | 908 | |
|---|
| 911 | 909 | psg->sg[i].addr = cpu_to_le32(addr); |
|---|
| 912 | 910 | byte_count += sg_count[i]; |
|---|
| .. | .. |
|---|
| 1061 | 1059 | return retval; |
|---|
| 1062 | 1060 | } |
|---|
| 1063 | 1061 | |
|---|
| 1064 | | -int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg) |
|---|
| 1062 | +int aac_do_ioctl(struct aac_dev *dev, unsigned int cmd, void __user *arg) |
|---|
| 1065 | 1063 | { |
|---|
| 1066 | 1064 | int status; |
|---|
| 1067 | 1065 | |
|---|