^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * linux/drivers/message/fusion/mptctl.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * mpt Ioctl driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * For use with LSI PCI chip/adapters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * running LSI Fusion MPT (Message Passing Technology) firmware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (c) 1999-2008 LSI Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * (mailto:DL-MPTFusionLinux@lsi.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) This program is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) it under the terms of the GNU General Public License as published by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) the Free Software Foundation; version 2 of the License.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) This program is distributed in the hope that it will be useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) but WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) GNU General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) NO WARRANTY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) solely responsible for determining the appropriateness of using and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) distributing the Program and assumes all risks associated with its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) exercise of rights under this Agreement, including but not limited to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) the risks and costs of program errors, damage to or loss of data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) programs or equipment, and unavailability or interruption of operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) DISCLAIMER OF LIABILITY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) You should have received a copy of the GNU General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) along with this program; if not, write to the Free Software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include <linux/delay.h> /* for mdelay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #include <linux/miscdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #include <linux/compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #include <scsi/scsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #include <scsi/scsi_cmnd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #include <scsi/scsi_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #include <scsi/scsi_tcq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define COPYRIGHT "Copyright (c) 1999-2008 LSI Corporation"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define MODULEAUTHOR "LSI Corporation"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #include "mptbase.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #include "mptctl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define my_NAME "Fusion MPT misc device (ioctl) driver"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define my_VERSION MPT_LINUX_VERSION_COMMON
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define MYNAM "mptctl"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) MODULE_AUTHOR(MODULEAUTHOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) MODULE_DESCRIPTION(my_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) MODULE_VERSION(my_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static DEFINE_MUTEX(mpctl_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static u8 mptctl_id = MPT_MAX_PROTOCOL_DRIVERS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static u8 mptctl_taskmgmt_id = MPT_MAX_PROTOCOL_DRIVERS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static DECLARE_WAIT_QUEUE_HEAD ( mptctl_wait );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct buflist {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) u8 *kptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * Function prototypes. Called from OS entry point mptctl_ioctl.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * arg contents specific to function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static int mptctl_fw_download(MPT_ADAPTER *iocp, unsigned long arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static int mptctl_getiocinfo(MPT_ADAPTER *iocp, unsigned long arg, unsigned int cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static int mptctl_gettargetinfo(MPT_ADAPTER *iocp, unsigned long arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static int mptctl_readtest(MPT_ADAPTER *iocp, unsigned long arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static int mptctl_mpt_command(MPT_ADAPTER *iocp, unsigned long arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static int mptctl_eventquery(MPT_ADAPTER *iocp, unsigned long arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static int mptctl_eventenable(MPT_ADAPTER *iocp, unsigned long arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static int mptctl_eventreport(MPT_ADAPTER *iocp, unsigned long arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static int mptctl_replace_fw(MPT_ADAPTER *iocp, unsigned long arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static int mptctl_do_reset(MPT_ADAPTER *iocp, unsigned long arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static int mptctl_hp_hostinfo(MPT_ADAPTER *iocp, unsigned long arg, unsigned int cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static int mptctl_hp_targetinfo(MPT_ADAPTER *iocp, unsigned long arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static int mptctl_probe(struct pci_dev *, const struct pci_device_id *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static void mptctl_remove(struct pci_dev *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static long compat_mpctl_ioctl(struct file *f, unsigned cmd, unsigned long arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * Private function calls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static int mptctl_do_mpt_command(MPT_ADAPTER *iocp, struct mpt_ioctl_command karg, void __user *mfPtr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static int mptctl_do_fw_download(MPT_ADAPTER *iocp, char __user *ufwbuf, size_t fwlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static MptSge_t *kbuf_alloc_2_sgl(int bytes, u32 dir, int sge_offset, int *frags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static void kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct buflist *buflist, MPT_ADAPTER *ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * Reset Handler cleanup function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static int mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * Event Handler function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static int mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static struct fasync_struct *async_queue=NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * Scatter gather list (SGL) sizes and limits...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) //#define MAX_SCSI_FRAGS 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define MAX_FRAGS_SPILL1 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define MAX_FRAGS_SPILL2 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define FRAGS_PER_BUCKET (MAX_FRAGS_SPILL2 + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) //#define MAX_CHAIN_FRAGS 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) //#define MAX_CHAIN_FRAGS (15+15+15+16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define MAX_CHAIN_FRAGS (4 * MAX_FRAGS_SPILL2 + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) // Define max sg LIST bytes ( == (#frags + #chains) * 8 bytes each)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) // Works out to: 592d bytes! (9+1)*8 + 4*(15+1)*8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) // ^----------------- 80 + 512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #define MAX_SGL_BYTES ((MAX_FRAGS_SPILL1 + 1 + (4 * FRAGS_PER_BUCKET)) * 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /* linux only seems to ever give 128kB MAX contiguous (GFP_USER) mem bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define MAX_KMALLOC_SZ (128*1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define MPT_IOCTL_DEFAULT_TIMEOUT 10 /* Default timeout value (seconds) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * mptctl_syscall_down - Down the MPT adapter syscall semaphore.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * @ioc: Pointer to MPT adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * @nonblock: boolean, non-zero if O_NONBLOCK is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * All of the ioctl commands can potentially sleep, which is illegal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * with a spinlock held, thus we perform mutual exclusion here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * Returns negative errno on error, or zero for success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) mptctl_syscall_down(MPT_ADAPTER *ioc, int nonblock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (nonblock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (!mutex_trylock(&ioc->ioctl_cmds.mutex))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) rc = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (mutex_lock_interruptible(&ioc->ioctl_cmds.mutex))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) rc = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * This is the callback for any message we have posted. The message itself
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * will be returned to the message pool when we return from the IRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * This runs in irq context so be short and sweet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) mptctl_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) char *sense_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) int req_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) int sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (!req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "completing mpi function "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) "(0x%02X), req=%p, reply=%p\n", ioc->name, req->u.hdr.Function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) req, reply));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * Handling continuation of the same reply. Processing the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * reply, and eating the other replys that come later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (ioc->ioctl_cmds.msg_context != req->u.hdr.MsgContext)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) goto out_continuation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) ioc->ioctl_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (!reply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) ioc->ioctl_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) sz = min(ioc->reply_sz, 4*reply->u.reply.MsgLength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) memcpy(ioc->ioctl_cmds.reply, reply, sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (reply->u.reply.IOCStatus || reply->u.reply.IOCLogInfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) "iocstatus (0x%04X), loginfo (0x%08X)\n", ioc->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) le16_to_cpu(reply->u.reply.IOCStatus),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) le32_to_cpu(reply->u.reply.IOCLogInfo)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if ((req->u.hdr.Function == MPI_FUNCTION_SCSI_IO_REQUEST) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) (req->u.hdr.Function ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (reply->u.sreply.SCSIStatus || reply->u.sreply.SCSIState)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) "scsi_status (0x%02x), scsi_state (0x%02x), "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) "tag = (0x%04x), transfer_count (0x%08x)\n", ioc->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) reply->u.sreply.SCSIStatus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) reply->u.sreply.SCSIState,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) le16_to_cpu(reply->u.sreply.TaskTag),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) le32_to_cpu(reply->u.sreply.TransferCount)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (reply->u.sreply.SCSIState &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) MPI_SCSI_STATE_AUTOSENSE_VALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) sz = req->u.scsireq.SenseBufferLength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) req_index =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) le16_to_cpu(req->u.frame.hwhdr.msgctxu.fld.req_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) sense_data = ((u8 *)ioc->sense_buf_pool +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) (req_index * MPT_SENSE_BUFFER_ALLOC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) memcpy(ioc->ioctl_cmds.sense, sense_data, sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) ioc->ioctl_cmds.status |= MPT_MGMT_STATUS_SENSE_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /* We are done, issue wake up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_PENDING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (req->u.hdr.Function == MPI_FUNCTION_SCSI_TASK_MGMT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) mpt_clear_taskmgmt_in_progress_flag(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) ioc->ioctl_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) complete(&ioc->ioctl_cmds.done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (ioc->bus_type == SAS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) ioc->schedule_target_reset(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) ioc->ioctl_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) complete(&ioc->ioctl_cmds.done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) out_continuation:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (reply && (reply->u.reply.MsgFlags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) MPI_MSGFLAGS_CONTINUATION_REPLY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) mptctl_taskmgmt_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (!mf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) "TaskMgmt completed (mf=%p, mr=%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) ioc->name, mf, mr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (!mr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) memcpy(ioc->taskmgmt_cmds.reply, mr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) mpt_clear_taskmgmt_in_progress_flag(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) complete(&ioc->taskmgmt_cmds.done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (ioc->bus_type == SAS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) ioc->schedule_target_reset(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) mptctl_do_taskmgmt(MPT_ADAPTER *ioc, u8 tm_type, u8 bus_id, u8 target_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) MPT_FRAME_HDR *mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) SCSITaskMgmt_t *pScsiTm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) SCSITaskMgmtReply_t *pScsiTmReply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) int ii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) unsigned long time_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) u16 iocstatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) mutex_lock(&ioc->taskmgmt_cmds.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) mutex_unlock(&ioc->taskmgmt_cmds.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) mf = mpt_get_msg_frame(mptctl_taskmgmt_id, ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (mf == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) dtmprintk(ioc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) printk(MYIOC_s_WARN_FMT "TaskMgmt, no msg frames!!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) ioc->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) mpt_clear_taskmgmt_in_progress_flag(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) retval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) goto tm_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ioc->name, mf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) pScsiTm = (SCSITaskMgmt_t *) mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) memset(pScsiTm, 0, sizeof(SCSITaskMgmt_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) pScsiTm->TaskType = tm_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if ((tm_type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) (ioc->bus_type == FC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) pScsiTm->MsgFlags =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) pScsiTm->TargetID = target_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) pScsiTm->Bus = bus_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) pScsiTm->ChainOffset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) pScsiTm->Reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) pScsiTm->Reserved1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) pScsiTm->TaskMsgContext = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) for (ii= 0; ii < 8; ii++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) pScsiTm->LUN[ii] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) for (ii=0; ii < 7; ii++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) pScsiTm->Reserved2[ii] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) switch (ioc->bus_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) case FC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) timeout = 40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) case SAS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) timeout = 30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) case SPI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) timeout = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) dtmprintk(ioc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) printk(MYIOC_s_DEBUG_FMT "TaskMgmt type=%d timeout=%ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) ioc->name, tm_type, timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) time_count = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) mpt_put_msg_frame_hi_pri(mptctl_taskmgmt_id, ioc, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) retval = mpt_send_handshake_request(mptctl_taskmgmt_id, ioc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) sizeof(SCSITaskMgmt_t), (u32 *)pScsiTm, CAN_SLEEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (retval != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) dfailprintk(ioc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) printk(MYIOC_s_ERR_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) "TaskMgmt send_handshake FAILED!"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) " (ioc %p, mf %p, rc=%d) \n", ioc->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) ioc, mf, retval));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) mpt_free_msg_frame(ioc, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) mpt_clear_taskmgmt_in_progress_flag(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) goto tm_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) /* Now wait for the command to complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) ii = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done, timeout*HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) "TaskMgmt failed\n", ioc->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) mpt_free_msg_frame(ioc, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) mpt_clear_taskmgmt_in_progress_flag(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) retval = -1; /* return failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) goto tm_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) "TaskMgmt failed\n", ioc->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) retval = -1; /* return failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) goto tm_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) pScsiTmReply = (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) "TaskMgmt fw_channel = %d, fw_id = %d, task_type=0x%02X, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) "iocstatus=0x%04X\n\tloginfo=0x%08X, response_code=0x%02X, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) "term_cmnds=%d\n", ioc->name, pScsiTmReply->Bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) pScsiTmReply->TargetID, tm_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) le16_to_cpu(pScsiTmReply->IOCStatus),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) le32_to_cpu(pScsiTmReply->IOCLogInfo),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) pScsiTmReply->ResponseCode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) le32_to_cpu(pScsiTmReply->TerminationCount)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) iocstatus == MPI_IOCSTATUS_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) "TaskMgmt failed\n", ioc->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) retval = -1; /* return failure */
^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) tm_done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) mutex_unlock(&ioc->taskmgmt_cmds.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) /* mptctl_timeout_expired
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) * Expecting an interrupt, however timed out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) mptctl_timeout_expired(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) int ret_val = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) SCSIIORequest_t *scsi_req = (SCSIIORequest_t *) mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) u8 function = mf->u.hdr.Function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) ioc->name, __func__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (mpt_fwfault_debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) mpt_halt_firmware(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (ioc->ioc_reset_in_progress) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) CLEAR_MGMT_PENDING_STATUS(ioc->ioctl_cmds.status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) mpt_free_msg_frame(ioc, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) CLEAR_MGMT_PENDING_STATUS(ioc->ioctl_cmds.status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (ioc->bus_type == SAS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (function == MPI_FUNCTION_SCSI_IO_REQUEST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) ret_val = mptctl_do_taskmgmt(ioc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) scsi_req->Bus, scsi_req->TargetID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) else if (function == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) ret_val = mptctl_do_taskmgmt(ioc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) scsi_req->Bus, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (!ret_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if ((function == MPI_FUNCTION_SCSI_IO_REQUEST) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) (function == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) ret_val = mptctl_do_taskmgmt(ioc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) scsi_req->Bus, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (!ret_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling Reset! \n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) ioc->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) mpt_free_msg_frame(ioc, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) /* mptctl_ioc_reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * Clean-up functionality. Used only if there has been a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * reload of the FW due.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) switch(reset_phase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) case MPT_IOC_SETUP_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) case MPT_IOC_PRE_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) case MPT_IOC_POST_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_PENDING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) ioc->ioctl_cmds.status |= MPT_MGMT_STATUS_DID_IOCRESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) complete(&ioc->ioctl_cmds.done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) /* ASYNC Event Notification Support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) u8 event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) event = le32_to_cpu(pEvReply->Event) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s() called\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) ioc->name, __func__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if(async_queue == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) /* Raise SIGIO for persistent events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) * TODO - this define is not in MPI spec yet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) * but they plan to set it to 0x21
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (event == 0x21) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) ioc->aen_event_read_flag=1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Raised SIGIO to application\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) ioc->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) "Raised SIGIO to application\n", ioc->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) kill_fasync(&async_queue, SIGIO, POLL_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) /* This flag is set after SIGIO was raised, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) * remains set until the application has read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) * the event log via ioctl=MPTEVENTREPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if(ioc->aen_event_read_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) /* Signal only for the events that are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) * requested for by the application
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) ioc->aen_event_read_flag=1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) "Raised SIGIO to application\n", ioc->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) "Raised SIGIO to application\n", ioc->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) kill_fasync(&async_queue, SIGIO, POLL_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) mptctl_fasync(int fd, struct file *filep, int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) MPT_ADAPTER *ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) mutex_lock(&mpctl_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) list_for_each_entry(ioc, &ioc_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) ioc->aen_event_read_flag=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) ret = fasync_helper(fd, filep, mode, &async_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) mutex_unlock(&mpctl_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) * MPT ioctl handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) * cmd - specify the particular IOCTL command to be issued
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) * arg - data specific to the command. Must not be null.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) static long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) __mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) mpt_ioctl_header __user *uhdr = (void __user *) arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) mpt_ioctl_header khdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) int iocnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) unsigned iocnumX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) int nonblock = (file->f_flags & O_NONBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) MPT_ADAPTER *iocp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (copy_from_user(&khdr, uhdr, sizeof(khdr))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) printk(KERN_ERR MYNAM "%s::mptctl_ioctl() @%d - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) "Unable to copy mpt_ioctl_header data @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) __FILE__, __LINE__, uhdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) ret = -ENXIO; /* (-6) No such device or address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) /* Verify intended MPT adapter - set iocnum and the adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) * pointer (iocp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) iocnumX = khdr.iocnum & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) (iocp == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (!iocp->active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) printk(KERN_DEBUG MYNAM "%s::mptctl_ioctl() @%d - Controller disabled.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) __FILE__, __LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) /* Handle those commands that are just returning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) * information stored in the driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) * These commands should never time out and are unaffected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) * by TM and FW reloads.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) if ((cmd & ~IOCSIZE_MASK) == (MPTIOCINFO & ~IOCSIZE_MASK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) return mptctl_getiocinfo(iocp, arg, _IOC_SIZE(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) } else if (cmd == MPTTARGETINFO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) return mptctl_gettargetinfo(iocp, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) } else if (cmd == MPTTEST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) return mptctl_readtest(iocp, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) } else if (cmd == MPTEVENTQUERY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) return mptctl_eventquery(iocp, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) } else if (cmd == MPTEVENTENABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) return mptctl_eventenable(iocp, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) } else if (cmd == MPTEVENTREPORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return mptctl_eventreport(iocp, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) } else if (cmd == MPTFWREPLACE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) return mptctl_replace_fw(iocp, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) /* All of these commands require an interrupt or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) * are unknown/illegal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (cmd == MPTFWDOWNLOAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) ret = mptctl_fw_download(iocp, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) else if (cmd == MPTCOMMAND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) ret = mptctl_mpt_command(iocp, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) else if (cmd == MPTHARDRESET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) ret = mptctl_do_reset(iocp, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) else if ((cmd & ~IOCSIZE_MASK) == (HP_GETHOSTINFO & ~IOCSIZE_MASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) ret = mptctl_hp_hostinfo(iocp, arg, _IOC_SIZE(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) else if (cmd == HP_GETTARGETINFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) ret = mptctl_hp_targetinfo(iocp, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) mutex_unlock(&iocp->ioctl_cmds.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) static long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) mutex_lock(&mpctl_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) ret = __mptctl_ioctl(file, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) mutex_unlock(&mpctl_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) static int mptctl_do_reset(MPT_ADAPTER *iocp, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) struct mpt_ioctl_diag_reset __user *urinfo = (void __user *) arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) struct mpt_ioctl_diag_reset krinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) if (copy_from_user(&krinfo, urinfo, sizeof(struct mpt_ioctl_diag_reset))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) printk(KERN_ERR MYNAM "%s@%d::mptctl_do_reset - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) "Unable to copy mpt_ioctl_diag_reset struct @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) __FILE__, __LINE__, urinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "mptctl_do_reset called.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) iocp->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (mpt_HardResetHandler(iocp, CAN_SLEEP) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) printk (MYIOC_s_ERR_FMT "%s@%d::mptctl_do_reset - reset failed.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) iocp->name, __FILE__, __LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) return 0;
^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) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) * MPT FW download function. Cast the arg into the mpt_fw_xfer structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) * This structure contains: iocnum, firmware length (bytes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) * pointer to user space memory where the fw image is stored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) * Outputs: None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) * Return: 0 if successful
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) * -EFAULT if data unavailable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) * -ENXIO if no such device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) * -EAGAIN if resource problem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) * -ENOMEM if no memory for SGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) * -EMLINK if too many chain buffers required
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) * -EBADRQC if adapter does not support FW download
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) * -EBUSY if adapter is busy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) * -ENOMSG if FW upload returned bad status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) mptctl_fw_download(MPT_ADAPTER *iocp, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) struct mpt_fw_xfer __user *ufwdl = (void __user *) arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) struct mpt_fw_xfer kfwdl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) if (copy_from_user(&kfwdl, ufwdl, sizeof(struct mpt_fw_xfer))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) printk(KERN_ERR MYNAM "%s@%d::_ioctl_fwdl - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) "Unable to copy mpt_fw_xfer struct @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) __FILE__, __LINE__, ufwdl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) return mptctl_do_fw_download(iocp, kfwdl.bufp, kfwdl.fwlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) * FW Download engine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) * Outputs: None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) * Return: 0 if successful
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) * -EFAULT if data unavailable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) * -ENXIO if no such device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) * -EAGAIN if resource problem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) * -ENOMEM if no memory for SGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) * -EMLINK if too many chain buffers required
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) * -EBADRQC if adapter does not support FW download
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) * -EBUSY if adapter is busy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) * -ENOMSG if FW upload returned bad status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) mptctl_do_fw_download(MPT_ADAPTER *iocp, char __user *ufwbuf, size_t fwlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) FWDownload_t *dlmsg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) MPT_FRAME_HDR *mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) FWDownloadTCSGE_t *ptsge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) MptSge_t *sgl, *sgIn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) char *sgOut;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) struct buflist *buflist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) struct buflist *bl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) dma_addr_t sgl_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) int numfrags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) int maxfrags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) int n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) u32 sgdir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) u32 nib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) int fw_bytes_copied = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) int sge_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) u16 iocstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) pFWDownloadReply_t ReplyMsg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) unsigned long timeleft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) /* Valid device. Get a message frame and construct the FW download message.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) "mptctl_do_fwdl called. mptctl_id = %xh.\n", iocp->name, mptctl_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: kfwdl.bufp = %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) iocp->name, ufwbuf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: kfwdl.fwlen = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) iocp->name, (int)fwlen));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) dlmsg = (FWDownload_t*) mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) sgOut = (char *) (ptsge + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) * Construct f/w download request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) dlmsg->ImageType = MPI_FW_DOWNLOAD_ITYPE_FW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) dlmsg->Reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) dlmsg->ChainOffset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) dlmsg->Function = MPI_FUNCTION_FW_DOWNLOAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) dlmsg->Reserved1[0] = dlmsg->Reserved1[1] = dlmsg->Reserved1[2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) if (iocp->facts.MsgVersion >= MPI_VERSION_01_05)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) dlmsg->MsgFlags = MPI_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) dlmsg->MsgFlags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) /* Set up the Transaction SGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) ptsge->Reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) ptsge->ContextSize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) ptsge->DetailsLength = 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) ptsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) ptsge->Reserved_0100_Checksum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) ptsge->ImageOffset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) ptsge->ImageSize = cpu_to_le32(fwlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) /* Add the SGL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) * Need to kmalloc area(s) for holding firmware image bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) * But we need to do it piece meal, using a proper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) * scatter gather list (with 128kB MAX hunks).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) * A practical limit here might be # of sg hunks that fit into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) * a single IOC request frame; 12 or 8 (see below), so:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) * For FC9xx: 12 x 128kB == 1.5 mB (max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) * For C1030: 8 x 128kB == 1 mB (max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) * We could support chaining, but things get ugly(ier:)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) * Set the sge_offset to the start of the sgl (bytes).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) sgdir = 0x04000000; /* IOC will READ from sys mem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) sge_offset = sizeof(MPIHeader_t) + sizeof(FWDownloadTCSGE_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if ((sgl = kbuf_alloc_2_sgl(fwlen, sgdir, sge_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) &numfrags, &buflist, &sgl_dma, iocp)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) * We should only need SGL with 2 simple_32bit entries (up to 256 kB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) * for FC9xx f/w image, but calculate max number of sge hunks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) * we can fit into a request frame, and limit ourselves to that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) * (currently no chain support)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) * maxfrags = (Request Size - FWdownload Size ) / Size of 32 bit SGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) * Request maxfrags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) * 128 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) * 96 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) * 64 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) maxfrags = (iocp->req_sz - sizeof(MPIHeader_t) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) sizeof(FWDownloadTCSGE_t))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) / iocp->SGE_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (numfrags > maxfrags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) ret = -EMLINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) goto fwdl_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: sgl buffer = %p, sgfrags = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) iocp->name, sgl, numfrags));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) * Parse SG list, copying sgl itself,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) * plus f/w image hunks from user space as we go...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) sgIn = sgl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) bl = buflist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) for (i=0; i < numfrags; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) /* Get the SGE type: 0 - TCSGE, 3 - Chain, 1 - Simple SGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) * Skip everything but Simple. If simple, copy from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) * user space into kernel space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) * Note: we should not have anything but Simple as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) * Chain SGE are illegal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) nib = (sgIn->FlagsLength & 0x30000000) >> 28;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) if (nib == 0 || nib == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) } else if (sgIn->Address) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) iocp->add_sge(sgOut, sgIn->FlagsLength, sgIn->Address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (copy_from_user(bl->kptr, ufwbuf+fw_bytes_copied, bl->len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) printk(MYIOC_s_ERR_FMT "%s@%d::_ioctl_fwdl - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) "Unable to copy f/w buffer hunk#%d @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) iocp->name, __FILE__, __LINE__, n, ufwbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) goto fwdl_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) fw_bytes_copied += bl->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) sgIn++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) bl++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) sgOut += iocp->SGE_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) DBG_DUMP_FW_DOWNLOAD(iocp, (u32 *)mf, numfrags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) * Finally, perform firmware download.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) ReplyMsg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) SET_MGMT_MSG_CONTEXT(iocp->ioctl_cmds.msg_context, dlmsg->MsgContext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) INITIALIZE_MGMT_STATUS(iocp->ioctl_cmds.status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) mpt_put_msg_frame(mptctl_id, iocp, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) /* Now wait for the command to complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) retry_wait:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) timeleft = wait_for_completion_timeout(&iocp->ioctl_cmds.done, HZ*60);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) if (!(iocp->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) ret = -ETIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) printk(MYIOC_s_WARN_FMT "%s: failed\n", iocp->name, __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) if (iocp->ioctl_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) mpt_free_msg_frame(iocp, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) goto fwdl_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if (!timeleft) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) printk(MYIOC_s_WARN_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) "FW download timeout, doorbell=0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) iocp->name, mpt_GetIocState(iocp, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) mptctl_timeout_expired(iocp, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) goto retry_wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) goto fwdl_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) if (!(iocp->ioctl_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) printk(MYIOC_s_WARN_FMT "%s: failed\n", iocp->name, __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) mpt_free_msg_frame(iocp, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) ret = -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) goto fwdl_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) if (sgl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) kfree_sgl(sgl, sgl_dma, buflist, iocp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) ReplyMsg = (pFWDownloadReply_t)iocp->ioctl_cmds.reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) iocstat = le16_to_cpu(ReplyMsg->IOCStatus) & MPI_IOCSTATUS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) if (iocstat == MPI_IOCSTATUS_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) printk(MYIOC_s_INFO_FMT "F/W update successful!\n", iocp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) } else if (iocstat == MPI_IOCSTATUS_INVALID_FUNCTION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) printk(MYIOC_s_WARN_FMT "Hmmm... F/W download not supported!?!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) iocp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) printk(MYIOC_s_WARN_FMT "(time to go bang on somebodies door)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) iocp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) return -EBADRQC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) } else if (iocstat == MPI_IOCSTATUS_BUSY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) printk(MYIOC_s_WARN_FMT "IOC_BUSY!\n", iocp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) printk(MYIOC_s_WARN_FMT "(try again later?)\n", iocp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) printk(MYIOC_s_WARN_FMT "ioctl_fwdl() returned [bad] status = %04xh\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) iocp->name, iocstat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) printk(MYIOC_s_WARN_FMT "(bad VooDoo)\n", iocp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) return -ENOMSG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) fwdl_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) CLEAR_MGMT_STATUS(iocp->ioctl_cmds.status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) SET_MGMT_MSG_CONTEXT(iocp->ioctl_cmds.msg_context, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) kfree_sgl(sgl, sgl_dma, buflist, iocp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) * SGE Allocation routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) * Inputs: bytes - number of bytes to be transferred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) * sgdir - data direction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) * sge_offset - offset (in bytes) from the start of the request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) * frame to the first SGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) * ioc - pointer to the mptadapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) * Outputs: frags - number of scatter gather elements
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) * blp - point to the buflist pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) * sglbuf_dma - pointer to the (dma) sgl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) * Returns: Null if failes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) * pointer to the (virtual) sgl if successful.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) static MptSge_t *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) kbuf_alloc_2_sgl(int bytes, u32 sgdir, int sge_offset, int *frags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) MptSge_t *sglbuf = NULL; /* pointer to array of SGE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) /* and chain buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) struct buflist *buflist = NULL; /* kernel routine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) MptSge_t *sgl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) int numfrags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) int fragcnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) int alloc_sz = min(bytes,MAX_KMALLOC_SZ); // avoid kernel warning msg!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) int bytes_allocd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) int this_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) dma_addr_t pa; // phys addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) int i, buflist_ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) int sg_spill = MAX_FRAGS_SPILL1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) int dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) if (bytes < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) /* initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) *frags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) *blp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) /* Allocate and initialize an array of kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) * structures for the SG elements.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) i = MAX_SGL_BYTES / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) buflist = kzalloc(i, GFP_USER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) if (!buflist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) buflist_ent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) /* Allocate a single block of memory to store the sg elements and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) * the chain buffers. The calling routine is responsible for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) * copying the data in this array into the correct place in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) * request and chain buffers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) sglbuf = pci_alloc_consistent(ioc->pcidev, MAX_SGL_BYTES, sglbuf_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) if (sglbuf == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) goto free_and_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) if (sgdir & 0x04000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) dir = PCI_DMA_TODEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) dir = PCI_DMA_FROMDEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) /* At start:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) * sgl = sglbuf = point to beginning of sg buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) * buflist_ent = 0 = first kernel structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) * sg_spill = number of SGE that can be written before the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) * chain element.
^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) sgl = sglbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) sg_spill = ((ioc->req_sz - sge_offset)/ioc->SGE_size) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) while (bytes_allocd < bytes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) this_alloc = min(alloc_sz, bytes-bytes_allocd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) buflist[buflist_ent].len = this_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) buflist[buflist_ent].kptr = pci_alloc_consistent(ioc->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) this_alloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) &pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) if (buflist[buflist_ent].kptr == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) alloc_sz = alloc_sz / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) if (alloc_sz == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) printk(MYIOC_s_WARN_FMT "-SG: No can do - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) "not enough memory! :-(\n", ioc->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) printk(MYIOC_s_WARN_FMT "-SG: (freeing %d frags)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) ioc->name, numfrags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) goto free_and_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) dma_addr_t dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) bytes_allocd += this_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) sgl->FlagsLength = (0x10000000|sgdir|this_alloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) dma_addr = pci_map_single(ioc->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) buflist[buflist_ent].kptr, this_alloc, dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) sgl->Address = dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) fragcnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) numfrags++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) sgl++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) buflist_ent++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) if (bytes_allocd >= bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) /* Need to chain? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) if (fragcnt == sg_spill) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) printk(MYIOC_s_WARN_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) "-SG: No can do - " "Chain required! :-(\n", ioc->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) printk(MYIOC_s_WARN_FMT "(freeing %d frags)\n", ioc->name, numfrags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) goto free_and_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) /* overflow check... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) if (numfrags*8 > MAX_SGL_BYTES){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) /* GRRRRR... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) printk(MYIOC_s_WARN_FMT "-SG: No can do - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) "too many SG frags! :-(\n", ioc->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) printk(MYIOC_s_WARN_FMT "-SG: (freeing %d frags)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) ioc->name, numfrags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) goto free_and_fail;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) /* Last sge fixup: set LE+eol+eob bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) sgl[-1].FlagsLength |= 0xC1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) *frags = numfrags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) *blp = buflist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "-SG: kbuf_alloc_2_sgl() - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) "%d SG frags generated!\n", ioc->name, numfrags));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "-SG: kbuf_alloc_2_sgl() - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) "last (big) alloc_sz=%d\n", ioc->name, alloc_sz));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) return sglbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) free_and_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) if (sglbuf != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) for (i = 0; i < numfrags; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) dma_addr_t dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) u8 *kptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) if ((sglbuf[i].FlagsLength >> 24) == 0x30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) dma_addr = sglbuf[i].Address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) kptr = buflist[i].kptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) len = buflist[i].len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) pci_free_consistent(ioc->pcidev, len, kptr, dma_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) pci_free_consistent(ioc->pcidev, MAX_SGL_BYTES, sglbuf, *sglbuf_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) kfree(buflist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) * Routine to free the SGL elements.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma, struct buflist *buflist, MPT_ADAPTER *ioc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) MptSge_t *sg = sgl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) struct buflist *bl = buflist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) u32 nib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) int dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) int n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) if (sg->FlagsLength & 0x04000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) dir = PCI_DMA_TODEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) dir = PCI_DMA_FROMDEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) nib = (sg->FlagsLength & 0xF0000000) >> 28;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) while (! (nib & 0x4)) { /* eob */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) /* skip ignore/chain. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) if (nib == 0 || nib == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) } else if (sg->Address) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) dma_addr_t dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) void *kptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) dma_addr = sg->Address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) kptr = bl->kptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) len = bl->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) pci_unmap_single(ioc->pcidev, dma_addr, len, dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) pci_free_consistent(ioc->pcidev, len, kptr, dma_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) sg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) bl++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) nib = (le32_to_cpu(sg->FlagsLength) & 0xF0000000) >> 28;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) /* we're at eob! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) if (sg->Address) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) dma_addr_t dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) void *kptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) dma_addr = sg->Address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) kptr = bl->kptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) len = bl->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) pci_unmap_single(ioc->pcidev, dma_addr, len, dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) pci_free_consistent(ioc->pcidev, len, kptr, dma_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) pci_free_consistent(ioc->pcidev, MAX_SGL_BYTES, sgl, sgl_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) kfree(buflist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "-SG: Free'd 1 SGL buf + %d kbufs!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) ioc->name, n));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) * mptctl_getiocinfo - Query the host adapter for IOC information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) * @arg: User space argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) * Outputs: None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) * Return: 0 if successful
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) * -EFAULT if data unavailable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) * -ENODEV if no such device/adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) mptctl_getiocinfo (MPT_ADAPTER *ioc, unsigned long arg, unsigned int data_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) struct mpt_ioctl_iocinfo __user *uarg = (void __user *) arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) struct mpt_ioctl_iocinfo *karg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) unsigned int port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) int cim_rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) struct scsi_device *sdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) VirtDevice *vdevice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) /* Add of PCI INFO results in unaligned access for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) * IA64 and Sparc. Reset long to int. Return no PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) * data for obsolete format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) if (data_size == sizeof(struct mpt_ioctl_iocinfo_rev0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) cim_rev = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) else if (data_size == sizeof(struct mpt_ioctl_iocinfo_rev1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) cim_rev = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) else if (data_size == sizeof(struct mpt_ioctl_iocinfo))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) cim_rev = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) else if (data_size == (sizeof(struct mpt_ioctl_iocinfo_rev0)+12))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) cim_rev = 0; /* obsolete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) karg = memdup_user(uarg, data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) if (IS_ERR(karg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) printk(KERN_ERR MYNAM "%s@%d::mpt_ioctl_iocinfo() - memdup_user returned error [%ld]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) __FILE__, __LINE__, PTR_ERR(karg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) return PTR_ERR(karg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) /* Verify the data transfer size is correct. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) if (karg->hdr.maxDataSize != data_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_getiocinfo - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) "Structure size mismatch. Command not completed.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) ioc->name, __FILE__, __LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) kfree(karg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_getiocinfo called.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) ioc->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) /* Fill in the data and return the structure to the calling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) * program
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) if (ioc->bus_type == SAS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) karg->adapterType = MPT_IOCTL_INTERFACE_SAS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) else if (ioc->bus_type == FC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) karg->adapterType = MPT_IOCTL_INTERFACE_FC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) karg->adapterType = MPT_IOCTL_INTERFACE_SCSI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) if (karg->hdr.port > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) kfree(karg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) port = karg->hdr.port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) karg->port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) pdev = (struct pci_dev *) ioc->pcidev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) karg->pciId = pdev->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) karg->hwRev = pdev->revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) karg->subSystemDevice = pdev->subsystem_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) karg->subSystemVendor = pdev->subsystem_vendor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) if (cim_rev == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) /* Get the PCI bus, device, and function numbers for the IOC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) karg->pciInfo.u.bits.busNumber = pdev->bus->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) } else if (cim_rev == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) /* Get the PCI bus, device, function and segment ID numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) for the IOC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) karg->pciInfo.u.bits.busNumber = pdev->bus->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) karg->pciInfo.segmentID = pci_domain_nr(pdev->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) /* Get number of devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) karg->numDevices = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) if (ioc->sh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) shost_for_each_device(sdev, ioc->sh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) vdevice = sdev->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) if (vdevice == NULL || vdevice->vtarget == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) if (vdevice->vtarget->tflags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) MPT_TARGET_FLAGS_RAID_COMPONENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) karg->numDevices++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) /* Set the BIOS and FW Version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) karg->FWVersion = ioc->facts.FWVersion.Word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) karg->BIOSVersion = ioc->biosVersion;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) /* Set the Version Strings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) strncpy (karg->driverVersion, MPT_LINUX_PACKAGE_NAME, MPT_IOCTL_VERSION_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) karg->driverVersion[MPT_IOCTL_VERSION_LENGTH-1]='\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) karg->busChangeEvent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) karg->hostId = ioc->pfacts[port].PortSCSIID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) karg->rsvd[0] = karg->rsvd[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) /* Copy the data from kernel memory to user memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) if (copy_to_user((char __user *)arg, karg, data_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_getiocinfo - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) "Unable to write out mpt_ioctl_iocinfo struct @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) ioc->name, __FILE__, __LINE__, uarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) kfree(karg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) kfree(karg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) * mptctl_gettargetinfo - Query the host adapter for target information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) * @arg: User space argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) * Outputs: None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) * Return: 0 if successful
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) * -EFAULT if data unavailable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) * -ENODEV if no such device/adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) mptctl_gettargetinfo (MPT_ADAPTER *ioc, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) struct mpt_ioctl_targetinfo karg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) VirtDevice *vdevice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) char *pmem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) int *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) int numDevices = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) int lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) int maxWordsLeft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) int numBytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) u8 port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) struct scsi_device *sdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) printk(KERN_ERR MYNAM "%s@%d::mptctl_gettargetinfo - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) "Unable to read in mpt_ioctl_targetinfo struct @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) __FILE__, __LINE__, uarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_gettargetinfo called.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) ioc->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) /* Get the port number and set the maximum number of bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) * in the returned structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) * Ignore the port setting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) numBytes = karg.hdr.maxDataSize - sizeof(mpt_ioctl_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) maxWordsLeft = numBytes/sizeof(int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) port = karg.hdr.port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) if (maxWordsLeft <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo() - no memory available!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) ioc->name, __FILE__, __LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) /* Fill in the data and return the structure to the calling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) * program
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) /* struct mpt_ioctl_targetinfo does not contain sufficient space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) * for the target structures so when the IOCTL is called, there is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) * not sufficient stack space for the structure. Allocate memory,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) * populate the memory, copy back to the user, then free memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) * targetInfo format:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) * bits 31-24: reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) * 23-16: LUN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) * 15- 8: Bus Number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) * 7- 0: Target ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) pmem = kzalloc(numBytes, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) if (!pmem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo() - no memory available!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) ioc->name, __FILE__, __LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) pdata = (int *) pmem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) /* Get number of devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) if (ioc->sh){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) shost_for_each_device(sdev, ioc->sh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) if (!maxWordsLeft)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) vdevice = sdev->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) if (vdevice == NULL || vdevice->vtarget == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) if (vdevice->vtarget->tflags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) MPT_TARGET_FLAGS_RAID_COMPONENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) lun = (vdevice->vtarget->raidVolume) ? 0x80 : vdevice->lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) *pdata = (((u8)lun << 16) + (vdevice->vtarget->channel << 8) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) (vdevice->vtarget->id ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) pdata++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) numDevices++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) --maxWordsLeft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) karg.numDevices = numDevices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) /* Copy part of the data from kernel memory to user memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) if (copy_to_user((char __user *)arg, &karg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) sizeof(struct mpt_ioctl_targetinfo))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) ioc->name, __FILE__, __LINE__, uarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) kfree(pmem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) /* Copy the remaining data from kernel memory to user memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) if (copy_to_user(uarg->targetInfo, pmem, numBytes)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) ioc->name, __FILE__, __LINE__, pdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) kfree(pmem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) kfree(pmem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) /* MPT IOCTL Test function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) * Outputs: None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) * Return: 0 if successful
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) * -EFAULT if data unavailable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) * -ENODEV if no such device/adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) mptctl_readtest (MPT_ADAPTER *ioc, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) struct mpt_ioctl_test __user *uarg = (void __user *) arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) struct mpt_ioctl_test karg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_test))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) printk(KERN_ERR MYNAM "%s@%d::mptctl_readtest - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) "Unable to read in mpt_ioctl_test struct @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) __FILE__, __LINE__, uarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_readtest called.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) ioc->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) /* Fill in the data and return the structure to the calling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) * program
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) #ifdef MFCNT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) karg.chip_type = ioc->mfcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) karg.chip_type = ioc->pcidev->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) strncpy (karg.name, ioc->name, MPT_MAX_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) karg.name[MPT_MAX_NAME-1]='\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) strncpy (karg.product, ioc->prod_name, MPT_PRODUCT_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) karg.product[MPT_PRODUCT_LENGTH-1]='\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) /* Copy the data from kernel memory to user memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_test))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_readtest - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) "Unable to write out mpt_ioctl_test struct @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) ioc->name, __FILE__, __LINE__, uarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) * mptctl_eventquery - Query the host adapter for the event types
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) * that are being logged.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) * @arg: User space argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) * Outputs: None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) * Return: 0 if successful
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) * -EFAULT if data unavailable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) * -ENODEV if no such device/adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) mptctl_eventquery (MPT_ADAPTER *ioc, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) struct mpt_ioctl_eventquery __user *uarg = (void __user *) arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) struct mpt_ioctl_eventquery karg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventquery))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) printk(KERN_ERR MYNAM "%s@%d::mptctl_eventquery - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) "Unable to read in mpt_ioctl_eventquery struct @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) __FILE__, __LINE__, uarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventquery called.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) ioc->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) karg.eventEntries = MPTCTL_EVENT_LOG_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) karg.eventTypes = ioc->eventTypes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) /* Copy the data from kernel memory to user memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) if (copy_to_user((char __user *)arg, &karg, sizeof(struct mpt_ioctl_eventquery))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_eventquery - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) "Unable to write out mpt_ioctl_eventquery struct @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) ioc->name, __FILE__, __LINE__, uarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) mptctl_eventenable (MPT_ADAPTER *ioc, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) struct mpt_ioctl_eventenable __user *uarg = (void __user *) arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) struct mpt_ioctl_eventenable karg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventenable))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) printk(KERN_ERR MYNAM "%s@%d::mptctl_eventenable - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) "Unable to read in mpt_ioctl_eventenable struct @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) __FILE__, __LINE__, uarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventenable called.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) ioc->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) if (ioc->events == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) /* Have not yet allocated memory - do so now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) int sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) ioc->events = kzalloc(sz, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) if (!ioc->events) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) printk(MYIOC_s_ERR_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) ": ERROR - Insufficient memory to add adapter!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) ioc->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) ioc->alloc_total += sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) ioc->eventContext = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) /* Update the IOC event logging flag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) ioc->eventTypes = karg.eventTypes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) mptctl_eventreport (MPT_ADAPTER *ioc, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) struct mpt_ioctl_eventreport __user *uarg = (void __user *) arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) struct mpt_ioctl_eventreport karg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) int numBytes, maxEvents, max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventreport))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) printk(KERN_ERR MYNAM "%s@%d::mptctl_eventreport - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) "Unable to read in mpt_ioctl_eventreport struct @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) __FILE__, __LINE__, uarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventreport called.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) ioc->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) numBytes = karg.hdr.maxDataSize - sizeof(mpt_ioctl_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) maxEvents = numBytes/sizeof(MPT_IOCTL_EVENTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) max = MPTCTL_EVENT_LOG_SIZE < maxEvents ? MPTCTL_EVENT_LOG_SIZE : maxEvents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) /* If fewer than 1 event is requested, there must have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) * been some type of error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) if ((max < 1) || !ioc->events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) /* reset this flag so SIGIO can restart */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) ioc->aen_event_read_flag=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) /* Copy the data from kernel memory to user memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) numBytes = max * sizeof(MPT_IOCTL_EVENTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) if (copy_to_user(uarg->eventData, ioc->events, numBytes)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_eventreport - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) "Unable to write out mpt_ioctl_eventreport struct @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) ioc->name, __FILE__, __LINE__, ioc->events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) mptctl_replace_fw (MPT_ADAPTER *ioc, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) struct mpt_ioctl_replace_fw __user *uarg = (void __user *) arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) struct mpt_ioctl_replace_fw karg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) int newFwSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_replace_fw))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) printk(KERN_ERR MYNAM "%s@%d::mptctl_replace_fw - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) "Unable to read in mpt_ioctl_replace_fw struct @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) __FILE__, __LINE__, uarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_replace_fw called.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) ioc->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) /* If caching FW, Free the old FW image
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) if (ioc->cached_fw == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) mpt_free_fw_memory(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) /* Allocate memory for the new FW image
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) newFwSize = ALIGN(karg.newImageSize, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) mpt_alloc_fw_memory(ioc, newFwSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) if (ioc->cached_fw == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) /* Copy the data from user memory to kernel space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) if (copy_from_user(ioc->cached_fw, uarg->newImage, newFwSize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_replace_fw - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) "Unable to read in mpt_ioctl_replace_fw image "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) "@ %p\n", ioc->name, __FILE__, __LINE__, uarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) mpt_free_fw_memory(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) /* Update IOCFactsReply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) ioc->facts.FWImageSize = newFwSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) /* MPT IOCTL MPTCOMMAND function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) * Cast the arg into the mpt_ioctl_mpt_command structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) * Outputs: None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) * Return: 0 if successful
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) * -EBUSY if previous command timeout and IOC reset is not complete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) * -EFAULT if data unavailable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) * -ENODEV if no such device/adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) * -ETIME if timer expires
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) * -ENOMEM if memory allocation error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) mptctl_mpt_command (MPT_ADAPTER *ioc, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) struct mpt_ioctl_command __user *uarg = (void __user *) arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) struct mpt_ioctl_command karg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_command))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) printk(KERN_ERR MYNAM "%s@%d::mptctl_mpt_command - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) "Unable to read in mpt_ioctl_command struct @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) __FILE__, __LINE__, uarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) rc = mptctl_do_mpt_command (ioc, karg, &uarg->MF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) /* Worker routine for the IOCTL MPTCOMMAND and MPTCOMMAND32 (sparc) commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) * Outputs: None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) * Return: 0 if successful
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) * -EBUSY if previous command timeout and IOC reset is not complete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) * -EFAULT if data unavailable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) * -ENODEV if no such device/adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) * -ETIME if timer expires
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) * -ENOMEM if memory allocation error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) * -EPERM if SCSI I/O and target is untagged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) mptctl_do_mpt_command (MPT_ADAPTER *ioc, struct mpt_ioctl_command karg, void __user *mfPtr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) MPT_FRAME_HDR *mf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) MPIHeader_t *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) char *psge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) struct buflist bufIn; /* data In buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) struct buflist bufOut; /* data Out buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) dma_addr_t dma_addr_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) dma_addr_t dma_addr_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) int sgSize = 0; /* Num SG elements */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) int flagsLength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) int sz, rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) int msgContext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) u16 req_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) ulong timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) unsigned long timeleft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) struct scsi_device *sdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) u8 function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) /* bufIn and bufOut are used for user to kernel space transfers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) bufIn.kptr = bufOut.kptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) bufIn.len = bufOut.len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) if (ioc->ioc_reset_in_progress) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) printk(KERN_ERR MYNAM "%s@%d::mptctl_do_mpt_command - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) "Busy with diagnostic reset\n", __FILE__, __LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) /* Basic sanity checks to prevent underflows or integer overflows */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) if (karg.maxReplyBytes < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) karg.dataInSize < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) karg.dataOutSize < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) karg.dataSgeOffset < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) karg.maxSenseBytes < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) karg.dataSgeOffset > ioc->req_sz / 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) /* Verify that the final request frame will not be too large.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) sz = karg.dataSgeOffset * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) if (karg.dataInSize > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) sz += ioc->SGE_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) if (karg.dataOutSize > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) sz += ioc->SGE_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) if (sz > ioc->req_sz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) "Request frame too large (%d) maximum (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) ioc->name, __FILE__, __LINE__, sz, ioc->req_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) /* Get a free request frame and save the message context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) hdr = (MPIHeader_t *) mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) msgContext = le32_to_cpu(hdr->MsgContext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) /* Copy the request frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) * Reset the saved message context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) * Request frame in user space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) if (copy_from_user(mf, mfPtr, karg.dataSgeOffset * 4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) "Unable to read MF from mpt_ioctl_command struct @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) ioc->name, __FILE__, __LINE__, mfPtr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) function = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) goto done_free_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) hdr->MsgContext = cpu_to_le32(msgContext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) function = hdr->Function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) /* Verify that this request is allowed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sending mpi function (0x%02X), req=%p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) ioc->name, hdr->Function, mf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) switch (function) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) case MPI_FUNCTION_IOC_FACTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) case MPI_FUNCTION_PORT_FACTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) karg.dataOutSize = karg.dataInSize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) case MPI_FUNCTION_CONFIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) Config_t *config_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) config_frame = (Config_t *)mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\ttype=0x%02x ext_type=0x%02x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) "number=0x%02x action=0x%02x\n", ioc->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) config_frame->Header.PageType,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) config_frame->ExtPageType,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) config_frame->Header.PageNumber,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) config_frame->Action));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) case MPI_FUNCTION_FC_COMMON_TRANSPORT_SEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) case MPI_FUNCTION_FC_EX_LINK_SRVC_SEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) case MPI_FUNCTION_FW_UPLOAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) case MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) case MPI_FUNCTION_FW_DOWNLOAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) case MPI_FUNCTION_FC_PRIMITIVE_SEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) case MPI_FUNCTION_TOOLBOX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) case MPI_FUNCTION_SCSI_IO_REQUEST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) if (ioc->sh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) int qtag = MPI_SCSIIO_CONTROL_UNTAGGED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) int scsidir = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) int dataSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) u32 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) id = (ioc->devices_per_bus == 0) ? 256 : ioc->devices_per_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) if (pScsiReq->TargetID > id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) "Target ID out of bounds. \n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) ioc->name, __FILE__, __LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) goto done_free_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) if (pScsiReq->Bus >= ioc->number_of_buses) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) "Target Bus out of bounds. \n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) ioc->name, __FILE__, __LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) goto done_free_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) pScsiReq->MsgFlags |= mpt_msg_flags(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) /* verify that app has not requested
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) * more sense data than driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) * can provide, if so, reset this parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) * set the sense buffer pointer low address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) * update the control field to specify Q type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) pScsiReq->SenseBufferLength = karg.maxSenseBytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) pScsiReq->SenseBufferLowAddr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) cpu_to_le32(ioc->sense_buf_low_dma
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) + (req_idx * MPT_SENSE_BUFFER_ALLOC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) shost_for_each_device(sdev, ioc->sh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) struct scsi_target *starget = scsi_target(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) VirtTarget *vtarget = starget->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) if (vtarget == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) if ((pScsiReq->TargetID == vtarget->id) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) (pScsiReq->Bus == vtarget->channel) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) /* Have the IOCTL driver set the direction based
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) * on the dataOutSize (ordering issue with Sparc).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) if (karg.dataOutSize > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) scsidir = MPI_SCSIIO_CONTROL_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) dataSize = karg.dataOutSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) scsidir = MPI_SCSIIO_CONTROL_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) dataSize = karg.dataInSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) pScsiReq->Control = cpu_to_le32(scsidir | qtag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) pScsiReq->DataLength = cpu_to_le32(dataSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) "SCSI driver is not loaded. \n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) ioc->name, __FILE__, __LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) goto done_free_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) case MPI_FUNCTION_SMP_PASSTHROUGH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) /* Check mf->PassthruFlags to determine if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) * transfer is ImmediateMode or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) * Immediate mode returns data in the ReplyFrame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) * Else, we are sending request and response data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) * in two SGLs at the end of the mf.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) case MPI_FUNCTION_SATA_PASSTHROUGH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) if (!ioc->sh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) "SCSI driver is not loaded. \n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) ioc->name, __FILE__, __LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) goto done_free_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) case MPI_FUNCTION_RAID_ACTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) /* Just add a SGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) case MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) if (ioc->sh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) int qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) int scsidir = MPI_SCSIIO_CONTROL_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) int dataSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) pScsiReq->MsgFlags |= mpt_msg_flags(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) /* verify that app has not requested
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) * more sense data than driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) * can provide, if so, reset this parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) * set the sense buffer pointer low address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) * update the control field to specify Q type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) pScsiReq->SenseBufferLength = karg.maxSenseBytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) pScsiReq->SenseBufferLowAddr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) cpu_to_le32(ioc->sense_buf_low_dma
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) + (req_idx * MPT_SENSE_BUFFER_ALLOC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) /* All commands to physical devices are tagged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) /* Have the IOCTL driver set the direction based
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) * on the dataOutSize (ordering issue with Sparc).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) if (karg.dataOutSize > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) scsidir = MPI_SCSIIO_CONTROL_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) dataSize = karg.dataOutSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) scsidir = MPI_SCSIIO_CONTROL_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) dataSize = karg.dataInSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) pScsiReq->Control = cpu_to_le32(scsidir | qtag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) pScsiReq->DataLength = cpu_to_le32(dataSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) "SCSI driver is not loaded. \n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) ioc->name, __FILE__, __LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) goto done_free_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) case MPI_FUNCTION_SCSI_TASK_MGMT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) SCSITaskMgmt_t *pScsiTm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) pScsiTm = (SCSITaskMgmt_t *)mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) "\tTaskType=0x%x MsgFlags=0x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) "TaskMsgContext=0x%x id=%d channel=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) ioc->name, pScsiTm->TaskType, le32_to_cpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) (pScsiTm->TaskMsgContext), pScsiTm->MsgFlags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) pScsiTm->TargetID, pScsiTm->Bus));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) case MPI_FUNCTION_IOC_INIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) IOCInit_t *pInit = (IOCInit_t *) mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) u32 high_addr, sense_high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) /* Verify that all entries in the IOC INIT match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) * existing setup (and in LE format).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) if (sizeof(dma_addr_t) == sizeof(u64)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) high_addr = cpu_to_le32((u32)((u64)ioc->req_frames_dma >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) sense_high= cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) high_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) sense_high= 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) if ((pInit->Flags != 0) || (pInit->MaxDevices != ioc->facts.MaxDevices) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) (pInit->MaxBuses != ioc->facts.MaxBuses) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) (pInit->ReplyFrameSize != cpu_to_le16(ioc->reply_sz)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) (pInit->HostMfaHighAddr != high_addr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) (pInit->SenseBufferHighAddr != sense_high)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) "IOC_INIT issued with 1 or more incorrect parameters. Rejected.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) ioc->name, __FILE__, __LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) goto done_free_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) * MPI_FUNCTION_PORT_ENABLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) * MPI_FUNCTION_TARGET_CMD_BUFFER_POST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) * MPI_FUNCTION_TARGET_ASSIST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) * MPI_FUNCTION_TARGET_STATUS_SEND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) * MPI_FUNCTION_TARGET_MODE_ABORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) * MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) * MPI_FUNCTION_IO_UNIT_RESET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) * MPI_FUNCTION_HANDSHAKE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) * MPI_FUNCTION_REPLY_FRAME_REMOVAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) * MPI_FUNCTION_EVENT_NOTIFICATION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) * (driver handles event notification)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) * MPI_FUNCTION_EVENT_ACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) /* What to do with these??? CHECK ME!!!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) MPI_FUNCTION_FC_LINK_SRVC_BUF_POST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) MPI_FUNCTION_FC_LINK_SRVC_RSP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) MPI_FUNCTION_FC_ABORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) MPI_FUNCTION_LAN_SEND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) MPI_FUNCTION_LAN_RECEIVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) MPI_FUNCTION_LAN_RESET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) "Illegal request (function 0x%x) \n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) ioc->name, __FILE__, __LINE__, hdr->Function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) goto done_free_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) /* Add the SGL ( at most one data in SGE and one data out SGE )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) * In the case of two SGE's - the data out (write) will always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) * preceede the data in (read) SGE. psgList is used to free the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) * allocated memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) psge = (char *) (((int *) mf) + karg.dataSgeOffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) flagsLength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) if (karg.dataOutSize > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) sgSize ++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) if (karg.dataInSize > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) sgSize ++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) if (sgSize > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) /* Set up the dataOut memory allocation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) if (karg.dataOutSize > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) if (karg.dataInSize > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) flagsLength = ( MPI_SGE_FLAGS_SIMPLE_ELEMENT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) MPI_SGE_FLAGS_END_OF_BUFFER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) MPI_SGE_FLAGS_DIRECTION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) << MPI_SGE_FLAGS_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) flagsLength |= karg.dataOutSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) bufOut.len = karg.dataOutSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) bufOut.kptr = pci_alloc_consistent(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) ioc->pcidev, bufOut.len, &dma_addr_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) if (bufOut.kptr == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) goto done_free_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) /* Set up this SGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) * Copy to MF and to sglbuf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) ioc->add_sge(psge, flagsLength, dma_addr_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) psge += ioc->SGE_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) /* Copy user data to kernel space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) if (copy_from_user(bufOut.kptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) karg.dataOutBufPtr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) bufOut.len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) printk(MYIOC_s_ERR_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) "%s@%d::mptctl_do_mpt_command - Unable "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) "to read user data "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) "struct @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) ioc->name, __FILE__, __LINE__,karg.dataOutBufPtr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) goto done_free_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) if (karg.dataInSize > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) flagsLength |= karg.dataInSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) bufIn.len = karg.dataInSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) bufIn.kptr = pci_alloc_consistent(ioc->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) bufIn.len, &dma_addr_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) if (bufIn.kptr == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) goto done_free_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) /* Set up this SGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) * Copy to MF and to sglbuf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) ioc->add_sge(psge, flagsLength, dma_addr_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) /* Add a NULL SGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) ioc->add_sge(psge, flagsLength, (dma_addr_t) -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context, hdr->MsgContext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) INITIALIZE_MGMT_STATUS(ioc->ioctl_cmds.status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) if (hdr->Function == MPI_FUNCTION_SCSI_TASK_MGMT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) mutex_lock(&ioc->taskmgmt_cmds.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) mutex_unlock(&ioc->taskmgmt_cmds.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) goto done_free_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) mpt_put_msg_frame_hi_pri(mptctl_id, ioc, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) rc =mpt_send_handshake_request(mptctl_id, ioc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) sizeof(SCSITaskMgmt_t), (u32*)mf, CAN_SLEEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) if (rc != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) "send_handshake FAILED! (ioc %p, mf %p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) ioc->name, ioc, mf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) mpt_clear_taskmgmt_in_progress_flag(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) rc = -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) mutex_unlock(&ioc->taskmgmt_cmds.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) goto done_free_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) mpt_put_msg_frame(mptctl_id, ioc, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) /* Now wait for the command to complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) timeout = (karg.timeout > 0) ? karg.timeout : MPT_IOCTL_DEFAULT_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) retry_wait:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) timeleft = wait_for_completion_timeout(&ioc->ioctl_cmds.done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) HZ*timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) if (!(ioc->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) rc = -ETIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: TIMED OUT!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) ioc->name, __func__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) if (function == MPI_FUNCTION_SCSI_TASK_MGMT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) mutex_unlock(&ioc->taskmgmt_cmds.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) goto done_free_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) if (!timeleft) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) printk(MYIOC_s_WARN_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) "mpt cmd timeout, doorbell=0x%08x"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) " function=0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) ioc->name, mpt_GetIocState(ioc, 0), function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) if (function == MPI_FUNCTION_SCSI_TASK_MGMT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) mutex_unlock(&ioc->taskmgmt_cmds.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) mptctl_timeout_expired(ioc, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) mf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) goto retry_wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) goto done_free_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) if (function == MPI_FUNCTION_SCSI_TASK_MGMT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) mutex_unlock(&ioc->taskmgmt_cmds.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) mf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) /* If a valid reply frame, copy to the user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) * Offset 2: reply length in U32's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_RF_VALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) if (karg.maxReplyBytes < ioc->reply_sz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) sz = min(karg.maxReplyBytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 4*ioc->ioctl_cmds.reply[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) sz = min(ioc->reply_sz, 4*ioc->ioctl_cmds.reply[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) if (sz > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) if (copy_to_user(karg.replyFrameBufPtr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) ioc->ioctl_cmds.reply, sz)){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) printk(MYIOC_s_ERR_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) "%s@%d::mptctl_do_mpt_command - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) "Unable to write out reply frame %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) ioc->name, __FILE__, __LINE__, karg.replyFrameBufPtr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) rc = -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) goto done_free_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) /* If valid sense data, copy to user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_SENSE_VALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) sz = min(karg.maxSenseBytes, MPT_SENSE_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) if (sz > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) if (copy_to_user(karg.senseDataPtr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) ioc->ioctl_cmds.sense, sz)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) "Unable to write sense data to user %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) ioc->name, __FILE__, __LINE__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) karg.senseDataPtr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) rc = -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) goto done_free_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) /* If the overall status is _GOOD and data in, copy data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) * to user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) if ((ioc->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) (karg.dataInSize > 0) && (bufIn.kptr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) if (copy_to_user(karg.dataInBufPtr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) bufIn.kptr, karg.dataInSize)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) "Unable to write data to user %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) ioc->name, __FILE__, __LINE__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) karg.dataInBufPtr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) rc = -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) done_free_mem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) CLEAR_MGMT_STATUS(ioc->ioctl_cmds.status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) /* Free the allocated memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) if (bufOut.kptr != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) pci_free_consistent(ioc->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) bufOut.len, (void *) bufOut.kptr, dma_addr_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) if (bufIn.kptr != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) pci_free_consistent(ioc->pcidev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) bufIn.len, (void *) bufIn.kptr, dma_addr_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) /* mf is null if command issued successfully
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) * otherwise, failure occurred after mf acquired.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) if (mf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) mpt_free_msg_frame(ioc, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) /* Prototype Routine for the HOST INFO command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) * Outputs: None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) * Return: 0 if successful
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) * -EFAULT if data unavailable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) * -EBUSY if previous command timeout and IOC reset is not complete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) * -ENODEV if no such device/adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) * -ETIME if timer expires
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) * -ENOMEM if memory allocation error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) mptctl_hp_hostinfo(MPT_ADAPTER *ioc, unsigned long arg, unsigned int data_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) hp_host_info_t __user *uarg = (void __user *) arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) char *pbuf=NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) dma_addr_t buf_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) hp_host_info_t karg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) CONFIGPARMS cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) ConfigPageHeader_t hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) int rc, cim_rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) ToolboxIstwiReadWriteRequest_t *IstwiRWRequest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) MPT_FRAME_HDR *mf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) unsigned long timeleft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) u32 msgcontext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) /* Reset long to int. Should affect IA64 and SPARC only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) if (data_size == sizeof(hp_host_info_t))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) cim_rev = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) else if (data_size == sizeof(hp_host_info_rev0_t))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) cim_rev = 0; /* obsolete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) if (copy_from_user(&karg, uarg, sizeof(hp_host_info_t))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) printk(KERN_ERR MYNAM "%s@%d::mptctl_hp_host_info - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) "Unable to read in hp_host_info struct @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) __FILE__, __LINE__, uarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": mptctl_hp_hostinfo called.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) ioc->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) /* Fill in the data and return the structure to the calling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) * program
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) pdev = (struct pci_dev *) ioc->pcidev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) karg.vendor = pdev->vendor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) karg.device = pdev->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) karg.subsystem_id = pdev->subsystem_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) karg.subsystem_vendor = pdev->subsystem_vendor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) karg.devfn = pdev->devfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) karg.bus = pdev->bus->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) /* Save the SCSI host no. if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) * SCSI driver loaded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) if (ioc->sh != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) karg.host_no = ioc->sh->host_no;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) karg.host_no = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) /* Reformat the fw_version into a string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) snprintf(karg.fw_version, sizeof(karg.fw_version),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) "%.2hhu.%.2hhu.%.2hhu.%.2hhu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) ioc->facts.FWVersion.Struct.Major,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) ioc->facts.FWVersion.Struct.Minor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) ioc->facts.FWVersion.Struct.Unit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) ioc->facts.FWVersion.Struct.Dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) /* Issue a config request to get the device serial number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) hdr.PageVersion = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) hdr.PageLength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) hdr.PageNumber = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) cfg.cfghdr.hdr = &hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) cfg.physAddr = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) cfg.pageAddr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) cfg.dir = 0; /* read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) cfg.timeout = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) strncpy(karg.serial_number, " ", 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) if (mpt_config(ioc, &cfg) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) if (cfg.cfghdr.hdr->PageLength > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) /* Issue the second config page request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) if (pbuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) cfg.physAddr = buf_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) if (mpt_config(ioc, &cfg) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) ManufacturingPage0_t *pdata = (ManufacturingPage0_t *) pbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) if (strlen(pdata->BoardTracerNumber) > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) strlcpy(karg.serial_number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) pdata->BoardTracerNumber, 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) pbuf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) rc = mpt_GetIocState(ioc, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) switch (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) case MPI_IOC_STATE_OPERATIONAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) karg.ioc_status = HP_STATUS_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) case MPI_IOC_STATE_FAULT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) karg.ioc_status = HP_STATUS_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) case MPI_IOC_STATE_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) case MPI_IOC_STATE_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) karg.ioc_status = HP_STATUS_OTHER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) karg.base_io_addr = pci_resource_start(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) if ((ioc->bus_type == SAS) || (ioc->bus_type == FC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) karg.bus_phys_width = HP_BUS_WIDTH_UNK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) karg.bus_phys_width = HP_BUS_WIDTH_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) karg.hard_resets = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) karg.soft_resets = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) karg.timeouts = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) if (ioc->sh != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) if (hd && (cim_rev == 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) karg.hard_resets = ioc->hard_resets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) karg.soft_resets = ioc->soft_resets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) karg.timeouts = ioc->timeouts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) * Gather ISTWI(Industry Standard Two Wire Interface) Data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) "%s, no msg frames!!\n", ioc->name, __func__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) IstwiRWRequest = (ToolboxIstwiReadWriteRequest_t *)mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) msgcontext = IstwiRWRequest->MsgContext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) memset(IstwiRWRequest,0,sizeof(ToolboxIstwiReadWriteRequest_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) IstwiRWRequest->MsgContext = msgcontext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) IstwiRWRequest->Function = MPI_FUNCTION_TOOLBOX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) IstwiRWRequest->Tool = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) IstwiRWRequest->Flags = MPI_TB_ISTWI_FLAGS_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) IstwiRWRequest->NumAddressBytes = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) IstwiRWRequest->DataLength = cpu_to_le16(0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) if (pdev->devfn & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) IstwiRWRequest->DeviceAddr = 0xB2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) IstwiRWRequest->DeviceAddr = 0xB0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) if (!pbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) ioc->add_sge((char *)&IstwiRWRequest->SGL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) (MPT_SGE_FLAGS_SSIMPLE_READ|4), buf_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) IstwiRWRequest->MsgContext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) INITIALIZE_MGMT_STATUS(ioc->ioctl_cmds.status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) mpt_put_msg_frame(mptctl_id, ioc, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) retry_wait:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) timeleft = wait_for_completion_timeout(&ioc->ioctl_cmds.done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) HZ*MPT_IOCTL_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) if (!(ioc->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) retval = -ETIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) printk(MYIOC_s_WARN_FMT "%s: failed\n", ioc->name, __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) mpt_free_msg_frame(ioc, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) if (!timeleft) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) printk(MYIOC_s_WARN_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) "HOST INFO command timeout, doorbell=0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) ioc->name, mpt_GetIocState(ioc, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) mptctl_timeout_expired(ioc, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) goto retry_wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) *ISTWI Data Definition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) * pbuf[0] = FW_VERSION = 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) * pbuf[1] = Bay Count = 6 or 4 or 2, depending on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) * the config, you should be seeing one out of these three values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) * pbuf[2] = Drive Installed Map = bit pattern depend on which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) * bays have drives in them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) * pbuf[3] = Checksum (0x100 = (byte0 + byte2 + byte3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_RF_VALID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) karg.rsvd = *(u32 *)pbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) CLEAR_MGMT_STATUS(ioc->ioctl_cmds.status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) if (pbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) /* Copy the data from kernel memory to user memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_hpgethostinfo - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) "Unable to write out hp_host_info @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) ioc->name, __FILE__, __LINE__, uarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) /* Prototype Routine for the TARGET INFO command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) * Outputs: None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) * Return: 0 if successful
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) * -EFAULT if data unavailable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) * -EBUSY if previous command timeout and IOC reset is not complete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) * -ENODEV if no such device/adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) * -ETIME if timer expires
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) * -ENOMEM if memory allocation error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) mptctl_hp_targetinfo(MPT_ADAPTER *ioc, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) hp_target_info_t __user *uarg = (void __user *) arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) SCSIDevicePage0_t *pg0_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) SCSIDevicePage3_t *pg3_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) MPT_SCSI_HOST *hd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) hp_target_info_t karg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) int data_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) dma_addr_t page_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) CONFIGPARMS cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) ConfigPageHeader_t hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) int tmp, np, rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) if (copy_from_user(&karg, uarg, sizeof(hp_target_info_t))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) printk(KERN_ERR MYNAM "%s@%d::mptctl_hp_targetinfo - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) "Unable to read in hp_host_targetinfo struct @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) __FILE__, __LINE__, uarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) if (karg.hdr.id >= MPT_MAX_FC_DEVICES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_hp_targetinfo called.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) ioc->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) /* There is nothing to do for FCP parts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) if ((ioc->bus_type == SAS) || (ioc->bus_type == FC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) if ((ioc->spi_data.sdp0length == 0) || (ioc->sh == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) if (ioc->sh->host_no != karg.hdr.host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) /* Get the data transfer speeds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) data_sz = ioc->spi_data.sdp0length * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) pg0_alloc = pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) if (pg0_alloc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) hdr.PageVersion = ioc->spi_data.sdp0version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) hdr.PageLength = data_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) hdr.PageNumber = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) cfg.cfghdr.hdr = &hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) cfg.dir = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) cfg.timeout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) cfg.physAddr = page_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) cfg.pageAddr = (karg.hdr.channel << 8) | karg.hdr.id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) if ((rc = mpt_config(ioc, &cfg)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) np = le32_to_cpu(pg0_alloc->NegotiatedParameters);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) karg.negotiated_width = np & MPI_SCSIDEVPAGE0_NP_WIDE ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) HP_BUS_WIDTH_16 : HP_BUS_WIDTH_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) if (np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) tmp = (np & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) if (tmp < 0x09)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) karg.negotiated_speed = HP_DEV_SPEED_ULTRA320;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) else if (tmp <= 0x09)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) karg.negotiated_speed = HP_DEV_SPEED_ULTRA160;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) else if (tmp <= 0x0A)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) karg.negotiated_speed = HP_DEV_SPEED_ULTRA2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) else if (tmp <= 0x0C)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) karg.negotiated_speed = HP_DEV_SPEED_ULTRA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) else if (tmp <= 0x25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) karg.negotiated_speed = HP_DEV_SPEED_FAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) karg.negotiated_speed = HP_DEV_SPEED_ASYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) karg.negotiated_speed = HP_DEV_SPEED_ASYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg0_alloc, page_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) /* Set defaults
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) karg.message_rejects = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) karg.phase_errors = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) karg.parity_errors = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) karg.select_timeouts = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) /* Get the target error parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) hdr.PageVersion = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) hdr.PageLength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) hdr.PageNumber = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) cfg.cfghdr.hdr = &hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) cfg.dir = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) cfg.timeout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) cfg.physAddr = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) if ((mpt_config(ioc, &cfg) == 0) && (cfg.cfghdr.hdr->PageLength > 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) /* Issue the second config page request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) data_sz = (int) cfg.cfghdr.hdr->PageLength * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) pg3_alloc = pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) if (pg3_alloc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) cfg.physAddr = page_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) cfg.pageAddr = (karg.hdr.channel << 8) | karg.hdr.id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) if ((rc = mpt_config(ioc, &cfg)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) karg.message_rejects = (u32) le16_to_cpu(pg3_alloc->MsgRejectCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) karg.phase_errors = (u32) le16_to_cpu(pg3_alloc->PhaseErrorCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) karg.parity_errors = (u32) le16_to_cpu(pg3_alloc->ParityErrorCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) pci_free_consistent(ioc->pcidev, data_sz, (u8 *) pg3_alloc, page_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) hd = shost_priv(ioc->sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) if (hd != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) karg.select_timeouts = hd->sel_timeout[karg.hdr.id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) /* Copy the data from kernel memory to user memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) if (copy_to_user((char __user *)arg, &karg, sizeof(hp_target_info_t))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_hp_target_info - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) "Unable to write out mpt_ioctl_targetinfo struct @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) ioc->name, __FILE__, __LINE__, uarg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) static const struct file_operations mptctl_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) .llseek = no_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) .fasync = mptctl_fasync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) .unlocked_ioctl = mptctl_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) .compat_ioctl = compat_mpctl_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) static struct miscdevice mptctl_miscdev = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) MPT_MINOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) MYNAM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) &mptctl_fops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) compat_mptfwxfer_ioctl(struct file *filp, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) struct mpt_fw_xfer32 kfw32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) struct mpt_fw_xfer kfw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) MPT_ADAPTER *iocp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) int iocnum, iocnumX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) int nonblock = (filp->f_flags & O_NONBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) if (copy_from_user(&kfw32, (char __user *)arg, sizeof(kfw32)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) /* Verify intended MPT adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) iocnumX = kfw32.iocnum & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) (iocp == NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) printk(KERN_DEBUG MYNAM "::compat_mptfwxfer_ioctl @%d - ioc%d not found!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) __LINE__, iocnumX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "compat_mptfwxfer_ioctl() called\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) iocp->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) kfw.iocnum = iocnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) kfw.fwlen = kfw32.fwlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) kfw.bufp = compat_ptr(kfw32.bufp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) ret = mptctl_do_fw_download(iocp, kfw.bufp, kfw.fwlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) mutex_unlock(&iocp->ioctl_cmds.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) compat_mpt_command(struct file *filp, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) struct mpt_ioctl_command32 karg32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) struct mpt_ioctl_command32 __user *uarg = (struct mpt_ioctl_command32 __user *) arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) struct mpt_ioctl_command karg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) MPT_ADAPTER *iocp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) int iocnum, iocnumX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) int nonblock = (filp->f_flags & O_NONBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) if (copy_from_user(&karg32, (char __user *)arg, sizeof(karg32)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) /* Verify intended MPT adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) iocnumX = karg32.hdr.iocnum & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) (iocp == NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) printk(KERN_DEBUG MYNAM "::compat_mpt_command @%d - ioc%d not found!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) __LINE__, iocnumX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "compat_mpt_command() called\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) iocp->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) /* Copy data to karg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) karg.hdr.iocnum = karg32.hdr.iocnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) karg.hdr.port = karg32.hdr.port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) karg.timeout = karg32.timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) karg.maxReplyBytes = karg32.maxReplyBytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) karg.dataInSize = karg32.dataInSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) karg.dataOutSize = karg32.dataOutSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) karg.maxSenseBytes = karg32.maxSenseBytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) karg.dataSgeOffset = karg32.dataSgeOffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) karg.replyFrameBufPtr = (char __user *)(unsigned long)karg32.replyFrameBufPtr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) karg.dataInBufPtr = (char __user *)(unsigned long)karg32.dataInBufPtr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) karg.dataOutBufPtr = (char __user *)(unsigned long)karg32.dataOutBufPtr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) karg.senseDataPtr = (char __user *)(unsigned long)karg32.senseDataPtr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) /* Pass new structure to do_mpt_command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) ret = mptctl_do_mpt_command (iocp, karg, &uarg->MF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) mutex_unlock(&iocp->ioctl_cmds.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) static long compat_mpctl_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) mutex_lock(&mpctl_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) case MPTIOCINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) case MPTIOCINFO1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) case MPTIOCINFO2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) case MPTTARGETINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) case MPTEVENTQUERY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) case MPTEVENTENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) case MPTEVENTREPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) case MPTHARDRESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) case HP_GETHOSTINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) case HP_GETTARGETINFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) case MPTTEST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) ret = __mptctl_ioctl(f, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) case MPTCOMMAND32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) ret = compat_mpt_command(f, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) case MPTFWDOWNLOAD32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) ret = compat_mptfwxfer_ioctl(f, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) ret = -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) mutex_unlock(&mpctl_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) * mptctl_probe - Installs ioctl devices per bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) * @pdev: Pointer to pci_dev structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) * Returns 0 for success, non-zero for failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) mptctl_probe(struct pci_dev *pdev, const struct pci_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) mutex_init(&ioc->ioctl_cmds.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) init_completion(&ioc->ioctl_cmds.done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) * mptctl_remove - Removed ioctl devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) * @pdev: Pointer to pci_dev structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) mptctl_remove(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) static struct mpt_pci_driver mptctl_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) .probe = mptctl_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) .remove = mptctl_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) static int __init mptctl_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) int where = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) show_mptmod_ver(my_NAME, my_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) mpt_device_driver_register(&mptctl_driver, MPTCTL_DRIVER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) /* Register this device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) err = misc_register(&mptctl_miscdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) printk(KERN_ERR MYNAM ": Can't register misc device [minor=%d].\n", MPT_MINOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) goto out_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) printk(KERN_INFO MYNAM ": Registered with Fusion MPT base driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) printk(KERN_INFO MYNAM ": /dev/%s @ (major,minor=%d,%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) * Install our handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) ++where;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) "mptctl_reply");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) if (!mptctl_id || mptctl_id >= MPT_MAX_PROTOCOL_DRIVERS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) misc_deregister(&mptctl_miscdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) goto out_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) mptctl_taskmgmt_id = mpt_register(mptctl_taskmgmt_reply, MPTCTL_DRIVER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) "mptctl_taskmgmt_reply");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) if (!mptctl_taskmgmt_id || mptctl_taskmgmt_id >= MPT_MAX_PROTOCOL_DRIVERS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) mpt_deregister(mptctl_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) misc_deregister(&mptctl_miscdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) goto out_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) mpt_reset_register(mptctl_id, mptctl_ioc_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) mpt_event_register(mptctl_id, mptctl_event_process);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) out_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) mpt_device_driver_deregister(MPTCTL_DRIVER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) static void mptctl_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) misc_deregister(&mptctl_miscdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) printk(KERN_INFO MYNAM ": Deregistered /dev/%s @ (major,minor=%d,%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) /* De-register event handler from base module */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) mpt_event_deregister(mptctl_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) /* De-register reset handler from base module */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) mpt_reset_deregister(mptctl_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) /* De-register callback handler from base module */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) mpt_deregister(mptctl_taskmgmt_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) mpt_deregister(mptctl_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) mpt_device_driver_deregister(MPTCTL_DRIVER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) module_init(mptctl_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) module_exit(mptctl_exit);