^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Adaptec AAC series RAID controller driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * (c) Copyright 2001 Red Hat Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * based on the old aacraid driver that is..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Adaptec aacraid device driver for Linux.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (c) 2000-2010 Adaptec, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * 2010-2015 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * 2016-2017 Microsemi Corp. (aacraid@microsemi.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Module Name:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * commctrl.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Abstract: Contains all routines for control of the AFA comm layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/delay.h> /* ssleep prototype */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/kthread.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include "aacraid.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) # define AAC_DEBUG_PREAMBLE KERN_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) # define AAC_DEBUG_POSTAMBLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * ioctl_send_fib - send a FIB from userspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * @dev: adapter is being processed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * @arg: arguments to the ioctl call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * This routine sends a fib to the adapter on behalf of a user level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * program.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static int ioctl_send_fib(struct aac_dev * dev, void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct hw_fib * kfib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct fib *fibptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct hw_fib * hw_fib = (struct hw_fib *)0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) dma_addr_t hw_fib_pa = (dma_addr_t)0LL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) unsigned int size, osize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (dev->in_reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) fibptr = aac_fib_alloc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if(fibptr == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) kfib = fibptr->hw_fib_va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * First copy in the header so that we can check the size field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (copy_from_user((void *)kfib, arg, sizeof(struct aac_fibhdr))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) aac_fib_free(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * Since we copy based on the fib header size, make sure that we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * will not overrun the buffer when we copy the memory. Return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * an error if we would.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) osize = size = le16_to_cpu(kfib->header.Size) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) sizeof(struct aac_fibhdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (size < le16_to_cpu(kfib->header.SenderSize))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) size = le16_to_cpu(kfib->header.SenderSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (size > dev->max_fib_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) dma_addr_t daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (size > 2048) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) retval = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) kfib = dma_alloc_coherent(&dev->pdev->dev, size, &daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (!kfib) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) retval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /* Highjack the hw_fib */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) hw_fib = fibptr->hw_fib_va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) hw_fib_pa = fibptr->hw_fib_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) fibptr->hw_fib_va = kfib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) fibptr->hw_fib_pa = daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) memset(((char *)kfib) + dev->max_fib_size, 0, size - dev->max_fib_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) memcpy(kfib, hw_fib, dev->max_fib_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (copy_from_user(kfib, arg, size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) retval = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /* Sanity check the second copy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if ((osize != le16_to_cpu(kfib->header.Size) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) sizeof(struct aac_fibhdr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) || (size < le16_to_cpu(kfib->header.SenderSize))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) retval = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (kfib->header.Command == cpu_to_le16(TakeABreakPt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) aac_adapter_interrupt(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * Since we didn't really send a fib, zero out the state to allow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * cleanup code not to assert.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) kfib->header.XferState = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) retval = aac_fib_send(le16_to_cpu(kfib->header.Command), fibptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) le16_to_cpu(kfib->header.Size) , FsaNormal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 1, 1, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (aac_fib_complete(fibptr) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) retval = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * Make sure that the size returned by the adapter (which includes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * the header) is less than or equal to the size of a fib, so we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * don't corrupt application data. Then copy that size to the user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * buffer. (Don't try to add the header information again, since it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * was already included by the adapter.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (copy_to_user(arg, (void *)kfib, size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) retval = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (hw_fib) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) dma_free_coherent(&dev->pdev->dev, size, kfib,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) fibptr->hw_fib_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) fibptr->hw_fib_pa = hw_fib_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) fibptr->hw_fib_va = hw_fib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (retval != -ERESTARTSYS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) aac_fib_free(fibptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * open_getadapter_fib - Get the next fib
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * @dev: adapter is being processed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * @arg: arguments to the open call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * This routine will get the next Fib, if available, from the AdapterFibContext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * passed in from the user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static int open_getadapter_fib(struct aac_dev * dev, void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct aac_fib_context * fibctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) fibctx = kmalloc(sizeof(struct aac_fib_context), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (fibctx == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) status = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) struct list_head * entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct aac_fib_context * context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) fibctx->type = FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) fibctx->size = sizeof(struct aac_fib_context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * Yes yes, I know this could be an index, but we have a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * better guarantee of uniqueness for the locked loop below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * Without the aid of a persistent history, this also helps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * reduce the chance that the opaque context would be reused.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) fibctx->unique = (u32)((ulong)fibctx & 0xFFFFFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * Initialize the mutex used to wait for the next AIF.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) init_completion(&fibctx->completion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) fibctx->wait = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * Initialize the fibs and set the count of fibs on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * the list to 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) fibctx->count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) INIT_LIST_HEAD(&fibctx->fib_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) fibctx->jiffies = jiffies/HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * Now add this context onto the adapter's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * AdapterFibContext list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) spin_lock_irqsave(&dev->fib_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /* Ensure that we have a unique identifier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) entry = dev->fib_list.next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) while (entry != &dev->fib_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) context = list_entry(entry, struct aac_fib_context, next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (context->unique == fibctx->unique) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* Not unique (32 bits) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) fibctx->unique++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) entry = dev->fib_list.next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) entry = entry->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) list_add_tail(&fibctx->next, &dev->fib_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) spin_unlock_irqrestore(&dev->fib_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (copy_to_user(arg, &fibctx->unique,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) sizeof(fibctx->unique))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) status = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) struct compat_fib_ioctl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) u32 fibctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) s32 wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) compat_uptr_t fib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * next_getadapter_fib - get the next fib
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * @dev: adapter to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * @arg: ioctl argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * This routine will get the next Fib, if available, from the AdapterFibContext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * passed in from the user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static int next_getadapter_fib(struct aac_dev * dev, void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct fib_ioctl f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) struct fib *fib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) struct aac_fib_context *fibctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct list_head * entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (in_compat_syscall()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct compat_fib_ioctl cf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (copy_from_user(&cf, arg, sizeof(struct compat_fib_ioctl)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) f.fibctx = cf.fibctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) f.wait = cf.wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) f.fib = compat_ptr(cf.fib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (copy_from_user(&f, arg, sizeof(struct fib_ioctl)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * Verify that the HANDLE passed in was a valid AdapterFibContext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * Search the list of AdapterFibContext addresses on the adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * to be sure this is a valid address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) spin_lock_irqsave(&dev->fib_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) entry = dev->fib_list.next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) fibctx = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) while (entry != &dev->fib_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) fibctx = list_entry(entry, struct aac_fib_context, next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * Extract the AdapterFibContext from the Input parameters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (fibctx->unique == f.fibctx) { /* We found a winner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) entry = entry->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) fibctx = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (!fibctx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) spin_unlock_irqrestore(&dev->fib_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) dprintk ((KERN_INFO "Fib Context not found\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) (fibctx->size != sizeof(struct aac_fib_context))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) spin_unlock_irqrestore(&dev->fib_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) dprintk ((KERN_INFO "Fib Context corrupt?\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * If there are no fibs to send back, then either wait or return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * -EAGAIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return_fib:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (!list_empty(&fibctx->fib_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * Pull the next fib from the fibs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) entry = fibctx->fib_list.next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) list_del(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) fib = list_entry(entry, struct fib, fiblink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) fibctx->count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) spin_unlock_irqrestore(&dev->fib_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (copy_to_user(f.fib, fib->hw_fib_va, sizeof(struct hw_fib))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) kfree(fib->hw_fib_va);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) kfree(fib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * Free the space occupied by this copy of the fib.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) kfree(fib->hw_fib_va);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) kfree(fib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) spin_unlock_irqrestore(&dev->fib_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) /* If someone killed the AIF aacraid thread, restart it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) status = !dev->aif_thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) if (status && !dev->in_reset && dev->queues && dev->fsa_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) /* Be paranoid, be very paranoid! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) kthread_stop(dev->thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) ssleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) dev->aif_thread = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) dev->thread = kthread_run(aac_command_thread, dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) "%s", dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) ssleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (f.wait) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (wait_for_completion_interruptible(&fibctx->completion) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) status = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /* Lock again and retry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) spin_lock_irqsave(&dev->fib_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) goto return_fib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) status = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) fibctx->jiffies = jiffies/HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context * fibctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) struct fib *fib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * First free any FIBs that have not been consumed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) while (!list_empty(&fibctx->fib_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) struct list_head * entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * Pull the next fib from the fibs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) entry = fibctx->fib_list.next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) list_del(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) fib = list_entry(entry, struct fib, fiblink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) fibctx->count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) * Free the space occupied by this copy of the fib.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) kfree(fib->hw_fib_va);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) kfree(fib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * Remove the Context from the AdapterFibContext List
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) list_del(&fibctx->next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) * Invalidate context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) fibctx->type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * Free the space occupied by the Context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) kfree(fibctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * close_getadapter_fib - close down user fib context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * @dev: adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * @arg: ioctl arguments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * This routine will close down the fibctx passed in from the user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) static int close_getadapter_fib(struct aac_dev * dev, void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) struct aac_fib_context *fibctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct list_head * entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * Verify that the HANDLE passed in was a valid AdapterFibContext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * Search the list of AdapterFibContext addresses on the adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) * to be sure this is a valid address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) entry = dev->fib_list.next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) fibctx = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) while(entry != &dev->fib_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) fibctx = list_entry(entry, struct aac_fib_context, next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * Extract the fibctx from the input parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (fibctx->unique == (u32)(uintptr_t)arg) /* We found a winner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) entry = entry->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) fibctx = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (!fibctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return 0; /* Already gone */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) (fibctx->size != sizeof(struct aac_fib_context)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) spin_lock_irqsave(&dev->fib_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) status = aac_close_fib_context(dev, fibctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) spin_unlock_irqrestore(&dev->fib_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) * check_revision - close down user fib context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) * @dev: adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) * @arg: ioctl arguments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) * This routine returns the driver version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) * Under Linux, there have been no version incompatibilities, so this is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) * simple!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) static int check_revision(struct aac_dev *dev, void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) struct revision response;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) char *driver_version = aac_driver_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) u32 version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) response.compat = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) version = (simple_strtol(driver_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) &driver_version, 10) << 24) | 0x00000400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) version += simple_strtol(driver_version + 1, &driver_version, 10) << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) version += simple_strtol(driver_version + 1, NULL, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) response.version = cpu_to_le32(version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) # ifdef AAC_DRIVER_BUILD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) response.build = cpu_to_le32(AAC_DRIVER_BUILD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) # else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) response.build = cpu_to_le32(9999);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) # endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (copy_to_user(arg, &response, sizeof(response)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) * aac_send_raw_scb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) * @dev: adapter is being processed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) * @arg: arguments to the send call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) struct fib* srbfib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct aac_srb *srbcmd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct aac_hba_cmd_req *hbacmd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) struct user_aac_srb *user_srbcmd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct user_aac_srb __user *user_srb = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) struct aac_srb_reply __user *user_reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) u32 chn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) u32 fibsize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) u32 flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) s32 rcode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) u32 data_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) void __user *sg_user[HBA_MAX_SG_EMBEDDED];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) void *sg_list[HBA_MAX_SG_EMBEDDED];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) u32 sg_count[HBA_MAX_SG_EMBEDDED];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) u32 sg_indx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) u32 byte_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) u32 actual_fibsize64, actual_fibsize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) int is_native_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) u64 address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (dev->in_reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) dprintk((KERN_DEBUG"aacraid: send raw srb -EBUSY\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (!capable(CAP_SYS_ADMIN)){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) dprintk((KERN_DEBUG"aacraid: No permission to send raw srb\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) * Allocate and initialize a Fib then setup a SRB command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (!(srbfib = aac_fib_alloc(dev))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) memset(sg_list, 0, sizeof(sg_list)); /* cleanup may take issue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if(copy_from_user(&fibsize, &user_srb->count,sizeof(u32))){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) dprintk((KERN_DEBUG"aacraid: Could not copy data size from user\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) rcode = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if ((fibsize < (sizeof(struct user_aac_srb) - sizeof(struct user_sgentry))) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) rcode = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) user_srbcmd = memdup_user(user_srb, fibsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (IS_ERR(user_srbcmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) rcode = PTR_ERR(user_srbcmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) user_srbcmd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) flags = user_srbcmd->flags; /* from user in cpu order */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) switch (flags & (SRB_DataIn | SRB_DataOut)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) case SRB_DataOut:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) data_dir = DMA_TO_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) case (SRB_DataIn | SRB_DataOut):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) data_dir = DMA_BIDIRECTIONAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) case SRB_DataIn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) data_dir = DMA_FROM_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) data_dir = DMA_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (user_srbcmd->sg.count > ARRAY_SIZE(sg_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) dprintk((KERN_DEBUG"aacraid: too many sg entries %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) user_srbcmd->sg.count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) rcode = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if ((data_dir == DMA_NONE) && user_srbcmd->sg.count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) dprintk((KERN_DEBUG"aacraid:SG with no direction specified\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) rcode = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) actual_fibsize = sizeof(struct aac_srb) - sizeof(struct sgentry) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) ((user_srbcmd->sg.count & 0xff) * sizeof(struct sgentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) actual_fibsize64 = actual_fibsize + (user_srbcmd->sg.count & 0xff) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) (sizeof(struct sgentry64) - sizeof(struct sgentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) /* User made a mistake - should not continue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) if ((actual_fibsize != fibsize) && (actual_fibsize64 != fibsize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) dprintk((KERN_DEBUG"aacraid: Bad Size specified in "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) "Raw SRB command calculated fibsize=%lu;%lu "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) "user_srbcmd->sg.count=%d aac_srb=%lu sgentry=%lu;%lu "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) "issued fibsize=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) actual_fibsize, actual_fibsize64, user_srbcmd->sg.count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) sizeof(struct aac_srb), sizeof(struct sgentry),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) sizeof(struct sgentry64), fibsize));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) rcode = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) chn = user_srbcmd->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (chn < AAC_MAX_BUSES && user_srbcmd->id < AAC_MAX_TARGETS &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) dev->hba_map[chn][user_srbcmd->id].devtype ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) AAC_DEVTYPE_NATIVE_RAW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) is_native_device = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) hbacmd = (struct aac_hba_cmd_req *)srbfib->hw_fib_va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) memset(hbacmd, 0, 96); /* sizeof(*hbacmd) is not necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) /* iu_type is a parameter of aac_hba_send */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) switch (data_dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) case DMA_TO_DEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) hbacmd->byte1 = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) case DMA_FROM_DEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) case DMA_BIDIRECTIONAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) hbacmd->byte1 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) case DMA_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) hbacmd->lun[1] = cpu_to_le32(user_srbcmd->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) hbacmd->it_nexus = dev->hba_map[chn][user_srbcmd->id].rmw_nexus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) * we fill in reply_qid later in aac_src_deliver_message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) * we fill in iu_type, request_id later in aac_hba_send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) * we fill in emb_data_desc_count, data_length later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) * in sg list build
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) memcpy(hbacmd->cdb, user_srbcmd->cdb, sizeof(hbacmd->cdb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) address = (u64)srbfib->hw_error_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) hbacmd->error_ptr_hi = cpu_to_le32((u32)(address >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) hbacmd->error_ptr_lo = cpu_to_le32((u32)(address & 0xffffffff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) hbacmd->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) hbacmd->emb_data_desc_count =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) cpu_to_le32(user_srbcmd->sg.count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) srbfib->hbacmd_size = 64 +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) user_srbcmd->sg.count * sizeof(struct aac_hba_sgl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) is_native_device = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) aac_fib_init(srbfib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) /* raw_srb FIB is not FastResponseCapable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) srbfib->hw_fib_va->header.XferState &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) ~cpu_to_le32(FastResponseCapable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) srbcmd = (struct aac_srb *) fib_data(srbfib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) // Fix up srb for endian and force some values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); // Force this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) srbcmd->channel = cpu_to_le32(user_srbcmd->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) srbcmd->id = cpu_to_le32(user_srbcmd->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) srbcmd->lun = cpu_to_le32(user_srbcmd->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) srbcmd->timeout = cpu_to_le32(user_srbcmd->timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) srbcmd->flags = cpu_to_le32(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) srbcmd->retry_limit = 0; // Obsolete parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) srbcmd->cdb_size = cpu_to_le32(user_srbcmd->cdb_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) memcpy(srbcmd->cdb, user_srbcmd->cdb, sizeof(srbcmd->cdb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) byte_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (is_native_device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) struct user_sgmap *usg32 = &user_srbcmd->sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) struct user_sgmap64 *usg64 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) (struct user_sgmap64 *)&user_srbcmd->sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) for (i = 0; i < usg32->count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) void *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) u64 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) sg_count[i] = (actual_fibsize64 == fibsize) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) usg64->sg[i].count : usg32->sg[i].count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) if (sg_count[i] >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) (dev->scsi_host_ptr->max_sectors << 9)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) pr_err("aacraid: upsg->sg[%d].count=%u>%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) i, sg_count[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) dev->scsi_host_ptr->max_sectors << 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) rcode = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) p = kmalloc(sg_count[i], GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (!p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) rcode = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if (actual_fibsize64 == fibsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) addr = (u64)usg64->sg[i].addr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) addr += ((u64)usg64->sg[i].addr[1]) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) addr = (u64)usg32->sg[i].addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) sg_user[i] = (void __user *)(uintptr_t)addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) sg_list[i] = p; // save so we can clean up later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) sg_indx = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (flags & SRB_DataOut) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (copy_from_user(p, sg_user[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) sg_count[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) rcode = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) addr = dma_map_single(&dev->pdev->dev, p, sg_count[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) data_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) hbacmd->sge[i].addr_hi = cpu_to_le32((u32)(addr>>32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) hbacmd->sge[i].addr_lo = cpu_to_le32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) (u32)(addr & 0xffffffff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) hbacmd->sge[i].len = cpu_to_le32(sg_count[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) hbacmd->sge[i].flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) byte_count += sg_count[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) if (usg32->count > 0) /* embedded sglist */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) hbacmd->sge[usg32->count-1].flags =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) cpu_to_le32(0x40000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) hbacmd->data_length = cpu_to_le32(byte_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) status = aac_hba_send(HBA_IU_TYPE_SCSI_CMD_REQ, srbfib,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) } else if (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) struct user_sgmap64* upsg = (struct user_sgmap64*)&user_srbcmd->sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) struct sgmap64* psg = (struct sgmap64*)&srbcmd->sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) * This should also catch if user used the 32 bit sgmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (actual_fibsize64 == fibsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) actual_fibsize = actual_fibsize64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) for (i = 0; i < upsg->count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) u64 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) void* p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) sg_count[i] = upsg->sg[i].count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (sg_count[i] >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) ((dev->adapter_info.options &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) AAC_OPT_NEW_COMM) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) (dev->scsi_host_ptr->max_sectors << 9) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 65536)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) rcode = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) p = kmalloc(sg_count[i], GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if(!p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) sg_count[i], i, upsg->count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) rcode = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) addr = (u64)upsg->sg[i].addr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) addr += ((u64)upsg->sg[i].addr[1]) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) sg_user[i] = (void __user *)(uintptr_t)addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) sg_list[i] = p; // save so we can clean up later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) sg_indx = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if (flags & SRB_DataOut) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (copy_from_user(p, sg_user[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) sg_count[i])){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) rcode = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) addr = dma_map_single(&dev->pdev->dev, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) sg_count[i], data_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) psg->sg[i].addr[1] = cpu_to_le32(addr>>32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) byte_count += sg_count[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) psg->sg[i].count = cpu_to_le32(sg_count[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) struct user_sgmap* usg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) usg = kmemdup(upsg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) actual_fibsize - sizeof(struct aac_srb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) + sizeof(struct sgmap), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (!usg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) dprintk((KERN_DEBUG"aacraid: Allocation error in Raw SRB command\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) rcode = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) actual_fibsize = actual_fibsize64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) for (i = 0; i < usg->count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) u64 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) void* p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) sg_count[i] = usg->sg[i].count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (sg_count[i] >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) ((dev->adapter_info.options &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) AAC_OPT_NEW_COMM) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) (dev->scsi_host_ptr->max_sectors << 9) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 65536)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) kfree(usg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) rcode = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) p = kmalloc(sg_count[i], GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) if(!p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) dprintk((KERN_DEBUG "aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) sg_count[i], i, usg->count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) kfree(usg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) rcode = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) sg_user[i] = (void __user *)(uintptr_t)usg->sg[i].addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) sg_list[i] = p; // save so we can clean up later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) sg_indx = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) if (flags & SRB_DataOut) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (copy_from_user(p, sg_user[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) sg_count[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) kfree (usg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) rcode = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) addr = dma_map_single(&dev->pdev->dev, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) sg_count[i], data_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) psg->sg[i].addr[1] = cpu_to_le32(addr>>32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) byte_count += sg_count[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) psg->sg[i].count = cpu_to_le32(sg_count[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) kfree (usg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) srbcmd->count = cpu_to_le32(byte_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (user_srbcmd->sg.count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) psg->count = cpu_to_le32(sg_indx+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) psg->count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) status = aac_fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,NULL,NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) struct user_sgmap* upsg = &user_srbcmd->sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) struct sgmap* psg = &srbcmd->sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) if (actual_fibsize64 == fibsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) struct user_sgmap64* usg = (struct user_sgmap64 *)upsg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) for (i = 0; i < upsg->count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) uintptr_t addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) void* p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) sg_count[i] = usg->sg[i].count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) if (sg_count[i] >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) ((dev->adapter_info.options &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) AAC_OPT_NEW_COMM) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) (dev->scsi_host_ptr->max_sectors << 9) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 65536)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) rcode = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) p = kmalloc(sg_count[i], GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (!p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) sg_count[i], i, usg->count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) rcode = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) addr = (u64)usg->sg[i].addr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) addr += ((u64)usg->sg[i].addr[1]) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) sg_user[i] = (void __user *)addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) sg_list[i] = p; // save so we can clean up later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) sg_indx = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) if (flags & SRB_DataOut) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) if (copy_from_user(p, sg_user[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) sg_count[i])){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) rcode = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) addr = dma_map_single(&dev->pdev->dev, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) usg->sg[i].count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) data_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) psg->sg[i].addr = cpu_to_le32(addr & 0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) byte_count += usg->sg[i].count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) psg->sg[i].count = cpu_to_le32(sg_count[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) for (i = 0; i < upsg->count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) dma_addr_t addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) void* p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) sg_count[i] = upsg->sg[i].count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (sg_count[i] >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) ((dev->adapter_info.options &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) AAC_OPT_NEW_COMM) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) (dev->scsi_host_ptr->max_sectors << 9) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) 65536)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) rcode = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) p = kmalloc(sg_count[i], GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) if (!p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) sg_count[i], i, upsg->count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) rcode = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) sg_user[i] = (void __user *)(uintptr_t)upsg->sg[i].addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) sg_list[i] = p; // save so we can clean up later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) sg_indx = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) if (flags & SRB_DataOut) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) if (copy_from_user(p, sg_user[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) sg_count[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) rcode = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) addr = dma_map_single(&dev->pdev->dev, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) sg_count[i], data_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) psg->sg[i].addr = cpu_to_le32(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) byte_count += sg_count[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) psg->sg[i].count = cpu_to_le32(sg_count[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) srbcmd->count = cpu_to_le32(byte_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) if (user_srbcmd->sg.count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) psg->count = cpu_to_le32(sg_indx+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) psg->count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) status = aac_fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (status == -ERESTARTSYS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) rcode = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (status != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) dprintk((KERN_DEBUG"aacraid: Could not send raw srb fib to hba\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) rcode = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) if (flags & SRB_DataIn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) for(i = 0 ; i <= sg_indx; i++){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) if (copy_to_user(sg_user[i], sg_list[i], sg_count[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) dprintk((KERN_DEBUG"aacraid: Could not copy sg data to user\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) rcode = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) user_reply = arg + fibsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if (is_native_device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) struct aac_hba_resp *err =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) &((struct aac_native_hba *)srbfib->hw_fib_va)->resp.err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) struct aac_srb_reply reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) memset(&reply, 0, sizeof(reply));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) reply.status = ST_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (srbfib->flags & FIB_CONTEXT_FLAG_FASTRESP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) /* fast response */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) reply.srb_status = SRB_STATUS_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) reply.scsi_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) reply.data_xfer_length = byte_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) reply.sense_data_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) memset(reply.sense_data, 0, AAC_SENSE_BUFFERSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) reply.srb_status = err->service_response;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) reply.scsi_status = err->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) reply.data_xfer_length = byte_count -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) le32_to_cpu(err->residual_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) reply.sense_data_size = err->sense_response_data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) memcpy(reply.sense_data, err->sense_response_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) AAC_SENSE_BUFFERSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) if (copy_to_user(user_reply, &reply,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) sizeof(struct aac_srb_reply))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) dprintk((KERN_DEBUG"aacraid: Copy to user failed\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) rcode = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) struct aac_srb_reply *reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) reply = (struct aac_srb_reply *) fib_data(srbfib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) if (copy_to_user(user_reply, reply,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) sizeof(struct aac_srb_reply))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) dprintk((KERN_DEBUG"aacraid: Copy to user failed\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) rcode = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) kfree(user_srbcmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) if (rcode != -ERESTARTSYS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) for (i = 0; i <= sg_indx; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) kfree(sg_list[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) aac_fib_complete(srbfib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) aac_fib_free(srbfib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) return rcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) struct aac_pci_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) u32 bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) u32 slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) static int aac_get_pci_info(struct aac_dev* dev, void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) struct aac_pci_info pci_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) pci_info.bus = dev->pdev->bus->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) pci_info.slot = PCI_SLOT(dev->pdev->devfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) if (copy_to_user(arg, &pci_info, sizeof(struct aac_pci_info))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) dprintk((KERN_DEBUG "aacraid: Could not copy pci info\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) static int aac_get_hba_info(struct aac_dev *dev, void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) struct aac_hba_info hbainfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) memset(&hbainfo, 0, sizeof(hbainfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) hbainfo.adapter_number = (u8) dev->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) hbainfo.system_io_bus_number = dev->pdev->bus->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) hbainfo.device_number = (dev->pdev->devfn >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) hbainfo.function_number = (dev->pdev->devfn & 0x0007);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) hbainfo.vendor_id = dev->pdev->vendor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) hbainfo.device_id = dev->pdev->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) hbainfo.sub_vendor_id = dev->pdev->subsystem_vendor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) hbainfo.sub_system_id = dev->pdev->subsystem_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) if (copy_to_user(arg, &hbainfo, sizeof(struct aac_hba_info))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) dprintk((KERN_DEBUG "aacraid: Could not copy hba info\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) struct aac_reset_iop {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) u8 reset_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) static int aac_send_reset_adapter(struct aac_dev *dev, void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) struct aac_reset_iop reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) if (copy_from_user((void *)&reset, arg, sizeof(struct aac_reset_iop)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) dev->adapter_shutdown = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) mutex_unlock(&dev->ioctl_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) retval = aac_reset_adapter(dev, 0, reset.reset_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) mutex_lock(&dev->ioctl_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) int aac_do_ioctl(struct aac_dev *dev, unsigned int cmd, void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) mutex_lock(&dev->ioctl_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) if (dev->adapter_shutdown) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) status = -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) * HBA gets first crack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) status = aac_dev_ioctl(dev, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) if (status != -ENOTTY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) case FSACTL_MINIPORT_REV_CHECK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) status = check_revision(dev, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) case FSACTL_SEND_LARGE_FIB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) case FSACTL_SENDFIB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) status = ioctl_send_fib(dev, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) case FSACTL_OPEN_GET_ADAPTER_FIB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) status = open_getadapter_fib(dev, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) case FSACTL_GET_NEXT_ADAPTER_FIB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) status = next_getadapter_fib(dev, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) case FSACTL_CLOSE_GET_ADAPTER_FIB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) status = close_getadapter_fib(dev, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) case FSACTL_SEND_RAW_SRB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) status = aac_send_raw_srb(dev,arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) case FSACTL_GET_PCI_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) status = aac_get_pci_info(dev,arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) case FSACTL_GET_HBA_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) status = aac_get_hba_info(dev, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) case FSACTL_RESET_IOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) status = aac_send_reset_adapter(dev, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) status = -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) mutex_unlock(&dev->ioctl_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)