Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *			Linux MegaRAID device driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * Copyright (c) 2002  LSI Logic Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  * Copyright (c) 2002  Red Hat, Inc. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  *	  - fixes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  *	  - speed-ups (list handling fixes, issued_list, optimizations.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  *	  - lots of cleanups.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  * Copyright (c) 2003  Christoph Hellwig  <hch@lst.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  *	  - new-style, hotplug-aware pci probing and scsi registration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  * Version : v2.00.4 Mon Nov 14 14:02:43 EST 2005 - Seokmann Ju
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  * 						<Seokmann.Ju@lsil.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19)  * Description: Linux device driver for LSI Logic MegaRAID controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21)  * Supported controllers: MegaRAID 418, 428, 438, 466, 762, 467, 471, 490, 493
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22)  *					518, 520, 531, 532
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24)  * This driver is supported by LSI Logic, with assistance from Red Hat, Dell,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25)  * and others. Please send updates to the mailing list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26)  * linux-scsi@vger.kernel.org .
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #include <linux/proc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #include <linux/reboot.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #include <scsi/scsicam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #include "scsi.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #include "megaraid.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #define MEGARAID_MODULE_VERSION "2.00.4"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) MODULE_AUTHOR ("sju@lsil.com");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) MODULE_DESCRIPTION ("LSI Logic MegaRAID legacy driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) MODULE_LICENSE ("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) MODULE_VERSION(MEGARAID_MODULE_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) static DEFINE_MUTEX(megadev_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) static unsigned int max_cmd_per_lun = DEF_CMD_PER_LUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) module_param(max_cmd_per_lun, uint, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) MODULE_PARM_DESC(max_cmd_per_lun, "Maximum number of commands which can be issued to a single LUN (default=DEF_CMD_PER_LUN=63)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) static unsigned short int max_sectors_per_io = MAX_SECTORS_PER_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) module_param(max_sectors_per_io, ushort, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) MODULE_PARM_DESC(max_sectors_per_io, "Maximum number of sectors per I/O request (default=MAX_SECTORS_PER_IO=128)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) static unsigned short int max_mbox_busy_wait = MBOX_BUSY_WAIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) module_param(max_mbox_busy_wait, ushort, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) MODULE_PARM_DESC(max_mbox_busy_wait, "Maximum wait for mailbox in microseconds if busy (default=MBOX_BUSY_WAIT=10)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) #define RDINDOOR(adapter)	readl((adapter)->mmio_base + 0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) #define RDOUTDOOR(adapter)	readl((adapter)->mmio_base + 0x2C)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) #define WRINDOOR(adapter,value)	 writel(value, (adapter)->mmio_base + 0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) #define WROUTDOOR(adapter,value) writel(value, (adapter)->mmio_base + 0x2C)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81)  * Global variables
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) static int hba_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) static adapter_t *hba_soft_state[MAX_CONTROLLERS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) static struct proc_dir_entry *mega_proc_dir_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) /* For controller re-ordering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) static struct mega_hbas mega_hbas[MAX_CONTROLLERS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) static long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) megadev_unlocked_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95)  * The File Operations structure for the serial/ioctl interface of the driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) static const struct file_operations megadev_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	.owner		= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	.unlocked_ioctl	= megadev_unlocked_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	.open		= megadev_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	.llseek		= noop_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105)  * Array to structures for storing the information about the controllers. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106)  * information is sent to the user level applications, when they do an ioctl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107)  * for this information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) static struct mcontroller mcontroller[MAX_CONTROLLERS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) /* The current driver version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) static u32 driver_ver = 0x02000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) /* major number used by the device for character interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) static int major;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) #define IS_RAID_CH(hba, ch)	(((hba)->mega_ch_class >> (ch)) & 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121)  * Debug variable to print some diagnostic messages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) static int trace_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126)  * mega_setup_mailbox()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127)  * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129)  * Allocates a 8 byte aligned memory for the handshake mailbox.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) mega_setup_mailbox(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	unsigned long	align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	adapter->una_mbox64 = dma_alloc_coherent(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 						 sizeof(mbox64_t),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 						 &adapter->una_mbox64_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 						 GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	if( !adapter->una_mbox64 ) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 		
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	adapter->mbox = &adapter->una_mbox64->mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	adapter->mbox = (mbox_t *)((((unsigned long) adapter->mbox) + 15) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 			(~0UL ^ 0xFUL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	adapter->mbox64 = (mbox64_t *)(((unsigned long)adapter->mbox) - 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	align = ((void *)adapter->mbox) - ((void *)&adapter->una_mbox64->mbox);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	adapter->mbox_dma = adapter->una_mbox64_dma + 8 + align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	 * Register the mailbox if the controller is an io-mapped controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	if( adapter->flag & BOARD_IOMAP ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 		outb(adapter->mbox_dma & 0xFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 				adapter->host->io_port + MBOX_PORT0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 		outb((adapter->mbox_dma >> 8) & 0xFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 				adapter->host->io_port + MBOX_PORT1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 		outb((adapter->mbox_dma >> 16) & 0xFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 				adapter->host->io_port + MBOX_PORT2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 		outb((adapter->mbox_dma >> 24) & 0xFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 				adapter->host->io_port + MBOX_PORT3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 		outb(ENABLE_MBOX_BYTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 				adapter->host->io_port + ENABLE_MBOX_REGION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 		irq_ack(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 		irq_enable(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184)  * mega_query_adapter()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185)  * @adapter - pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187)  * Issue the adapter inquiry commands to the controller and find out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188)  * information and parameter about the devices attached
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) mega_query_adapter(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	dma_addr_t	prod_info_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	mega_inquiry3	*inquiry3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	u8	raw_mbox[sizeof(struct mbox_out)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	mbox_t	*mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	int	retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	/* Initialize adapter inquiry mailbox */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	mbox = (mbox_t *)raw_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	memset(&mbox->m_out, 0, sizeof(raw_mbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	 * Try to issue Inquiry3 command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	 * if not succeeded, then issue MEGA_MBOXCMD_ADAPTERINQ command and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	 * update enquiry3 structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	mbox->m_out.xferaddr = (u32)adapter->buf_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	inquiry3 = (mega_inquiry3 *)adapter->mega_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	raw_mbox[0] = FC_NEW_CONFIG;		/* i.e. mbox->cmd=0xA1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	raw_mbox[2] = NC_SUBOP_ENQUIRY3;	/* i.e. 0x0F */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	raw_mbox[3] = ENQ3_GET_SOLICITED_FULL;	/* i.e. 0x02 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	/* Issue a blocking command to the card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	if ((retval = issue_scb_block(adapter, raw_mbox))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 		/* the adapter does not support 40ld */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 		mraid_ext_inquiry	*ext_inq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 		mraid_inquiry		*inq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 		dma_addr_t		dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 		ext_inq = dma_alloc_coherent(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 					     sizeof(mraid_ext_inquiry),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 					     &dma_handle, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 		if( ext_inq == NULL ) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 		inq = &ext_inq->raid_inq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 		mbox->m_out.xferaddr = (u32)dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 		/*issue old 0x04 command to adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 		mbox->m_out.cmd = MEGA_MBOXCMD_ADPEXTINQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 		issue_scb_block(adapter, raw_mbox);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 		 * update Enquiry3 and ProductInfo structures with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 		 * mraid_inquiry structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 		mega_8_to_40ld(inq, inquiry3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 				(mega_product_info *)&adapter->product_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 		dma_free_coherent(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 				  sizeof(mraid_ext_inquiry), ext_inq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 				  dma_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	} else {		/*adapter supports 40ld */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 		adapter->flag |= BOARD_40LD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 		 * get product_info, which is static information and will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 		 * unchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 		prod_info_dma_handle = dma_map_single(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 						      (void *)&adapter->product_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 						      sizeof(mega_product_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 						      DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 		mbox->m_out.xferaddr = prod_info_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 		raw_mbox[0] = FC_NEW_CONFIG;	/* i.e. mbox->cmd=0xA1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 		raw_mbox[2] = NC_SUBOP_PRODUCT_INFO;	/* i.e. 0x0E */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 		if ((retval = issue_scb_block(adapter, raw_mbox)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 			dev_warn(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 				"Product_info cmd failed with error: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 				retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 		dma_unmap_single(&adapter->dev->dev, prod_info_dma_handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 				 sizeof(mega_product_info), DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	 * kernel scans the channels from 0 to <= max_channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	adapter->host->max_channel =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 		adapter->product_info.nchannels + NVIRT_CHAN -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	adapter->host->max_id = 16;	/* max targets per channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	adapter->host->max_lun = 7;	/* Up to 7 luns for non disk devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	adapter->host->cmd_per_lun = max_cmd_per_lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	adapter->numldrv = inquiry3->num_ldrv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	adapter->max_cmds = adapter->product_info.max_commands;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	if(adapter->max_cmds > MAX_COMMANDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 		adapter->max_cmds = MAX_COMMANDS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	adapter->host->can_queue = adapter->max_cmds - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	 * Get the maximum number of scatter-gather elements supported by this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	 * firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	mega_get_max_sgl(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	adapter->host->sg_tablesize = adapter->sglen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	/* use HP firmware and bios version encoding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	   Note: fw_version[0|1] and bios_version[0|1] were originally shifted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	   right 8 bits making them zero. This 0 value was hardcoded to fix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	   sparse warnings. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	if (adapter->product_info.subsysvid == PCI_VENDOR_ID_HP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 		snprintf(adapter->fw_version, sizeof(adapter->fw_version),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 			 "%c%d%d.%d%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 			 adapter->product_info.fw_version[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 			 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 			 adapter->product_info.fw_version[1] & 0x0f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 			 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 			 adapter->product_info.fw_version[0] & 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 		snprintf(adapter->bios_version, sizeof(adapter->fw_version),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 			 "%c%d%d.%d%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 			 adapter->product_info.bios_version[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 			 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 			 adapter->product_info.bios_version[1] & 0x0f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 			 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 			 adapter->product_info.bios_version[0] & 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 		memcpy(adapter->fw_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 				(char *)adapter->product_info.fw_version, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 		adapter->fw_version[4] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 		memcpy(adapter->bios_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 				(char *)adapter->product_info.bios_version, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 		adapter->bios_version[4] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	dev_notice(&adapter->dev->dev, "[%s:%s] detected %d logical drives\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 		adapter->fw_version, adapter->bios_version, adapter->numldrv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	 * Do we support extended (>10 bytes) cdbs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 	adapter->support_ext_cdb = mega_support_ext_cdb(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	if (adapter->support_ext_cdb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 		dev_notice(&adapter->dev->dev, "supports extended CDBs\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354)  * mega_runpendq()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355)  * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357)  * Runs through the list of pending requests.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) mega_runpendq(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	if(!list_empty(&adapter->pending_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 		__mega_runpendq(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367)  * megaraid_queue()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368)  * @scmd - Issue this scsi command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369)  * @done - the callback hook into the scsi mid-layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371)  * The command queuing entry point for the mid-layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) megaraid_queue_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 	adapter_t	*adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	scb_t	*scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	int	busy=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	adapter = (adapter_t *)scmd->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	scmd->scsi_done = done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	 * Allocate and build a SCB request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	 * busy flag will be set if mega_build_cmd() command could not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	 * allocate scb. We will return non-zero status in that case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	 * NOTE: scb can be null even though certain commands completed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	 * successfully, e.g., MODE_SENSE and TEST_UNIT_READY, we would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	 * return 0 in that case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 	spin_lock_irqsave(&adapter->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	scb = mega_build_cmd(adapter, scmd, &busy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	if (!scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	scb->state |= SCB_PENDQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	list_add_tail(&scb->list, &adapter->pending_list);
^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) 	 * Check if the HBA is in quiescent state, e.g., during a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	 * delete logical drive opertion. If it is, don't run
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	 * the pending_list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	if (atomic_read(&adapter->quiescent) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 		mega_runpendq(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	busy = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	spin_unlock_irqrestore(&adapter->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	return busy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) static DEF_SCSI_QCMD(megaraid_queue)
^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)  * mega_allocate_scb()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421)  * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422)  * @cmd: scsi command from the mid-layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424)  * Allocate a SCB structure. This is the central structure for controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425)  * commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) static inline scb_t *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) mega_allocate_scb(adapter_t *adapter, struct scsi_cmnd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	struct list_head *head = &adapter->free_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	scb_t	*scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	/* Unlink command from Free List */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	if( !list_empty(head) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 		scb = list_entry(head->next, scb_t, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 		list_del_init(head->next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 		scb->state = SCB_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 		scb->cmd = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 		scb->dma_type = MEGA_DMA_TYPE_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 		return scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	return NULL;
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451)  * mega_get_ldrv_num()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452)  * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453)  * @cmd: scsi mid layer command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454)  * @channel: channel on the controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456)  * Calculate the logical drive number based on the information in scsi command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457)  * and the channel number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) mega_get_ldrv_num(adapter_t *adapter, struct scsi_cmnd *cmd, int channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	int		tgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 	int		ldrv_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	tgt = cmd->device->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	if ( tgt > adapter->this_id )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 		tgt--;	/* we do not get inquires for initiator id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	ldrv_num = (channel * 15) + tgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	 * If we have a logical drive with boot enabled, project it first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	if( adapter->boot_ldrv_enabled ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 		if( ldrv_num == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 			ldrv_num = adapter->boot_ldrv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 			if( ldrv_num <= adapter->boot_ldrv ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 				ldrv_num--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 			}
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	 * If "delete logical drive" feature is enabled on this controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	 * Do only if at least one delete logical drive operation was done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	 * Also, after logical drive deletion, instead of logical drive number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	 * the value returned should be 0x80+logical drive id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	 * These is valid only for IO commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	if (adapter->support_random_del && adapter->read_ldidmap )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 		switch (cmd->cmnd[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 		case READ_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 		case WRITE_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 		case READ_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 		case WRITE_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 			ldrv_num += 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	return ldrv_num;
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510)  * mega_build_cmd()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511)  * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512)  * @cmd: Prepare using this scsi command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513)  * @busy: busy flag if no resources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515)  * Prepares a command and scatter gather list for the controller. This routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516)  * also finds out if the commands is intended for a logical drive or a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517)  * physical device and prepares the controller command accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519)  * We also re-order the logical drives and physical devices based on their
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520)  * boot settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) static scb_t *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) mega_build_cmd(adapter_t *adapter, struct scsi_cmnd *cmd, int *busy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	mega_passthru	*pthru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	scb_t	*scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	mbox_t	*mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	u32	seg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	char	islogical;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	int	max_ldrv_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	int	channel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	int	target = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	int	ldrv_num = 0;   /* logical drive number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	 * We know what channels our logical drives are on - mega_find_card()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	islogical = adapter->logdrv_chan[cmd->device->channel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	 * The theory: If physical drive is chosen for boot, all the physical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	 * devices are exported before the logical drives, otherwise physical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	 * devices are pushed after logical drives, in which case - Kernel sees
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	 * the physical devices on virtual channel which is obviously converted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	 * to actual channel on the HBA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	if( adapter->boot_pdrv_enabled ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 		if( islogical ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 			/* logical channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 			channel = cmd->device->channel -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 				adapter->product_info.nchannels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 			/* this is physical channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 			channel = cmd->device->channel; 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 			target = cmd->device->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 			 * boot from a physical disk, that disk needs to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 			 * exposed first IF both the channels are SCSI, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 			 * booting from the second channel is not allowed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 			if( target == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 				target = adapter->boot_pdrv_tgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 			else if( target == adapter->boot_pdrv_tgt ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 				target = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 		if( islogical ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 			/* this is the logical channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 			channel = cmd->device->channel;	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 			/* physical channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 			channel = cmd->device->channel - NVIRT_CHAN;	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 			target = cmd->device->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	if(islogical) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 		/* have just LUN 0 for each target on virtual channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 		if (cmd->device->lun) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 			cmd->result = (DID_BAD_TARGET << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 			cmd->scsi_done(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 			return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 		ldrv_num = mega_get_ldrv_num(adapter, cmd, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 		max_ldrv_num = (adapter->flag & BOARD_40LD) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 			MAX_LOGICAL_DRIVES_40LD : MAX_LOGICAL_DRIVES_8LD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 		 * max_ldrv_num increases by 0x80 if some logical drive was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 		 * deleted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 		if(adapter->read_ldidmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 			max_ldrv_num += 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 		if(ldrv_num > max_ldrv_num ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 			cmd->result = (DID_BAD_TARGET << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 			cmd->scsi_done(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 			return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 		if( cmd->device->lun > 7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 			 * Do not support lun >7 for physically accessed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 			 * devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 			cmd->result = (DID_BAD_TARGET << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 			cmd->scsi_done(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 			return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	 * Logical drive commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	if(islogical) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 		switch (cmd->cmnd[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 		case TEST_UNIT_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) #if MEGA_HAVE_CLUSTERING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 			 * Do we support clustering and is the support enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 			 * If no, return success always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 			if( !adapter->has_cluster ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 				cmd->result = (DID_OK << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 				cmd->scsi_done(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 				return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 			if(!(scb = mega_allocate_scb(adapter, cmd))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 				*busy = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 				return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 			scb->raw_mbox[0] = MEGA_CLUSTER_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 			scb->raw_mbox[2] = MEGA_RESERVATION_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 			scb->raw_mbox[3] = ldrv_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 			scb->dma_direction = DMA_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 			return scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 			cmd->result = (DID_OK << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 			cmd->scsi_done(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 			return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 		case MODE_SENSE: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 			char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 			struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 			sg = scsi_sglist(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 			buf = kmap_atomic(sg_page(sg)) + sg->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 			memset(buf, 0, cmd->cmnd[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 			kunmap_atomic(buf - sg->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 			cmd->result = (DID_OK << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 			cmd->scsi_done(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 			return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 		case READ_CAPACITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 		case INQUIRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 			if(!(adapter->flag & (1L << cmd->device->channel))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 				dev_notice(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 					"scsi%d: scanning scsi channel %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 					"for logical drives\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 						adapter->host->host_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 						cmd->device->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 				adapter->flag |= (1L << cmd->device->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 			/* Allocate a SCB and initialize passthru */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 			if(!(scb = mega_allocate_scb(adapter, cmd))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 				*busy = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 				return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 			pthru = scb->pthru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 			mbox = (mbox_t *)scb->raw_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 			memset(mbox, 0, sizeof(scb->raw_mbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 			memset(pthru, 0, sizeof(mega_passthru));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 			pthru->timeout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 			pthru->ars = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 			pthru->reqsenselen = 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 			pthru->islogical = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 			pthru->logdrv = ldrv_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 			pthru->cdblen = cmd->cmd_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 			memcpy(pthru->cdb, cmd->cmnd, cmd->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 			if( adapter->has_64bit_addr ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 				mbox->m_out.cmd = MEGA_MBOXCMD_PASSTHRU64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 				mbox->m_out.cmd = MEGA_MBOXCMD_PASSTHRU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 			scb->dma_direction = DMA_FROM_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 			pthru->numsgelements = mega_build_sglist(adapter, scb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 				&pthru->dataxferaddr, &pthru->dataxferlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 			mbox->m_out.xferaddr = scb->pthru_dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 			return scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 		case READ_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 		case WRITE_6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 		case READ_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 		case WRITE_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 		case READ_12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 		case WRITE_12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 			/* Allocate a SCB and initialize mailbox */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 			if(!(scb = mega_allocate_scb(adapter, cmd))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 				*busy = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 				return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 			mbox = (mbox_t *)scb->raw_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 			memset(mbox, 0, sizeof(scb->raw_mbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 			mbox->m_out.logdrv = ldrv_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 			 * A little hack: 2nd bit is zero for all scsi read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 			 * commands and is set for all scsi write commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 			if( adapter->has_64bit_addr ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 				mbox->m_out.cmd = (*cmd->cmnd & 0x02) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 					MEGA_MBOXCMD_LWRITE64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 					MEGA_MBOXCMD_LREAD64 ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 				mbox->m_out.cmd = (*cmd->cmnd & 0x02) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 					MEGA_MBOXCMD_LWRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 					MEGA_MBOXCMD_LREAD ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 			 * 6-byte READ(0x08) or WRITE(0x0A) cdb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 			if( cmd->cmd_len == 6 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 				mbox->m_out.numsectors = (u32) cmd->cmnd[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 				mbox->m_out.lba =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 					((u32)cmd->cmnd[1] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 					((u32)cmd->cmnd[2] << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 					(u32)cmd->cmnd[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 				mbox->m_out.lba &= 0x1FFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) #if MEGA_HAVE_STATS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 				 * Take modulo 0x80, since the logical drive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 				 * number increases by 0x80 when a logical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 				 * drive was deleted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 				if (*cmd->cmnd == READ_6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 					adapter->nreads[ldrv_num%0x80]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 					adapter->nreadblocks[ldrv_num%0x80] +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 						mbox->m_out.numsectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 					adapter->nwrites[ldrv_num%0x80]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 					adapter->nwriteblocks[ldrv_num%0x80] +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 						mbox->m_out.numsectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 			 * 10-byte READ(0x28) or WRITE(0x2A) cdb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 			if( cmd->cmd_len == 10 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 				mbox->m_out.numsectors =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 					(u32)cmd->cmnd[8] |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 					((u32)cmd->cmnd[7] << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 				mbox->m_out.lba =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 					((u32)cmd->cmnd[2] << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 					((u32)cmd->cmnd[3] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 					((u32)cmd->cmnd[4] << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 					(u32)cmd->cmnd[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) #if MEGA_HAVE_STATS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 				if (*cmd->cmnd == READ_10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 					adapter->nreads[ldrv_num%0x80]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 					adapter->nreadblocks[ldrv_num%0x80] +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 						mbox->m_out.numsectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 					adapter->nwrites[ldrv_num%0x80]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 					adapter->nwriteblocks[ldrv_num%0x80] +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 						mbox->m_out.numsectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 			 * 12-byte READ(0xA8) or WRITE(0xAA) cdb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 			if( cmd->cmd_len == 12 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 				mbox->m_out.lba =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 					((u32)cmd->cmnd[2] << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 					((u32)cmd->cmnd[3] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 					((u32)cmd->cmnd[4] << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 					(u32)cmd->cmnd[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 				mbox->m_out.numsectors =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 					((u32)cmd->cmnd[6] << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 					((u32)cmd->cmnd[7] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 					((u32)cmd->cmnd[8] << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 					(u32)cmd->cmnd[9];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) #if MEGA_HAVE_STATS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 				if (*cmd->cmnd == READ_12) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 					adapter->nreads[ldrv_num%0x80]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 					adapter->nreadblocks[ldrv_num%0x80] +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 						mbox->m_out.numsectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 					adapter->nwrites[ldrv_num%0x80]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 					adapter->nwriteblocks[ldrv_num%0x80] +=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 						mbox->m_out.numsectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 			 * If it is a read command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 			if( (*cmd->cmnd & 0x0F) == 0x08 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 				scb->dma_direction = DMA_FROM_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 				scb->dma_direction = DMA_TO_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 			/* Calculate Scatter-Gather info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 			mbox->m_out.numsgelements = mega_build_sglist(adapter, scb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 					(u32 *)&mbox->m_out.xferaddr, &seg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 			return scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) #if MEGA_HAVE_CLUSTERING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 		case RESERVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 		case RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 			 * Do we support clustering and is the support enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 			if( ! adapter->has_cluster ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 				cmd->result = (DID_BAD_TARGET << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 				cmd->scsi_done(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 				return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 			/* Allocate a SCB and initialize mailbox */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 			if(!(scb = mega_allocate_scb(adapter, cmd))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 				*busy = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 				return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 			scb->raw_mbox[0] = MEGA_CLUSTER_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 			scb->raw_mbox[2] = ( *cmd->cmnd == RESERVE ) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 				MEGA_RESERVE_LD : MEGA_RELEASE_LD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 			scb->raw_mbox[3] = ldrv_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 			scb->dma_direction = DMA_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 			return scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 			cmd->result = (DID_BAD_TARGET << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 			cmd->scsi_done(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 			return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	 * Passthru drive commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 		/* Allocate a SCB and initialize passthru */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 		if(!(scb = mega_allocate_scb(adapter, cmd))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 			*busy = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 			return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 		mbox = (mbox_t *)scb->raw_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 		memset(mbox, 0, sizeof(scb->raw_mbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 		if( adapter->support_ext_cdb ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 			mega_prepare_extpassthru(adapter, scb, cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 					channel, target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 			mbox->m_out.cmd = MEGA_MBOXCMD_EXTPTHRU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 			mbox->m_out.xferaddr = scb->epthru_dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 			pthru = mega_prepare_passthru(adapter, scb, cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 					channel, target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 			/* Initialize mailbox */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 			if( adapter->has_64bit_addr ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 				mbox->m_out.cmd = MEGA_MBOXCMD_PASSTHRU64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 				mbox->m_out.cmd = MEGA_MBOXCMD_PASSTHRU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 			mbox->m_out.xferaddr = scb->pthru_dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 		return scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943)  * mega_prepare_passthru()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944)  * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945)  * @scb: our scsi control block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946)  * @cmd: scsi command from the mid-layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947)  * @channel: actual channel on the controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948)  * @target: actual id on the controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950)  * prepare a command for the scsi physical devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) static mega_passthru *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) mega_prepare_passthru(adapter_t *adapter, scb_t *scb, struct scsi_cmnd *cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 		      int channel, int target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	mega_passthru *pthru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	pthru = scb->pthru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	memset(pthru, 0, sizeof (mega_passthru));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	/* 0=6sec/1=60sec/2=10min/3=3hrs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	pthru->timeout = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	pthru->ars = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	pthru->reqsenselen = 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	pthru->islogical = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	pthru->channel = (adapter->flag & BOARD_40LD) ? 0 : channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	pthru->target = (adapter->flag & BOARD_40LD) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 		(channel << 4) | target : target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	pthru->cdblen = cmd->cmd_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	pthru->logdrv = cmd->device->lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	memcpy(pthru->cdb, cmd->cmnd, cmd->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	/* Not sure about the direction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	scb->dma_direction = DMA_BIDIRECTIONAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	/* Special Code for Handling READ_CAPA/ INQ using bounce buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	switch (cmd->cmnd[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	case INQUIRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	case READ_CAPACITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 		if(!(adapter->flag & (1L << cmd->device->channel))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 			dev_notice(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 				"scsi%d: scanning scsi channel %d [P%d] "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 				"for physical devices\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 					adapter->host->host_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 					cmd->device->channel, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 			adapter->flag |= (1L << cmd->device->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 		pthru->numsgelements = mega_build_sglist(adapter, scb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 				&pthru->dataxferaddr, &pthru->dataxferlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	return pthru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)  * mega_prepare_extpassthru()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)  * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)  * @scb: our scsi control block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)  * @cmd: scsi command from the mid-layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)  * @channel: actual channel on the controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)  * @target: actual id on the controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)  * prepare a command for the scsi physical devices. This rountine prepares
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)  * commands for devices which can take extended CDBs (>10 bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) static mega_ext_passthru *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) mega_prepare_extpassthru(adapter_t *adapter, scb_t *scb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 			 struct scsi_cmnd *cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 			 int channel, int target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	mega_ext_passthru	*epthru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	epthru = scb->epthru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	memset(epthru, 0, sizeof(mega_ext_passthru));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	/* 0=6sec/1=60sec/2=10min/3=3hrs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	epthru->timeout = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	epthru->ars = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	epthru->reqsenselen = 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	epthru->islogical = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	epthru->channel = (adapter->flag & BOARD_40LD) ? 0 : channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	epthru->target = (adapter->flag & BOARD_40LD) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 		(channel << 4) | target : target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	epthru->cdblen = cmd->cmd_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	epthru->logdrv = cmd->device->lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	memcpy(epthru->cdb, cmd->cmnd, cmd->cmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	/* Not sure about the direction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	scb->dma_direction = DMA_BIDIRECTIONAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 	switch(cmd->cmnd[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 	case INQUIRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	case READ_CAPACITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 		if(!(adapter->flag & (1L << cmd->device->channel))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 			dev_notice(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 				"scsi%d: scanning scsi channel %d [P%d] "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 				"for physical devices\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 					adapter->host->host_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 					cmd->device->channel, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 			adapter->flag |= (1L << cmd->device->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 		epthru->numsgelements = mega_build_sglist(adapter, scb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 				&epthru->dataxferaddr, &epthru->dataxferlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	return epthru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) __mega_runpendq(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	struct list_head *pos, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	/* Issue any pending commands to the card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	list_for_each_safe(pos, next, &adapter->pending_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 		scb = list_entry(pos, scb_t, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 		if( !(scb->state & SCB_ISSUED) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 			if( issue_scb(adapter, scb) != 0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 				return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)  * issue_scb()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)  * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)  * @scb: scsi control block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)  * Post a command to the card if the mailbox is available, otherwise return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)  * busy. We also take the scb from the pending list if the mailbox is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)  * available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) issue_scb(adapter_t *adapter, scb_t *scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	volatile mbox64_t	*mbox64 = adapter->mbox64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	volatile mbox_t		*mbox = adapter->mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	unsigned int	i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	if(unlikely(mbox->m_in.busy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 		do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 			udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 			i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 		} while( mbox->m_in.busy && (i < max_mbox_busy_wait) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 		if(mbox->m_in.busy) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	/* Copy mailbox data into host structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	memcpy((char *)&mbox->m_out, (char *)scb->raw_mbox, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 			sizeof(struct mbox_out));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	mbox->m_out.cmdid = scb->idx;	/* Set cmdid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	mbox->m_in.busy = 1;		/* Set busy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	 * Increment the pending queue counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	atomic_inc(&adapter->pend_cmds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	switch (mbox->m_out.cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	case MEGA_MBOXCMD_LREAD64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	case MEGA_MBOXCMD_LWRITE64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 	case MEGA_MBOXCMD_PASSTHRU64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	case MEGA_MBOXCMD_EXTPTHRU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 		mbox64->xfer_segment_lo = mbox->m_out.xferaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 		mbox64->xfer_segment_hi = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 		mbox->m_out.xferaddr = 0xFFFFFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 		mbox64->xfer_segment_lo = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 		mbox64->xfer_segment_hi = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 	 * post the command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 	scb->state |= SCB_ISSUED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	if( likely(adapter->flag & BOARD_MEMMAP) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 		mbox->m_in.poll = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 		mbox->m_in.ack = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 		WRINDOOR(adapter, adapter->mbox_dma | 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 		irq_enable(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 		issue_command(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)  * Wait until the controller's mailbox is available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) mega_busywait_mbox (adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	if (adapter->mbox->m_in.busy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 		return __mega_busywait_mbox(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)  * issue_scb_block()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)  * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)  * @raw_mbox: the mailbox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)  * Issue a scb in synchronous and non-interrupt mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) issue_scb_block(adapter_t *adapter, u_char *raw_mbox)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 	volatile mbox64_t *mbox64 = adapter->mbox64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	volatile mbox_t *mbox = adapter->mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 	u8	byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	/* Wait until mailbox is free */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 	if(mega_busywait_mbox (adapter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 		goto bug_blocked_mailbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 	/* Copy mailbox data into host structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 	memcpy((char *) mbox, raw_mbox, sizeof(struct mbox_out));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 	mbox->m_out.cmdid = 0xFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	mbox->m_in.busy = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 	switch (raw_mbox[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 	case MEGA_MBOXCMD_LREAD64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	case MEGA_MBOXCMD_LWRITE64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 	case MEGA_MBOXCMD_PASSTHRU64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	case MEGA_MBOXCMD_EXTPTHRU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 		mbox64->xfer_segment_lo = mbox->m_out.xferaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 		mbox64->xfer_segment_hi = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 		mbox->m_out.xferaddr = 0xFFFFFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 		mbox64->xfer_segment_lo = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 		mbox64->xfer_segment_hi = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 	if( likely(adapter->flag & BOARD_MEMMAP) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 		mbox->m_in.poll = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 		mbox->m_in.ack = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 		mbox->m_in.numstatus = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 		mbox->m_in.status = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 		WRINDOOR(adapter, adapter->mbox_dma | 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 		while((volatile u8)mbox->m_in.numstatus == 0xFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 			cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 		mbox->m_in.numstatus = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 		while( (volatile u8)mbox->m_in.poll != 0x77 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 			cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 		mbox->m_in.poll = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 		mbox->m_in.ack = 0x77;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 		WRINDOOR(adapter, adapter->mbox_dma | 0x2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 		while(RDINDOOR(adapter) & 0x2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 			cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 		irq_disable(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 		issue_command(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 		while (!((byte = irq_state(adapter)) & INTR_VALID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 			cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 		set_irq_state(adapter, byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 		irq_enable(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 		irq_ack(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	return mbox->m_in.status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) bug_blocked_mailbox:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 	dev_warn(&adapter->dev->dev, "Blocked mailbox......!!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 	udelay (1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)  * megaraid_isr_iomapped()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)  * @irq: irq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)  * @devp: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)  * Interrupt service routine for io-mapped controllers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)  * Find out if our device is interrupting. If yes, acknowledge the interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)  * and service the completed commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) static irqreturn_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) megaraid_isr_iomapped(int irq, void *devp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 	adapter_t	*adapter = devp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 	unsigned long	flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	u8	status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 	u8	nstatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 	u8	completed[MAX_FIRMWARE_STATUS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	u8	byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 	int	handled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	 * loop till F/W has more commands for us to complete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	spin_lock_irqsave(&adapter->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 		/* Check if a valid interrupt is pending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 		byte = irq_state(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 		if( (byte & VALID_INTR_BYTE) == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 			 * No more pending commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 			goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 		set_irq_state(adapter, byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 		while((nstatus = (volatile u8)adapter->mbox->m_in.numstatus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 				== 0xFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 			cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 		adapter->mbox->m_in.numstatus = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 		status = adapter->mbox->m_in.status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 		 * decrement the pending queue counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 		atomic_sub(nstatus, &adapter->pend_cmds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 		memcpy(completed, (void *)adapter->mbox->m_in.completed, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 				nstatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 		/* Acknowledge interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 		irq_ack(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 		mega_cmd_done(adapter, completed, nstatus, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 		mega_rundoneq(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 		handled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 		/* Loop through any pending requests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 		if(atomic_read(&adapter->quiescent) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 			mega_runpendq(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	} while(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)  out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	spin_unlock_irqrestore(&adapter->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	return IRQ_RETVAL(handled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)  * megaraid_isr_memmapped()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)  * @irq: irq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)  * @devp: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)  * Interrupt service routine for memory-mapped controllers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)  * Find out if our device is interrupting. If yes, acknowledge the interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)  * and service the completed commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) static irqreturn_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) megaraid_isr_memmapped(int irq, void *devp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 	adapter_t	*adapter = devp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	unsigned long	flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	u8	status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 	u32	dword = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 	u8	nstatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 	u8	completed[MAX_FIRMWARE_STATUS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	int	handled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 
^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) 	 * loop till F/W has more commands for us to complete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 	spin_lock_irqsave(&adapter->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 		/* Check if a valid interrupt is pending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 		dword = RDOUTDOOR(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 		if(dword != 0x10001234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 			 * No more pending commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 			goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 		WROUTDOOR(adapter, 0x10001234);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 		while((nstatus = (volatile u8)adapter->mbox->m_in.numstatus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 				== 0xFF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 			cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 		adapter->mbox->m_in.numstatus = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 		status = adapter->mbox->m_in.status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 		 * decrement the pending queue counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 		atomic_sub(nstatus, &adapter->pend_cmds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 		memcpy(completed, (void *)adapter->mbox->m_in.completed, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 				nstatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 		/* Acknowledge interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 		WRINDOOR(adapter, 0x2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 		handled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 		while( RDINDOOR(adapter) & 0x02 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 			cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 		mega_cmd_done(adapter, completed, nstatus, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 		mega_rundoneq(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 		/* Loop through any pending requests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 		if(atomic_read(&adapter->quiescent) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 			mega_runpendq(adapter);
^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) 	} while(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400)  out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 	spin_unlock_irqrestore(&adapter->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 	return IRQ_RETVAL(handled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)  * mega_cmd_done()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408)  * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)  * @completed: array of ids of completed commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)  * @nstatus: number of completed commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)  * @status: status of the last command completed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)  * Complete the commands and call the scsi mid-layer callback hooks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	mega_ext_passthru	*epthru = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	struct scatterlist	*sgl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	struct scsi_cmnd	*cmd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 	mega_passthru	*pthru = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 	mbox_t	*mbox = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 	u8	c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	scb_t	*scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 	int	islogical;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 	int	cmdid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 	int	i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 	 * for all the commands completed, call the mid-layer callback routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 	 * and free the scb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 	for( i = 0; i < nstatus; i++ ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 		cmdid = completed[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 		 * Only free SCBs for the commands coming down from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 		 * mid-layer, not for which were issued internally
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 		 * For internal command, restore the status returned by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 		 * firmware so that user can interpret it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 		if (cmdid == CMDID_INT_CMDS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 			scb = &adapter->int_scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 			list_del_init(&scb->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 			scb->state = SCB_FREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 			adapter->int_status = status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 			complete(&adapter->int_waitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 			scb = &adapter->scb_list[cmdid];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 			 * Make sure f/w has completed a valid command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 			if( !(scb->state & SCB_ISSUED) || scb->cmd == NULL ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 				dev_crit(&adapter->dev->dev, "invalid command "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 					"Id %d, scb->state:%x, scsi cmd:%p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 					cmdid, scb->state, scb->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 			 * Was a abort issued for this command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 			if( scb->state & SCB_ABORT ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 				dev_warn(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 					"aborted cmd [%x] complete\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 					scb->idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 				scb->cmd->result = (DID_ABORT << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 				list_add_tail(SCSI_LIST(scb->cmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 						&adapter->completed_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 				mega_free_scb(adapter, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 			 * Was a reset issued for this command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 			if( scb->state & SCB_RESET ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 				dev_warn(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 					"reset cmd [%x] complete\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 					scb->idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 				scb->cmd->result = (DID_RESET << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 				list_add_tail(SCSI_LIST(scb->cmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 						&adapter->completed_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 				mega_free_scb (adapter, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 			cmd = scb->cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 			pthru = scb->pthru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 			epthru = scb->epthru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 			mbox = (mbox_t *)scb->raw_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) #if MEGA_HAVE_STATS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 			int	logdrv = mbox->m_out.logdrv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 			islogical = adapter->logdrv_chan[cmd->channel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 			 * Maintain an error counter for the logical drive.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 			 * Some application like SNMP agent need such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 			 * statistics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 			if( status && islogical && (cmd->cmnd[0] == READ_6 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 						cmd->cmnd[0] == READ_10 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 						cmd->cmnd[0] == READ_12)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 				 * Logical drive number increases by 0x80 when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 				 * a logical drive is deleted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 				adapter->rd_errors[logdrv%0x80]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 			if( status && islogical && (cmd->cmnd[0] == WRITE_6 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 						cmd->cmnd[0] == WRITE_10 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 						cmd->cmnd[0] == WRITE_12)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 				 * Logical drive number increases by 0x80 when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 				 * a logical drive is deleted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 				adapter->wr_errors[logdrv%0x80]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 			}
^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) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 		 * Do not return the presence of hard disk on the channel so,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 		 * inquiry sent, and returned data==hard disk or removable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 		 * hard disk and not logical, request should return failure! -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 		 * PJ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 		islogical = adapter->logdrv_chan[cmd->device->channel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 		if( cmd->cmnd[0] == INQUIRY && !islogical ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 			sgl = scsi_sglist(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 			if( sg_page(sgl) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 				c = *(unsigned char *) sg_virt(&sgl[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 				dev_warn(&adapter->dev->dev, "invalid sg\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 				c = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 			if(IS_RAID_CH(adapter, cmd->device->channel) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 					((c & 0x1F ) == TYPE_DISK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 				status = 0xF0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 		/* clear result; otherwise, success returns corrupt value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 		cmd->result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 		/* Convert MegaRAID status to Linux error code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 		switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 		case 0x00:	/* SUCCESS , i.e. SCSI_STATUS_GOOD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 			cmd->result |= (DID_OK << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 		case 0x02:	/* ERROR_ABORTED, i.e.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 				   SCSI_STATUS_CHECK_CONDITION */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 			/* set sense_buffer and result fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 			if( mbox->m_out.cmd == MEGA_MBOXCMD_PASSTHRU ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 				mbox->m_out.cmd == MEGA_MBOXCMD_PASSTHRU64 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 				memcpy(cmd->sense_buffer, pthru->reqsensearea,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 						14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 				cmd->result = (DRIVER_SENSE << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 					(DID_OK << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 					(CHECK_CONDITION << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 				if (mbox->m_out.cmd == MEGA_MBOXCMD_EXTPTHRU) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 					memcpy(cmd->sense_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 						epthru->reqsensearea, 14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 					cmd->result = (DRIVER_SENSE << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 						(DID_OK << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 						(CHECK_CONDITION << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 					cmd->sense_buffer[0] = 0x70;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 					cmd->sense_buffer[2] = ABORTED_COMMAND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 					cmd->result |= (CHECK_CONDITION << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 		case 0x08:	/* ERR_DEST_DRIVE_FAILED, i.e.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 				   SCSI_STATUS_BUSY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 			cmd->result |= (DID_BUS_BUSY << 16) | status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) #if MEGA_HAVE_CLUSTERING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 			 * If TEST_UNIT_READY fails, we know
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 			 * MEGA_RESERVATION_STATUS failed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 			if( cmd->cmnd[0] == TEST_UNIT_READY ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 				cmd->result |= (DID_ERROR << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 					(RESERVATION_CONFLICT << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 			 * Error code returned is 1 if Reserve or Release
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 			 * failed or the input parameter is invalid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 			if( status == 1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 				(cmd->cmnd[0] == RESERVE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 					 cmd->cmnd[0] == RELEASE) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 				cmd->result |= (DID_ERROR << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 					(RESERVATION_CONFLICT << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 				cmd->result |= (DID_BAD_TARGET << 16)|status;
^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) 		mega_free_scb(adapter, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 		/* Add Scsi_Command to end of completed queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 		list_add_tail(SCSI_LIST(cmd), &adapter->completed_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648)  * mega_runpendq()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650)  * Run through the list of completed requests and finish it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) mega_rundoneq (adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 	struct scsi_cmnd *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 	struct list_head *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 	list_for_each(pos, &adapter->completed_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 		struct scsi_pointer* spos = (struct scsi_pointer *)pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 		cmd = list_entry(spos, struct scsi_cmnd, SCp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 		cmd->scsi_done(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 	INIT_LIST_HEAD(&adapter->completed_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671)  * Free a SCB structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672)  * Note: We assume the scsi commands associated with this scb is not free yet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) mega_free_scb(adapter_t *adapter, scb_t *scb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 	switch( scb->dma_type ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 	case MEGA_DMA_TYPE_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 	case MEGA_SGLIST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 		scsi_dma_unmap(scb->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 	}
^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) 	 * Remove from the pending list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 	list_del_init(&scb->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 	/* Link the scb back into free list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 	scb->state = SCB_FREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 	scb->cmd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 	list_add(&scb->list, &adapter->free_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 
^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) __mega_busywait_mbox (adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 	volatile mbox_t *mbox = adapter->mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 	long counter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 	for (counter = 0; counter < 10000; counter++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 		if (!mbox->m_in.busy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 		udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 		cond_resched();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 	return -1;		/* give up after 1 second */
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718)  * Copies data to SGLIST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719)  * Note: For 64 bit cards, we need a minimum of one SG element for read/write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) mega_build_sglist(adapter_t *adapter, scb_t *scb, u32 *buf, u32 *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 	struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 	struct scsi_cmnd	*cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 	int	sgcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 	int	idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 	cmd = scb->cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 	 * Copy Scatter-Gather list info into controller structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 	 * The number of sg elements returned must not exceed our limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 	sgcnt = scsi_dma_map(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 	scb->dma_type = MEGA_SGLIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 	BUG_ON(sgcnt > adapter->sglen || sgcnt < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 	*len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 	if (scsi_sg_count(cmd) == 1 && !adapter->has_64bit_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 		sg = scsi_sglist(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 		scb->dma_h_bulkdata = sg_dma_address(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 		*buf = (u32)scb->dma_h_bulkdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 		*len = sg_dma_len(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 	scsi_for_each_sg(cmd, sg, sgcnt, idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 		if (adapter->has_64bit_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 			scb->sgl64[idx].address = sg_dma_address(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 			*len += scb->sgl64[idx].length = sg_dma_len(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 			scb->sgl[idx].address = sg_dma_address(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 			*len += scb->sgl[idx].length = sg_dma_len(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 	/* Reset pointer and length fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 	*buf = scb->sgl_dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 	/* Return count of SG requests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 	return sgcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771)  * mega_8_to_40ld()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773)  * takes all info in AdapterInquiry structure and puts it into ProductInfo and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774)  * Enquiry3 structures for later use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) mega_8_to_40ld(mraid_inquiry *inquiry, mega_inquiry3 *enquiry3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 		mega_product_info *product_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 	product_info->max_commands = inquiry->adapter_info.max_commands;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 	enquiry3->rebuild_rate = inquiry->adapter_info.rebuild_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 	product_info->nchannels = inquiry->adapter_info.nchannels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 	for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 		product_info->fw_version[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 			inquiry->adapter_info.fw_version[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 		product_info->bios_version[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 			inquiry->adapter_info.bios_version[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 	enquiry3->cache_flush_interval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 		inquiry->adapter_info.cache_flush_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 	product_info->dram_size = inquiry->adapter_info.dram_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 	enquiry3->num_ldrv = inquiry->logdrv_info.num_ldrv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 	for (i = 0; i < MAX_LOGICAL_DRIVES_8LD; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 		enquiry3->ldrv_size[i] = inquiry->logdrv_info.ldrv_size[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 		enquiry3->ldrv_prop[i] = inquiry->logdrv_info.ldrv_prop[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 		enquiry3->ldrv_state[i] = inquiry->logdrv_info.ldrv_state[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 	for (i = 0; i < (MAX_PHYSICAL_DRIVES); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 		enquiry3->pdrv_state[i] = inquiry->pdrv_info.pdrv_state[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) mega_free_sgl(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 	scb_t	*scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 	int	i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 	for(i = 0; i < adapter->max_cmds; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 		scb = &adapter->scb_list[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 		if( scb->sgl64 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 			dma_free_coherent(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 					  sizeof(mega_sgl64) * adapter->sglen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 					  scb->sgl64, scb->sgl_dma_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 			scb->sgl64 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 		if( scb->pthru ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 			dma_free_coherent(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 					  sizeof(mega_passthru), scb->pthru,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 					  scb->pthru_dma_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 			scb->pthru = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 		if( scb->epthru ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 			dma_free_coherent(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 					  sizeof(mega_ext_passthru),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 					  scb->epthru, scb->epthru_dma_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 			scb->epthru = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849)  * Get information about the card/driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) const char *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) megaraid_info(struct Scsi_Host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 	static char buffer[512];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 	adapter_t *adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 	adapter = (adapter_t *)host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 	sprintf (buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 		 "LSI Logic MegaRAID %s %d commands %d targs %d chans %d luns",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 		 adapter->fw_version, adapter->product_info.max_commands,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 		 adapter->host->max_id, adapter->host->max_channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 		 (u32)adapter->host->max_lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 	return buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868)  * Abort a previous SCSI request. Only commands on the pending list can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869)  * aborted. All the commands issued to the F/W must complete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) megaraid_abort(struct scsi_cmnd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 	adapter_t	*adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 	int		rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 	adapter = (adapter_t *)cmd->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 	rval =  megaraid_abort_and_reset(adapter, cmd, SCB_ABORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) 	 * This is required here to complete any completed requests
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) 	 * to be communicated over to the mid layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) 	mega_rundoneq(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) megaraid_reset(struct scsi_cmnd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 	adapter_t	*adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 	megacmd_t	mc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 	int		rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 	adapter = (adapter_t *)cmd->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) #if MEGA_HAVE_CLUSTERING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 	mc.cmd = MEGA_CLUSTER_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 	mc.opcode = MEGA_RESET_RESERVATIONS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 	if( mega_internal_command(adapter, &mc, NULL) != 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 		dev_warn(&adapter->dev->dev, "reservation reset failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 		dev_info(&adapter->dev->dev, "reservation reset\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 	spin_lock_irq(&adapter->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 	rval =  megaraid_abort_and_reset(adapter, cmd, SCB_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 	 * This is required here to complete any completed requests
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 	 * to be communicated over to the mid layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 	mega_rundoneq(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 	spin_unlock_irq(&adapter->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927)  * megaraid_abort_and_reset()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928)  * @adapter: megaraid soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929)  * @cmd: scsi command to be aborted or reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930)  * @aor: abort or reset flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932)  * Try to locate the scsi command in the pending queue. If found and is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933)  * issued to the controller, abort/reset it. Otherwise return failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) megaraid_abort_and_reset(adapter_t *adapter, struct scsi_cmnd *cmd, int aor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 	struct list_head	*pos, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 	scb_t			*scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 	dev_warn(&adapter->dev->dev, "%s cmd=%x <c=%d t=%d l=%d>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 	     (aor == SCB_ABORT)? "ABORTING":"RESET",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 	     cmd->cmnd[0], cmd->device->channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 	     cmd->device->id, (u32)cmd->device->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 	if(list_empty(&adapter->pending_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 		return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 	list_for_each_safe(pos, next, &adapter->pending_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 		scb = list_entry(pos, scb_t, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 		if (scb->cmd == cmd) { /* Found command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 			scb->state |= aor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 			 * Check if this command has firmware ownership. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 			 * yes, we cannot reset this command. Whenever f/w
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 			 * completes this command, we will return appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 			 * status from ISR.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 			if( scb->state & SCB_ISSUED ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 				dev_warn(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 					"%s[%x], fw owner\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 					(aor==SCB_ABORT) ? "ABORTING":"RESET",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 					scb->idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 				return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) 				 * Not yet issued! Remove from the pending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 				 * list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 				dev_warn(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 					"%s-[%x], driver owner\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 					(aor==SCB_ABORT) ? "ABORTING":"RESET",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 					scb->idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 				mega_free_scb(adapter, scb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 				if( aor == SCB_ABORT ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 					cmd->result = (DID_ABORT << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 				else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 					cmd->result = (DID_RESET << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 				list_add_tail(SCSI_LIST(cmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 						&adapter->completed_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 				return SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 	return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) make_local_pdev(adapter_t *adapter, struct pci_dev **pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 	*pdev = pci_alloc_dev(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 	if( *pdev == NULL ) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 	memcpy(*pdev, adapter->dev, sizeof(struct pci_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) 	if (dma_set_mask(&(*pdev)->dev, DMA_BIT_MASK(32)) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 		kfree(*pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) free_local_pdev(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 	kfree(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027)  * mega_allocate_inquiry()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028)  * @dma_handle: handle returned for dma address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029)  * @pdev: handle to pci device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031)  * allocates memory for inquiry structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) static inline void *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) mega_allocate_inquiry(dma_addr_t *dma_handle, struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 	return dma_alloc_coherent(&pdev->dev, sizeof(mega_inquiry3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 				  dma_handle, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) mega_free_inquiry(void *inquiry, dma_addr_t dma_handle, struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 	dma_free_coherent(&pdev->dev, sizeof(mega_inquiry3), inquiry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) 			  dma_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) #ifdef CONFIG_PROC_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) /* Following code handles /proc fs  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053)  * proc_show_config()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054)  * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055)  * @v: File iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057)  * Display configuration information about the controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) proc_show_config(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 	adapter_t *adapter = m->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) 	seq_puts(m, MEGARAID_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) 	if(adapter->product_info.product_name[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 		seq_printf(m, "%s\n", adapter->product_info.product_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) 	seq_puts(m, "Controller Type: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 	if( adapter->flag & BOARD_MEMMAP )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) 		seq_puts(m, "438/466/467/471/493/518/520/531/532\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 		seq_puts(m, "418/428/434\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 	if(adapter->flag & BOARD_40LD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 		seq_puts(m, "Controller Supports 40 Logical Drives\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 	if(adapter->flag & BOARD_64BIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 		seq_puts(m, "Controller capable of 64-bit memory addressing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 	if( adapter->has_64bit_addr )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) 		seq_puts(m, "Controller using 64-bit memory addressing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) 		seq_puts(m, "Controller is not using 64-bit memory addressing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 	seq_printf(m, "Base = %08lx, Irq = %d, ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) 		   adapter->base, adapter->host->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) 	seq_printf(m, "Logical Drives = %d, Channels = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) 		   adapter->numldrv, adapter->product_info.nchannels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 	seq_printf(m, "Version =%s:%s, DRAM = %dMb\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 		   adapter->fw_version, adapter->bios_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 		   adapter->product_info.dram_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 	seq_printf(m, "Controller Queue Depth = %d, Driver Queue Depth = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 		   adapter->product_info.max_commands, adapter->max_cmds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 	seq_printf(m, "support_ext_cdb    = %d\n", adapter->support_ext_cdb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 	seq_printf(m, "support_random_del = %d\n", adapter->support_random_del);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 	seq_printf(m, "boot_ldrv_enabled  = %d\n", adapter->boot_ldrv_enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 	seq_printf(m, "boot_ldrv          = %d\n", adapter->boot_ldrv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 	seq_printf(m, "boot_pdrv_enabled  = %d\n", adapter->boot_pdrv_enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 	seq_printf(m, "boot_pdrv_ch       = %d\n", adapter->boot_pdrv_ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 	seq_printf(m, "boot_pdrv_tgt      = %d\n", adapter->boot_pdrv_tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 	seq_printf(m, "quiescent          = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 		   atomic_read(&adapter->quiescent));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) 	seq_printf(m, "has_cluster        = %d\n", adapter->has_cluster);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 	seq_puts(m, "\nModule Parameters:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) 	seq_printf(m, "max_cmd_per_lun    = %d\n", max_cmd_per_lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) 	seq_printf(m, "max_sectors_per_io = %d\n", max_sectors_per_io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117)  * proc_show_stat()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118)  * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119)  * @v: File iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121)  * Display statistical information about the I/O activity.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) proc_show_stat(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 	adapter_t *adapter = m->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) #if MEGA_HAVE_STATS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) 	int	i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) 	seq_puts(m, "Statistical Information for this controller\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 	seq_printf(m, "pend_cmds = %d\n", atomic_read(&adapter->pend_cmds));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) #if MEGA_HAVE_STATS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 	for(i = 0; i < adapter->numldrv; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) 		seq_printf(m, "Logical Drive %d:\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 		seq_printf(m, "\tReads Issued = %lu, Writes Issued = %lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 			   adapter->nreads[i], adapter->nwrites[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 		seq_printf(m, "\tSectors Read = %lu, Sectors Written = %lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 			   adapter->nreadblocks[i], adapter->nwriteblocks[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 		seq_printf(m, "\tRead errors = %lu, Write errors = %lu\n\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 			   adapter->rd_errors[i], adapter->wr_errors[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 	seq_puts(m, "IO and error counters not compiled in driver.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151)  * proc_show_mbox()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152)  * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153)  * @v: File iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155)  * Display mailbox information for the last command issued. This information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156)  * is good for debugging.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) proc_show_mbox(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 	adapter_t	*adapter = m->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) 	volatile mbox_t	*mbox = adapter->mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 	seq_puts(m, "Contents of Mail Box Structure\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) 	seq_printf(m, "  Fw Command   = 0x%02x\n", mbox->m_out.cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 	seq_printf(m, "  Cmd Sequence = 0x%02x\n", mbox->m_out.cmdid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 	seq_printf(m, "  No of Sectors= %04d\n", mbox->m_out.numsectors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 	seq_printf(m, "  LBA          = 0x%02x\n", mbox->m_out.lba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 	seq_printf(m, "  DTA          = 0x%08x\n", mbox->m_out.xferaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) 	seq_printf(m, "  Logical Drive= 0x%02x\n", mbox->m_out.logdrv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) 	seq_printf(m, "  No of SG Elmt= 0x%02x\n", mbox->m_out.numsgelements);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) 	seq_printf(m, "  Busy         = %01x\n", mbox->m_in.busy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) 	seq_printf(m, "  Status       = 0x%02x\n", mbox->m_in.status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179)  * proc_show_rebuild_rate()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180)  * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181)  * @v: File iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183)  * Display current rebuild rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) proc_show_rebuild_rate(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) 	adapter_t	*adapter = m->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) 	dma_addr_t	dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) 	caddr_t		inquiry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 	struct pci_dev	*pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 	if( make_local_pdev(adapter, &pdev) != 0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 	if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 		goto free_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) 	if( mega_adapinq(adapter, dma_handle) != 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) 		seq_puts(m, "Adapter inquiry failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) 		dev_warn(&adapter->dev->dev, "inquiry failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) 		goto free_inquiry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 	if( adapter->flag & BOARD_40LD )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 		seq_printf(m, "Rebuild Rate: [%d%%]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 			   ((mega_inquiry3 *)inquiry)->rebuild_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 		seq_printf(m, "Rebuild Rate: [%d%%]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 			((mraid_ext_inquiry *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 			 inquiry)->raid_inq.adapter_info.rebuild_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) free_inquiry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 	mega_free_inquiry(inquiry, dma_handle, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) free_pdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 	free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222)  * proc_show_battery()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223)  * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224)  * @v: File iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226)  * Display information about the battery module on the controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) proc_show_battery(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 	adapter_t	*adapter = m->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) 	dma_addr_t	dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 	caddr_t		inquiry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) 	struct pci_dev	*pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 	u8	battery_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 	if( make_local_pdev(adapter, &pdev) != 0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 	if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 		goto free_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 	if( mega_adapinq(adapter, dma_handle) != 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 		seq_puts(m, "Adapter inquiry failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 		dev_warn(&adapter->dev->dev, "inquiry failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 		goto free_inquiry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 	if( adapter->flag & BOARD_40LD ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 		battery_status = ((mega_inquiry3 *)inquiry)->battery_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) 		battery_status = ((mraid_ext_inquiry *)inquiry)->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 			raid_inq.adapter_info.battery_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 	 * Decode the battery status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 	seq_printf(m, "Battery Status:[%d]", battery_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 	if(battery_status == MEGA_BATT_CHARGE_DONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 		seq_puts(m, " Charge Done");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 	if(battery_status & MEGA_BATT_MODULE_MISSING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 		seq_puts(m, " Module Missing");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 	if(battery_status & MEGA_BATT_LOW_VOLTAGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) 		seq_puts(m, " Low Voltage");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) 	if(battery_status & MEGA_BATT_TEMP_HIGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) 		seq_puts(m, " Temperature High");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) 	if(battery_status & MEGA_BATT_PACK_MISSING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) 		seq_puts(m, " Pack Missing");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 	if(battery_status & MEGA_BATT_CHARGE_INPROG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) 		seq_puts(m, " Charge In-progress");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) 	if(battery_status & MEGA_BATT_CHARGE_FAIL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 		seq_puts(m, " Charge Fail");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) 	if(battery_status & MEGA_BATT_CYCLES_EXCEEDED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) 		seq_puts(m, " Cycles Exceeded");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 	seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) free_inquiry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 	mega_free_inquiry(inquiry, dma_handle, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) free_pdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 	free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297)  * Display scsi inquiry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) mega_print_inquiry(struct seq_file *m, char *scsi_inq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) 	int	i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) 	seq_puts(m, "  Vendor: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 	seq_write(m, scsi_inq + 8, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 	seq_puts(m, "  Model: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 	seq_write(m, scsi_inq + 16, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) 	seq_puts(m, "  Rev: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) 	seq_write(m, scsi_inq + 32, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) 	seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) 	i = scsi_inq[0] & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 	seq_printf(m, "  Type:   %s ", scsi_device_type(i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 	seq_printf(m, "                 ANSI SCSI revision: %02x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 		   scsi_inq[2] & 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 	if( (scsi_inq[2] & 0x07) == 1 && (scsi_inq[3] & 0x0f) == 1 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 		seq_puts(m, " CCS\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 		seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325)  * proc_show_pdrv()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326)  * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327)  * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328)  * @channel: channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330)  * Display information about the physical drives.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) proc_show_pdrv(struct seq_file *m, adapter_t *adapter, int channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 	dma_addr_t	dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) 	char		*scsi_inq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 	dma_addr_t	scsi_inq_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 	caddr_t		inquiry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 	struct pci_dev	*pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 	u8	*pdrv_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 	u8	state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 	int	tgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 	int	max_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 	int	i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 	if( make_local_pdev(adapter, &pdev) != 0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 	if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 		goto free_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) 	if( mega_adapinq(adapter, dma_handle) != 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 		seq_puts(m, "Adapter inquiry failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 		dev_warn(&adapter->dev->dev, "inquiry failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) 		goto free_inquiry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 	scsi_inq = dma_alloc_coherent(&pdev->dev, 256, &scsi_inq_dma_handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 				      GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 	if( scsi_inq == NULL ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 		seq_puts(m, "memory not available for scsi inq.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 		goto free_inquiry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) 	if( adapter->flag & BOARD_40LD ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 		pdrv_state = ((mega_inquiry3 *)inquiry)->pdrv_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 		pdrv_state = ((mraid_ext_inquiry *)inquiry)->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 			raid_inq.pdrv_info.pdrv_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 	max_channels = adapter->product_info.nchannels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 	if( channel >= max_channels ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 		goto free_pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 	for( tgt = 0; tgt <= MAX_TARGET; tgt++ ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 		i = channel*16 + tgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 		state = *(pdrv_state + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 		switch( state & 0x0F ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) 		case PDRV_ONLINE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 			seq_printf(m, "Channel:%2d Id:%2d State: Online",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) 				   channel, tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 		case PDRV_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 			seq_printf(m, "Channel:%2d Id:%2d State: Failed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 				   channel, tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 		case PDRV_RBLD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) 			seq_printf(m, "Channel:%2d Id:%2d State: Rebuild",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) 				   channel, tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 		case PDRV_HOTSPARE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) 			seq_printf(m, "Channel:%2d Id:%2d State: Hot spare",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 				   channel, tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 			seq_printf(m, "Channel:%2d Id:%2d State: Un-configured",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 				   channel, tgt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) 		 * This interface displays inquiries for disk drives
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 		 * only. Inquries for logical drives and non-disk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 		 * devices are available through /proc/scsi/scsi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) 		memset(scsi_inq, 0, 256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 		if( mega_internal_dev_inquiry(adapter, channel, tgt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 				scsi_inq_dma_handle) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 				(scsi_inq[0] & 0x1F) != TYPE_DISK ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 		 * Check for overflow. We print less than 240
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 		 * characters for inquiry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 		seq_puts(m, ".\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) 		mega_print_inquiry(m, scsi_inq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) free_pci:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 	dma_free_coherent(&pdev->dev, 256, scsi_inq, scsi_inq_dma_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) free_inquiry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 	mega_free_inquiry(inquiry, dma_handle, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) free_pdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 	free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442)  * proc_show_pdrv_ch0()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443)  * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444)  * @v: File iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446)  * Display information about the physical drives on physical channel 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) proc_show_pdrv_ch0(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) 	return proc_show_pdrv(m, m->private, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456)  * proc_show_pdrv_ch1()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457)  * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458)  * @v: File iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460)  * Display information about the physical drives on physical channel 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) proc_show_pdrv_ch1(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 	return proc_show_pdrv(m, m->private, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470)  * proc_show_pdrv_ch2()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471)  * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472)  * @v: File iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474)  * Display information about the physical drives on physical channel 2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) proc_show_pdrv_ch2(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 	return proc_show_pdrv(m, m->private, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484)  * proc_show_pdrv_ch3()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485)  * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486)  * @v: File iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488)  * Display information about the physical drives on physical channel 3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) proc_show_pdrv_ch3(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) 	return proc_show_pdrv(m, m->private, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498)  * proc_show_rdrv()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499)  * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500)  * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501)  * @start: starting logical drive to display
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502)  * @end: ending logical drive to display
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504)  * We do not print the inquiry information since its already available through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505)  * /proc/scsi/scsi interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) proc_show_rdrv(struct seq_file *m, adapter_t *adapter, int start, int end )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) 	dma_addr_t	dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) 	logdrv_param	*lparam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 	megacmd_t	mc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 	char		*disk_array;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) 	dma_addr_t	disk_array_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 	caddr_t		inquiry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) 	struct pci_dev	*pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 	u8	*rdrv_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) 	int	num_ldrv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) 	u32	array_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) 	int	i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) 	if( make_local_pdev(adapter, &pdev) != 0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) 	if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 		goto free_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 	if( mega_adapinq(adapter, dma_handle) != 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 		seq_puts(m, "Adapter inquiry failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 		dev_warn(&adapter->dev->dev, "inquiry failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 		goto free_inquiry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) 	memset(&mc, 0, sizeof(megacmd_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 	if( adapter->flag & BOARD_40LD ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 		array_sz = sizeof(disk_array_40ld);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 		rdrv_state = ((mega_inquiry3 *)inquiry)->ldrv_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 		num_ldrv = ((mega_inquiry3 *)inquiry)->num_ldrv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 		array_sz = sizeof(disk_array_8ld);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) 		rdrv_state = ((mraid_ext_inquiry *)inquiry)->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) 			raid_inq.logdrv_info.ldrv_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 		num_ldrv = ((mraid_ext_inquiry *)inquiry)->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 			raid_inq.logdrv_info.num_ldrv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 	disk_array = dma_alloc_coherent(&pdev->dev, array_sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) 					&disk_array_dma_handle, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 	if( disk_array == NULL ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 		seq_puts(m, "memory not available.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) 		goto free_inquiry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) 	mc.xferaddr = (u32)disk_array_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) 	if( adapter->flag & BOARD_40LD ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 		mc.cmd = FC_NEW_CONFIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 		mc.opcode = OP_DCMD_READ_CONFIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 		if( mega_internal_command(adapter, &mc, NULL) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) 			seq_puts(m, "40LD read config failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) 			goto free_pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) 		mc.cmd = NEW_READ_CONFIG_8LD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) 		if( mega_internal_command(adapter, &mc, NULL) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) 			mc.cmd = READ_CONFIG_8LD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) 			if( mega_internal_command(adapter, &mc, NULL) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) 				seq_puts(m, "8LD read config failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) 				goto free_pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) 	for( i = start; i < ( (end+1 < num_ldrv) ? end+1 : num_ldrv ); i++ ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) 		if( adapter->flag & BOARD_40LD ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) 			lparam =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) 			&((disk_array_40ld *)disk_array)->ldrv[i].lparam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) 			lparam =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) 			&((disk_array_8ld *)disk_array)->ldrv[i].lparam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) 		 * Check for overflow. We print less than 240 characters for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) 		 * information about each logical drive.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) 		seq_printf(m, "Logical drive:%2d:, ", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) 		switch( rdrv_state[i] & 0x0F ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 		case RDRV_OFFLINE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) 			seq_puts(m, "state: offline");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) 		case RDRV_DEGRADED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) 			seq_puts(m, "state: degraded");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) 		case RDRV_OPTIMAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) 			seq_puts(m, "state: optimal");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) 		case RDRV_DELETED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) 			seq_puts(m, "state: deleted");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) 			seq_puts(m, "state: unknown");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) 		 * Check if check consistency or initialization is going on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) 		 * for this logical drive.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) 		if( (rdrv_state[i] & 0xF0) == 0x20 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) 			seq_puts(m, ", check-consistency in progress");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) 		else if( (rdrv_state[i] & 0xF0) == 0x10 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) 			seq_puts(m, ", initialization in progress");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) 		
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) 		seq_putc(m, '\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) 		seq_printf(m, "Span depth:%3d, ", lparam->span_depth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) 		seq_printf(m, "RAID level:%3d, ", lparam->level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) 		seq_printf(m, "Stripe size:%3d, ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) 			   lparam->stripe_sz ? lparam->stripe_sz/2: 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 		seq_printf(m, "Row size:%3d\n", lparam->row_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) 		seq_puts(m, "Read Policy: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) 		switch(lparam->read_ahead) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) 		case NO_READ_AHEAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) 			seq_puts(m, "No read ahead, ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) 		case READ_AHEAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) 			seq_puts(m, "Read ahead, ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) 		case ADAP_READ_AHEAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) 			seq_puts(m, "Adaptive, ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) 		seq_puts(m, "Write Policy: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) 		switch(lparam->write_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) 		case WRMODE_WRITE_THRU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) 			seq_puts(m, "Write thru, ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) 		case WRMODE_WRITE_BACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) 			seq_puts(m, "Write back, ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) 		seq_puts(m, "Cache Policy: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) 		switch(lparam->direct_io) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) 		case CACHED_IO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) 			seq_puts(m, "Cached IO\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) 		case DIRECT_IO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) 			seq_puts(m, "Direct IO\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) 		}
^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) free_pci:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 	dma_free_coherent(&pdev->dev, array_sz, disk_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 			  disk_array_dma_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) free_inquiry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 	mega_free_inquiry(inquiry, dma_handle, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) free_pdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 	free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683)  * proc_show_rdrv_10()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684)  * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685)  * @v: File iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687)  * Display real time information about the logical drives 0 through 9.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) proc_show_rdrv_10(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 	return proc_show_rdrv(m, m->private, 0, 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697)  * proc_show_rdrv_20()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698)  * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699)  * @v: File iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701)  * Display real time information about the logical drives 0 through 9.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) proc_show_rdrv_20(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) 	return proc_show_rdrv(m, m->private, 10, 19);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711)  * proc_show_rdrv_30()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712)  * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713)  * @v: File iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715)  * Display real time information about the logical drives 0 through 9.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) proc_show_rdrv_30(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) 	return proc_show_rdrv(m, m->private, 20, 29);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725)  * proc_show_rdrv_40()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726)  * @m: Synthetic file construction data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727)  * @v: File iterator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729)  * Display real time information about the logical drives 0 through 9.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) proc_show_rdrv_40(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) 	return proc_show_rdrv(m, m->private, 30, 39);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738)  * mega_create_proc_entry()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739)  * @index: index in soft state array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740)  * @parent: parent node for this /proc entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742)  * Creates /proc entries for our controllers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) mega_create_proc_entry(int index, struct proc_dir_entry *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) 	adapter_t *adapter = hba_soft_state[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) 	struct proc_dir_entry *dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) 	u8 string[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) 	sprintf(string, "hba%d", adapter->host->host_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) 	dir = proc_mkdir_data(string, 0, parent, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) 	if (!dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) 		dev_warn(&adapter->dev->dev, "proc_mkdir failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) 	proc_create_single_data("config", S_IRUSR, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) 			proc_show_config, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) 	proc_create_single_data("stat", S_IRUSR, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) 			proc_show_stat, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) 	proc_create_single_data("mailbox", S_IRUSR, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) 			proc_show_mbox, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) #if MEGA_HAVE_ENH_PROC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) 	proc_create_single_data("rebuild-rate", S_IRUSR, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) 			proc_show_rebuild_rate, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) 	proc_create_single_data("battery-status", S_IRUSR, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) 			proc_show_battery, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) 	proc_create_single_data("diskdrives-ch0", S_IRUSR, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) 			proc_show_pdrv_ch0, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) 	proc_create_single_data("diskdrives-ch1", S_IRUSR, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) 			proc_show_pdrv_ch1, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) 	proc_create_single_data("diskdrives-ch2", S_IRUSR, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) 			proc_show_pdrv_ch2, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) 	proc_create_single_data("diskdrives-ch3", S_IRUSR, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) 			proc_show_pdrv_ch3, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) 	proc_create_single_data("raiddrives-0-9", S_IRUSR, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) 			proc_show_rdrv_10, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) 	proc_create_single_data("raiddrives-10-19", S_IRUSR, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) 			proc_show_rdrv_20, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) 	proc_create_single_data("raiddrives-20-29", S_IRUSR, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 			proc_show_rdrv_30, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 	proc_create_single_data("raiddrives-30-39", S_IRUSR, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 			proc_show_rdrv_40, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) static inline void mega_create_proc_entry(int index, struct proc_dir_entry *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796)  * megaraid_biosparam()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798)  * Return the disk geometry for a particular disk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) megaraid_biosparam(struct scsi_device *sdev, struct block_device *bdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) 		    sector_t capacity, int geom[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) 	adapter_t	*adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) 	int	heads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) 	int	sectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) 	int	cylinders;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) 	/* Get pointer to host config structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) 	adapter = (adapter_t *)sdev->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) 	if (IS_RAID_CH(adapter, sdev->channel)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) 			/* Default heads (64) & sectors (32) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) 			heads = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) 			sectors = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) 			cylinders = (ulong)capacity / (heads * sectors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) 			 * Handle extended translation size for logical drives
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) 			 * > 1Gb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) 			if ((ulong)capacity >= 0x200000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) 				heads = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 				sectors = 63;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) 				cylinders = (ulong)capacity / (heads * sectors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) 			/* return result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) 			geom[0] = heads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) 			geom[1] = sectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) 			geom[2] = cylinders;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) 		if (scsi_partsize(bdev, capacity, geom))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) 		dev_info(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) 			 "invalid partition on this disk on channel %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) 			 sdev->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) 		/* Default heads (64) & sectors (32) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) 		heads = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) 		sectors = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) 		cylinders = (ulong)capacity / (heads * sectors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) 		/* Handle extended translation size for logical drives > 1Gb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) 		if ((ulong)capacity >= 0x200000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 			heads = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) 			sectors = 63;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) 			cylinders = (ulong)capacity / (heads * sectors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) 		/* return result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) 		geom[0] = heads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) 		geom[1] = sectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) 		geom[2] = cylinders;
^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) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863)  * mega_init_scb()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864)  * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866)  * Allocate memory for the various pointers in the scb structures:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867)  * scatter-gather list pointer, passthru and extended passthru structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868)  * pointers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) mega_init_scb(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) 	scb_t	*scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) 	int	i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) 	for( i = 0; i < adapter->max_cmds; i++ ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) 		scb = &adapter->scb_list[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) 		scb->sgl64 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) 		scb->sgl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) 		scb->pthru = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) 		scb->epthru = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) 	for( i = 0; i < adapter->max_cmds; i++ ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 		scb = &adapter->scb_list[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) 		scb->idx = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) 		scb->sgl64 = dma_alloc_coherent(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) 						sizeof(mega_sgl64) * adapter->sglen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) 						&scb->sgl_dma_addr, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) 		scb->sgl = (mega_sglist *)scb->sgl64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 		if( !scb->sgl ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) 			dev_warn(&adapter->dev->dev, "RAID: Can't allocate sglist\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 			mega_free_sgl(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 		scb->pthru = dma_alloc_coherent(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 						sizeof(mega_passthru),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) 						&scb->pthru_dma_addr, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) 		if( !scb->pthru ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) 			dev_warn(&adapter->dev->dev, "RAID: Can't allocate passthru\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) 			mega_free_sgl(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) 		scb->epthru = dma_alloc_coherent(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) 						 sizeof(mega_ext_passthru),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) 						 &scb->epthru_dma_addr, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) 		if( !scb->epthru ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) 			dev_warn(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) 				"Can't allocate extended passthru\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) 			mega_free_sgl(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) 		scb->dma_type = MEGA_DMA_TYPE_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) 		 * Link to free list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) 		 * lock not required since we are loading the driver, so no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) 		 * commands possible right now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) 		scb->state = SCB_FREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) 		scb->cmd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) 		list_add(&scb->list, &adapter->free_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943)  * megadev_open()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944)  * @inode: unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945)  * @filep: unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947)  * Routines for the character/ioctl interface to the driver. Find out if this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948)  * is a valid open. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) megadev_open (struct inode *inode, struct file *filep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) 	 * Only allow superuser to access private ioctl interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) 	if( !capable(CAP_SYS_ADMIN) ) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963)  * megadev_ioctl()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964)  * @filep: Our device file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965)  * @cmd: ioctl command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966)  * @arg: user buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968)  * ioctl entry point for our private ioctl interface. We move the data in from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969)  * the user space, prepare the command (if necessary, convert the old MIMD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970)  * ioctl to new ioctl command), and issue a synchronous command to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971)  * controller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) megadev_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) 	adapter_t	*adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) 	nitioctl_t	uioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) 	int		adapno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) 	int		rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) 	mega_passthru	__user *upthru;	/* user address for passthru */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) 	mega_passthru	*pthru;		/* copy user passthru here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) 	dma_addr_t	pthru_dma_hndl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) 	void		*data = NULL;	/* data to be transferred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) 	dma_addr_t	data_dma_hndl;	/* dma handle for data xfer area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) 	megacmd_t	mc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) #if MEGA_HAVE_STATS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) 	megastat_t	__user *ustats = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) 	int		num_ldrv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) 	u32		uxferaddr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) 	struct pci_dev	*pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) 	 * Make sure only USCSICMD are issued through this interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) 	 * MIMD application would still fire different command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) 	if( (_IOC_TYPE(cmd) != MEGAIOC_MAGIC) && (cmd != USCSICMD) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) 	 * Check and convert a possible MIMD command to NIT command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) 	 * mega_m_to_n() copies the data from the user space, so we do not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) 	 * have to do it here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) 	 * NOTE: We will need some user address to copyout the data, therefore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) 	 * the inteface layer will also provide us with the required user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) 	 * addresses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) 	memset(&uioc, 0, sizeof(nitioctl_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) 	if( (rval = mega_m_to_n( (void __user *)arg, &uioc)) != 0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) 	switch( uioc.opcode ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) 	case GET_DRIVER_VER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) 		if( put_user(driver_ver, (u32 __user *)uioc.uioc_uaddr) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) 			return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) 	case GET_N_ADAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) 		if( put_user(hba_count, (u32 __user *)uioc.uioc_uaddr) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) 			return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) 		 * Shucks. MIMD interface returns a positive value for number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) 		 * of adapters. TODO: Change it to return 0 when there is no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) 		 * applicatio using mimd interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) 		return hba_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) 	case GET_ADAP_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) 		 * Which adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) 		if( (adapno = GETADAP(uioc.adapno)) >= hba_count )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) 			return (-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) 		if( copy_to_user(uioc.uioc_uaddr, mcontroller+adapno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) 				sizeof(struct mcontroller)) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) 			return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) #if MEGA_HAVE_STATS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) 	case GET_STATS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) 		 * Which adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) 		if( (adapno = GETADAP(uioc.adapno)) >= hba_count )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) 			return (-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) 		adapter = hba_soft_state[adapno];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) 		ustats = uioc.uioc_uaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) 		if( copy_from_user(&num_ldrv, &ustats->num_ldrv, sizeof(int)) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) 			return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) 		 * Check for the validity of the logical drive number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) 		if( num_ldrv >= MAX_LOGICAL_DRIVES_40LD ) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) 		if( copy_to_user(ustats->nreads, adapter->nreads,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) 					num_ldrv*sizeof(u32)) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) 		if( copy_to_user(ustats->nreadblocks, adapter->nreadblocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) 					num_ldrv*sizeof(u32)) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) 		if( copy_to_user(ustats->nwrites, adapter->nwrites,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) 					num_ldrv*sizeof(u32)) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) 		if( copy_to_user(ustats->nwriteblocks, adapter->nwriteblocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) 					num_ldrv*sizeof(u32)) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) 		if( copy_to_user(ustats->rd_errors, adapter->rd_errors,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) 					num_ldrv*sizeof(u32)) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) 		if( copy_to_user(ustats->wr_errors, adapter->wr_errors,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) 					num_ldrv*sizeof(u32)) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) 	case MBOX_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) 		 * Which adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) 		if( (adapno = GETADAP(uioc.adapno)) >= hba_count )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) 			return (-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) 		adapter = hba_soft_state[adapno];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) 		 * Deletion of logical drive is a special case. The adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) 		 * should be quiescent before this command is issued.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) 		if( uioc.uioc_rmbox[0] == FC_DEL_LOGDRV &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) 				uioc.uioc_rmbox[2] == OP_DEL_LOGDRV ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) 			 * Do we support this feature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) 			if( !adapter->support_random_del ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) 				dev_warn(&adapter->dev->dev, "logdrv "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) 					"delete on non-supporting F/W\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) 				return (-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) 			rval = mega_del_logdrv( adapter, uioc.uioc_rmbox[3] );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) 			if( rval == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) 				memset(&mc, 0, sizeof(megacmd_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) 				mc.status = rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) 				rval = mega_n_to_m((void __user *)arg, &mc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) 			return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) 		 * This interface only support the regular passthru commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) 		 * Reject extended passthru and 64-bit passthru
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) 		if( uioc.uioc_rmbox[0] == MEGA_MBOXCMD_PASSTHRU64 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) 			uioc.uioc_rmbox[0] == MEGA_MBOXCMD_EXTPTHRU ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) 			dev_warn(&adapter->dev->dev, "rejected passthru\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) 			return (-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) 		 * For all internal commands, the buffer must be allocated in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) 		 * <4GB address range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) 		if( make_local_pdev(adapter, &pdev) != 0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) 			return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) 		/* Is it a passthru command or a DCMD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) 		if( uioc.uioc_rmbox[0] == MEGA_MBOXCMD_PASSTHRU ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) 			/* Passthru commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) 			pthru = dma_alloc_coherent(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) 						   sizeof(mega_passthru),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) 						   &pthru_dma_hndl, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) 			if( pthru == NULL ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) 				free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) 				return (-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) 			 * The user passthru structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) 			upthru = (mega_passthru __user *)(unsigned long)MBOX(uioc)->xferaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) 			 * Copy in the user passthru here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) 			if( copy_from_user(pthru, upthru,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) 						sizeof(mega_passthru)) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) 				dma_free_coherent(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) 						  sizeof(mega_passthru),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) 						  pthru, pthru_dma_hndl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) 				free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) 				return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) 			 * Is there a data transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) 			if( pthru->dataxferlen ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) 				data = dma_alloc_coherent(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) 							  pthru->dataxferlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) 							  &data_dma_hndl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) 							  GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) 				if( data == NULL ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) 					dma_free_coherent(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) 							  sizeof(mega_passthru),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) 							  pthru,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) 							  pthru_dma_hndl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) 					free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) 					return (-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) 				 * Save the user address and point the kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) 				 * address at just allocated memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) 				uxferaddr = pthru->dataxferaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) 				pthru->dataxferaddr = data_dma_hndl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) 			 * Is data coming down-stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) 			if( pthru->dataxferlen && (uioc.flags & UIOC_WR) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) 				 * Get the user data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) 				if( copy_from_user(data, (char __user *)(unsigned long) uxferaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) 							pthru->dataxferlen) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) 					rval = (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) 					goto freemem_and_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) 			memset(&mc, 0, sizeof(megacmd_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) 			mc.cmd = MEGA_MBOXCMD_PASSTHRU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) 			mc.xferaddr = (u32)pthru_dma_hndl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) 			 * Issue the command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) 			mega_internal_command(adapter, &mc, pthru);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) 			rval = mega_n_to_m((void __user *)arg, &mc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) 			if( rval ) goto freemem_and_return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) 			 * Is data going up-stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) 			if( pthru->dataxferlen && (uioc.flags & UIOC_RD) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) 				if( copy_to_user((char __user *)(unsigned long) uxferaddr, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) 							pthru->dataxferlen) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) 					rval = (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) 			 * Send the request sense data also, irrespective of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) 			 * whether the user has asked for it or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) 			if (copy_to_user(upthru->reqsensearea,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) 					pthru->reqsensearea, 14))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) 				rval = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) freemem_and_return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) 			if( pthru->dataxferlen ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) 				dma_free_coherent(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) 						  pthru->dataxferlen, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) 						  data_dma_hndl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) 			dma_free_coherent(&pdev->dev, sizeof(mega_passthru),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) 					  pthru, pthru_dma_hndl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) 			free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) 			return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) 			/* DCMD commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) 			 * Is there a data transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) 			if( uioc.xferlen ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) 				data = dma_alloc_coherent(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) 							  uioc.xferlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) 							  &data_dma_hndl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) 							  GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) 				if( data == NULL ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) 					free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) 					return (-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) 				uxferaddr = MBOX(uioc)->xferaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) 			 * Is data coming down-stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) 			if( uioc.xferlen && (uioc.flags & UIOC_WR) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) 				 * Get the user data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) 				if( copy_from_user(data, (char __user *)(unsigned long) uxferaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) 							uioc.xferlen) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) 					dma_free_coherent(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) 							  uioc.xferlen, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) 							  data_dma_hndl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) 					free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) 					return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) 			memcpy(&mc, MBOX(uioc), sizeof(megacmd_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) 			mc.xferaddr = (u32)data_dma_hndl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) 			 * Issue the command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) 			mega_internal_command(adapter, &mc, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) 			rval = mega_n_to_m((void __user *)arg, &mc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) 			if( rval ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) 				if( uioc.xferlen ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) 					dma_free_coherent(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) 							  uioc.xferlen, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) 							  data_dma_hndl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) 				free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) 				return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) 			 * Is data going up-stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) 			if( uioc.xferlen && (uioc.flags & UIOC_RD) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) 				if( copy_to_user((char __user *)(unsigned long) uxferaddr, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) 							uioc.xferlen) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) 					rval = (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) 			if( uioc.xferlen ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) 				dma_free_coherent(&pdev->dev, uioc.xferlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) 						  data, data_dma_hndl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) 			free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) 			return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) 		return (-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) static long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) megadev_unlocked_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) 	mutex_lock(&megadev_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) 	ret = megadev_ioctl(filep, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) 	mutex_unlock(&megadev_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379)  * mega_m_to_n()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380)  * @arg: user address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381)  * @uioc: new ioctl structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383)  * A thin layer to convert older mimd interface ioctl structure to NIT ioctl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384)  * structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386)  * Converts the older mimd ioctl structure to newer NIT structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) mega_m_to_n(void __user *arg, nitioctl_t *uioc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) 	struct uioctl_t	uioc_mimd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) 	char	signature[8] = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) 	u8	opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) 	u8	subopcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) 	 * check is the application conforms to NIT. We do not have to do much
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) 	 * in that case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) 	 * We exploit the fact that the signature is stored in the very
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) 	 * beginning of the structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) 	if( copy_from_user(signature, arg, 7) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) 		return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) 	if( memcmp(signature, "MEGANIT", 7) == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) 		 * NOTE NOTE: The nit ioctl is still under flux because of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) 		 * change of mailbox definition, in HPE. No applications yet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) 		 * use this interface and let's not have applications use this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) 		 * interface till the new specifitions are in place.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) 		if( copy_from_user(uioc, arg, sizeof(nitioctl_t)) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) 			return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) 	 * Else assume we have mimd uioctl_t as arg. Convert to nitioctl_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) 	 * Get the user ioctl structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) 	if( copy_from_user(&uioc_mimd, arg, sizeof(struct uioctl_t)) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) 		return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) 	 * Get the opcode and subopcode for the commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) 	opcode = uioc_mimd.ui.fcs.opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) 	subopcode = uioc_mimd.ui.fcs.subopcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) 	switch (opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) 	case 0x82:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) 		switch (subopcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) 		case MEGAIOC_QDRVRVER:	/* Query driver version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) 			uioc->opcode = GET_DRIVER_VER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) 			uioc->uioc_uaddr = uioc_mimd.data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) 		case MEGAIOC_QNADAP:	/* Get # of adapters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) 			uioc->opcode = GET_N_ADAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) 			uioc->uioc_uaddr = uioc_mimd.data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) 		case MEGAIOC_QADAPINFO:	/* Get adapter information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) 			uioc->opcode = GET_ADAP_INFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) 			uioc->adapno = uioc_mimd.ui.fcs.adapno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) 			uioc->uioc_uaddr = uioc_mimd.data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) 			return(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) 	case 0x81:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) 		uioc->opcode = MBOX_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) 		uioc->adapno = uioc_mimd.ui.fcs.adapno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) 		memcpy(uioc->uioc_rmbox, uioc_mimd.mbox, 18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) 		uioc->xferlen = uioc_mimd.ui.fcs.length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) 		if( uioc_mimd.outlen ) uioc->flags = UIOC_RD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) 		if( uioc_mimd.inlen ) uioc->flags |= UIOC_WR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) 	case 0x80:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) 		uioc->opcode = MBOX_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) 		uioc->adapno = uioc_mimd.ui.fcs.adapno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) 		memcpy(uioc->uioc_rmbox, uioc_mimd.mbox, 18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) 		 * Choose the xferlen bigger of input and output data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) 		uioc->xferlen = uioc_mimd.outlen > uioc_mimd.inlen ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) 			uioc_mimd.outlen : uioc_mimd.inlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) 		if( uioc_mimd.outlen ) uioc->flags = UIOC_RD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) 		if( uioc_mimd.inlen ) uioc->flags |= UIOC_WR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) 		return (-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507)  * mega_n_to_m()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508)  * @arg: user address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509)  * @mc: mailbox command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511)  * Updates the status information to the application, depending on application
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512)  * conforms to older mimd ioctl interface or newer NIT ioctl interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) mega_n_to_m(void __user *arg, megacmd_t *mc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) 	nitioctl_t	__user *uiocp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) 	megacmd_t	__user *umc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) 	mega_passthru	__user *upthru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) 	struct uioctl_t	__user *uioc_mimd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) 	char	signature[8] = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) 	 * check is the application conforms to NIT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) 	if( copy_from_user(signature, arg, 7) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) 	if( memcmp(signature, "MEGANIT", 7) == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) 		uiocp = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) 		if( put_user(mc->status, (u8 __user *)&MBOX_P(uiocp)->status) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) 			return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) 		if( mc->cmd == MEGA_MBOXCMD_PASSTHRU ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) 			umc = MBOX_P(uiocp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) 			if (get_user(upthru, (mega_passthru __user * __user *)&umc->xferaddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) 				return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) 			if( put_user(mc->status, (u8 __user *)&upthru->scsistatus))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) 				return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) 		uioc_mimd = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) 		if( put_user(mc->status, (u8 __user *)&uioc_mimd->mbox[17]) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) 			return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) 		if( mc->cmd == MEGA_MBOXCMD_PASSTHRU ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) 			umc = (megacmd_t __user *)uioc_mimd->mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) 			if (get_user(upthru, (mega_passthru __user * __user *)&umc->xferaddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) 				return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) 			if( put_user(mc->status, (u8 __user *)&upthru->scsistatus) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) 				return (-EFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570)  * MEGARAID 'FW' commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574)  * mega_is_bios_enabled()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575)  * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577)  * issue command to find out if the BIOS is enabled for this controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) mega_is_bios_enabled(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) 	unsigned char	raw_mbox[sizeof(struct mbox_out)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) 	mbox_t	*mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) 	mbox = (mbox_t *)raw_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) 	memset(&mbox->m_out, 0, sizeof(raw_mbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) 	memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) 	mbox->m_out.xferaddr = (u32)adapter->buf_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) 	raw_mbox[0] = IS_BIOS_ENABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) 	raw_mbox[2] = GET_BIOS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) 	issue_scb_block(adapter, raw_mbox);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) 	return *(char *)adapter->mega_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603)  * mega_enum_raid_scsi()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604)  * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606)  * Find out what channels are RAID/SCSI. This information is used to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607)  * differentiate the virtual channels and physical channels and to support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608)  * ROMB feature and non-disk devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) mega_enum_raid_scsi(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) 	unsigned char raw_mbox[sizeof(struct mbox_out)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) 	mbox_t *mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) 	mbox = (mbox_t *)raw_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) 	memset(&mbox->m_out, 0, sizeof(raw_mbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) 	 * issue command to find out what channels are raid/scsi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) 	raw_mbox[0] = CHNL_CLASS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) 	raw_mbox[2] = GET_CHNL_CLASS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) 	memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) 	mbox->m_out.xferaddr = (u32)adapter->buf_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) 	 * Non-ROMB firmware fail this command, so all channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) 	 * must be shown RAID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) 	adapter->mega_ch_class = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) 	if(!issue_scb_block(adapter, raw_mbox)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) 		adapter->mega_ch_class = *((char *)adapter->mega_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) 	for( i = 0; i < adapter->product_info.nchannels; i++ ) { 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) 		if( (adapter->mega_ch_class >> i) & 0x01 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) 			dev_info(&adapter->dev->dev, "channel[%d] is raid\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) 					i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) 			dev_info(&adapter->dev->dev, "channel[%d] is scsi\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) 					i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658)  * mega_get_boot_drv()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659)  * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661)  * Find out which device is the boot device. Note, any logical drive or any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662)  * phyical device (e.g., a CDROM) can be designated as a boot device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) mega_get_boot_drv(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) 	struct private_bios_data	*prv_bios_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) 	unsigned char	raw_mbox[sizeof(struct mbox_out)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) 	mbox_t	*mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) 	u16	cksum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) 	u8	*cksum_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) 	u8	boot_pdrv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) 	int	i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) 	mbox = (mbox_t *)raw_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) 	memset(&mbox->m_out, 0, sizeof(raw_mbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) 	raw_mbox[0] = BIOS_PVT_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) 	raw_mbox[2] = GET_BIOS_PVT_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) 	memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) 	mbox->m_out.xferaddr = (u32)adapter->buf_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) 	adapter->boot_ldrv_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) 	adapter->boot_ldrv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) 	adapter->boot_pdrv_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) 	adapter->boot_pdrv_ch = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) 	adapter->boot_pdrv_tgt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) 	if(issue_scb_block(adapter, raw_mbox) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) 		prv_bios_data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) 			(struct private_bios_data *)adapter->mega_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) 		cksum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) 		cksum_p = (char *)prv_bios_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) 		for (i = 0; i < 14; i++ ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) 			cksum += (u16)(*cksum_p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) 		if (prv_bios_data->cksum == (u16)(0-cksum) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) 			 * If MSB is set, a physical drive is set as boot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) 			 * device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) 			if( prv_bios_data->boot_drv & 0x80 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) 				adapter->boot_pdrv_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) 				boot_pdrv = prv_bios_data->boot_drv & 0x7F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) 				adapter->boot_pdrv_ch = boot_pdrv / 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) 				adapter->boot_pdrv_tgt = boot_pdrv % 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) 				adapter->boot_ldrv_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) 				adapter->boot_ldrv = prv_bios_data->boot_drv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725)  * mega_support_random_del()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726)  * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728)  * Find out if this controller supports random deletion and addition of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729)  * logical drives
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) mega_support_random_del(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) 	unsigned char raw_mbox[sizeof(struct mbox_out)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) 	mbox_t *mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) 	int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) 	mbox = (mbox_t *)raw_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) 	memset(&mbox->m_out, 0, sizeof(raw_mbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) 	 * issue command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) 	raw_mbox[0] = FC_DEL_LOGDRV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) 	raw_mbox[2] = OP_SUP_DEL_LOGDRV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) 	rval = issue_scb_block(adapter, raw_mbox);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) 	return !rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755)  * mega_support_ext_cdb()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756)  * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758)  * Find out if this firmware support cdblen > 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) mega_support_ext_cdb(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) 	unsigned char raw_mbox[sizeof(struct mbox_out)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) 	mbox_t *mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) 	int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) 	mbox = (mbox_t *)raw_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) 	memset(&mbox->m_out, 0, sizeof(raw_mbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) 	 * issue command to find out if controller supports extended CDBs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) 	raw_mbox[0] = 0xA4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) 	raw_mbox[2] = 0x16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) 	rval = issue_scb_block(adapter, raw_mbox);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) 	return !rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783)  * mega_del_logdrv()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784)  * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785)  * @logdrv: logical drive to be deleted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787)  * Delete the specified logical drive. It is the responsibility of the user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788)  * app to let the OS know about this operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) mega_del_logdrv(adapter_t *adapter, int logdrv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) 	scb_t *scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) 	int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) 	 * Stop sending commands to the controller, queue them internally.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) 	 * When deletion is complete, ISR will flush the queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) 	atomic_set(&adapter->quiescent, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) 	 * Wait till all the issued commands are complete and there are no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) 	 * commands in the pending queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) 	while (atomic_read(&adapter->pend_cmds) > 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) 	       !list_empty(&adapter->pending_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) 		msleep(1000);	/* sleep for 1s */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) 	rval = mega_do_del_logdrv(adapter, logdrv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) 	spin_lock_irqsave(&adapter->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) 	 * If delete operation was successful, add 0x80 to the logical drive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) 	 * ids for commands in the pending queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) 	if (adapter->read_ldidmap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) 		struct list_head *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) 		list_for_each(pos, &adapter->pending_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) 			scb = list_entry(pos, scb_t, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) 			if (scb->pthru->logdrv < 0x80 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) 				scb->pthru->logdrv += 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) 	atomic_set(&adapter->quiescent, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) 	mega_runpendq(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) 	spin_unlock_irqrestore(&adapter->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) mega_do_del_logdrv(adapter_t *adapter, int logdrv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) 	megacmd_t	mc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) 	int	rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) 	memset( &mc, 0, sizeof(megacmd_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) 	mc.cmd = FC_DEL_LOGDRV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) 	mc.opcode = OP_DEL_LOGDRV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) 	mc.subopcode = logdrv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) 	rval = mega_internal_command(adapter, &mc, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) 	/* log this event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) 	if(rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) 		dev_warn(&adapter->dev->dev, "Delete LD-%d failed", logdrv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) 	 * After deleting first logical drive, the logical drives must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) 	 * addressed by adding 0x80 to the logical drive id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) 	adapter->read_ldidmap = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869)  * mega_get_max_sgl()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870)  * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872)  * Find out the maximum number of scatter-gather elements supported by this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873)  * version of the firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) mega_get_max_sgl(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) 	unsigned char	raw_mbox[sizeof(struct mbox_out)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) 	mbox_t	*mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) 	mbox = (mbox_t *)raw_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) 	memset(mbox, 0, sizeof(raw_mbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) 	memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) 	mbox->m_out.xferaddr = (u32)adapter->buf_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) 	raw_mbox[0] = MAIN_MISC_OPCODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) 	raw_mbox[2] = GET_MAX_SG_SUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) 	if( issue_scb_block(adapter, raw_mbox) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) 		 * f/w does not support this command. Choose the default value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) 		adapter->sglen = MIN_SGLIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) 		adapter->sglen = *((char *)adapter->mega_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) 		
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) 		 * Make sure this is not more than the resources we are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) 		 * planning to allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) 		if ( adapter->sglen > MAX_SGLIST )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) 			adapter->sglen = MAX_SGLIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915)  * mega_support_cluster()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916)  * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918)  * Find out if this firmware support cluster calls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) mega_support_cluster(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) 	unsigned char	raw_mbox[sizeof(struct mbox_out)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) 	mbox_t	*mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) 	mbox = (mbox_t *)raw_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) 	memset(mbox, 0, sizeof(raw_mbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) 	memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) 	mbox->m_out.xferaddr = (u32)adapter->buf_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) 	 * Try to get the initiator id. This command will succeed iff the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) 	 * clustering is available on this HBA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) 	raw_mbox[0] = MEGA_GET_TARGET_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) 	if( issue_scb_block(adapter, raw_mbox) == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) 		 * Cluster support available. Get the initiator target id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) 		 * Tell our id to mid-layer too.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) 		adapter->this_id = *(u32 *)adapter->mega_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) 		adapter->host->this_id = adapter->this_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) #ifdef CONFIG_PROC_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957)  * mega_adapinq()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958)  * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959)  * @dma_handle: DMA address of the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961)  * Issue internal commands while interrupts are available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962)  * We only issue direct mailbox commands from within the driver. ioctl()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963)  * interface using these routines can issue passthru commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) mega_adapinq(adapter_t *adapter, dma_addr_t dma_handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) 	megacmd_t	mc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) 	memset(&mc, 0, sizeof(megacmd_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) 	if( adapter->flag & BOARD_40LD ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) 		mc.cmd = FC_NEW_CONFIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) 		mc.opcode = NC_SUBOP_ENQUIRY3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) 		mc.subopcode = ENQ3_GET_SOLICITED_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) 		mc.cmd = MEGA_MBOXCMD_ADPEXTINQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) 	mc.xferaddr = (u32)dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) 	if ( mega_internal_command(adapter, &mc, NULL) != 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992)  * mega_internal_dev_inquiry()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993)  * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994)  * @ch: channel for this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995)  * @tgt: ID of this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996)  * @buf_dma_handle: DMA address of the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998)  * Issue the scsi inquiry for the specified device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) mega_internal_dev_inquiry(adapter_t *adapter, u8 ch, u8 tgt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) 		dma_addr_t buf_dma_handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) 	mega_passthru	*pthru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) 	dma_addr_t	pthru_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) 	megacmd_t	mc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) 	int		rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) 	struct pci_dev	*pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) 	 * For all internal commands, the buffer must be allocated in <4GB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) 	 * address range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) 	if( make_local_pdev(adapter, &pdev) != 0 ) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) 	pthru = dma_alloc_coherent(&pdev->dev, sizeof(mega_passthru),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) 				   &pthru_dma_handle, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) 	if( pthru == NULL ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) 		free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) 	pthru->timeout = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) 	pthru->ars = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) 	pthru->reqsenselen = 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) 	pthru->islogical = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) 	pthru->channel = (adapter->flag & BOARD_40LD) ? 0 : ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) 	pthru->target = (adapter->flag & BOARD_40LD) ? (ch << 4)|tgt : tgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) 	pthru->cdblen = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) 	pthru->cdb[0] = INQUIRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) 	pthru->cdb[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) 	pthru->cdb[2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) 	pthru->cdb[3] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) 	pthru->cdb[4] = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) 	pthru->cdb[5] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) 	pthru->dataxferaddr = (u32)buf_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) 	pthru->dataxferlen = 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) 	memset(&mc, 0, sizeof(megacmd_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) 	mc.cmd = MEGA_MBOXCMD_PASSTHRU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) 	mc.xferaddr = (u32)pthru_dma_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) 	rval = mega_internal_command(adapter, &mc, pthru);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) 	dma_free_coherent(&pdev->dev, sizeof(mega_passthru), pthru,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) 			  pthru_dma_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) 	free_local_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064)  * mega_internal_command()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065)  * @adapter: pointer to our soft state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066)  * @mc: the mailbox command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067)  * @pthru: Passthru structure for DCDB commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069)  * Issue the internal commands in interrupt mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070)  * The last argument is the address of the passthru structure if the command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071)  * to be fired is a passthru command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073)  * Note: parameter 'pthru' is null for non-passthru commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) 	scb_t	*scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) 	int	rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) 	 * The internal commands share one command id and hence are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) 	 * serialized. This is so because we want to reserve maximum number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) 	 * available command ids for the I/O commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) 	mutex_lock(&adapter->int_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) 	scb = &adapter->int_scb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) 	memset(scb, 0, sizeof(scb_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) 	scb->idx = CMDID_INT_CMDS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) 	scb->state |= SCB_ACTIVE | SCB_PENDQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) 	memcpy(scb->raw_mbox, mc, sizeof(megacmd_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) 	 * Is it a passthru command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) 	if (mc->cmd == MEGA_MBOXCMD_PASSTHRU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) 		scb->pthru = pthru;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) 	spin_lock_irqsave(&adapter->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) 	list_add_tail(&scb->list, &adapter->pending_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) 	 * Check if the HBA is in quiescent state, e.g., during a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) 	 * delete logical drive opertion. If it is, don't run
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) 	 * the pending_list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) 	if (atomic_read(&adapter->quiescent) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) 		mega_runpendq(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) 	spin_unlock_irqrestore(&adapter->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) 	wait_for_completion(&adapter->int_waitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) 	mc->status = rval = adapter->int_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) 	 * Print a debug message for all failed commands. Applications can use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) 	 * this information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) 	if (rval && trace_level) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) 		dev_info(&adapter->dev->dev, "cmd [%x, %x, %x] status:[%x]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) 			mc->cmd, mc->opcode, mc->subopcode, rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) 	mutex_unlock(&adapter->int_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) static struct scsi_host_template megaraid_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) 	.module				= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) 	.name				= "MegaRAID",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) 	.proc_name			= "megaraid_legacy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) 	.info				= megaraid_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) 	.queuecommand			= megaraid_queue,	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) 	.bios_param			= megaraid_biosparam,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) 	.max_sectors			= MAX_SECTORS_PER_IO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) 	.can_queue			= MAX_COMMANDS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) 	.this_id			= DEFAULT_INITIATOR_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) 	.sg_tablesize			= MAX_SGLIST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) 	.cmd_per_lun			= DEF_CMD_PER_LUN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) 	.eh_abort_handler		= megaraid_abort,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) 	.eh_device_reset_handler	= megaraid_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) 	.eh_bus_reset_handler		= megaraid_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) 	.eh_host_reset_handler		= megaraid_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) 	.no_write_same			= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) 	struct Scsi_Host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) 	adapter_t *adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) 	unsigned long mega_baseport, tbase, flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) 	u16 subsysid, subsysvid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) 	u8 pci_bus, pci_dev_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) 	int irq, i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) 	int error = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) 	if (hba_count >= MAX_CONTROLLERS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) 	if (pci_enable_device(pdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) 	pci_set_master(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) 	pci_bus = pdev->bus->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) 	pci_dev_func = pdev->devfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) 	 * The megaraid3 stuff reports the ID of the Intel part which is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) 	 * remotely specific to the megaraid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) 	if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) 		u16 magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) 		 * Don't fall over the Compaq management cards using the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) 		 * PCI identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) 		if (pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) 		    pdev->subsystem_device == 0xC000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) 			goto out_disable_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) 		/* Now check the magic signature byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) 		pci_read_config_word(pdev, PCI_CONF_AMISIG, &magic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) 		if (magic != HBA_SIGNATURE_471 && magic != HBA_SIGNATURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) 			goto out_disable_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) 		/* Ok it is probably a megaraid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) 	 * For these vendor and device ids, signature offsets are not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) 	 * valid and 64 bit is implicit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) 	if (id->driver_data & BOARD_64BIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) 		flag |= BOARD_64BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) 		u32 magic64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) 		pci_read_config_dword(pdev, PCI_CONF_AMISIG64, &magic64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) 		if (magic64 == HBA_SIGNATURE_64BIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) 			flag |= BOARD_64BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) 	subsysvid = pdev->subsystem_vendor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) 	subsysid = pdev->subsystem_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) 	dev_notice(&pdev->dev, "found 0x%4.04x:0x%4.04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) 		id->vendor, id->device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) 	/* Read the base port and IRQ from PCI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) 	mega_baseport = pci_resource_start(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) 	irq = pdev->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) 	tbase = mega_baseport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) 	if (pci_resource_flags(pdev, 0) & IORESOURCE_MEM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) 		flag |= BOARD_MEMMAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) 		if (!request_mem_region(mega_baseport, 128, "megaraid")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) 			dev_warn(&pdev->dev, "mem region busy!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) 			goto out_disable_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) 		mega_baseport = (unsigned long)ioremap(mega_baseport, 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225) 		if (!mega_baseport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) 			dev_warn(&pdev->dev, "could not map hba memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) 			goto out_release_region;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) 		flag |= BOARD_IOMAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) 		mega_baseport += 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) 		if (!request_region(mega_baseport, 16, "megaraid"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) 			goto out_disable_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) 	/* Initialize SCSI Host structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) 	host = scsi_host_alloc(&megaraid_template, sizeof(adapter_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) 	if (!host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) 		goto out_iounmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242) 	adapter = (adapter_t *)host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) 	memset(adapter, 0, sizeof(adapter_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245) 	dev_notice(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) 		"scsi%d:Found MegaRAID controller at 0x%lx, IRQ:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) 		host->host_no, mega_baseport, irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) 	adapter->base = mega_baseport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) 	if (flag & BOARD_MEMMAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) 		adapter->mmio_base = (void __iomem *) mega_baseport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) 	INIT_LIST_HEAD(&adapter->free_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) 	INIT_LIST_HEAD(&adapter->pending_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) 	INIT_LIST_HEAD(&adapter->completed_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) 	adapter->flag = flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) 	spin_lock_init(&adapter->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) 	host->cmd_per_lun = max_cmd_per_lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) 	host->max_sectors = max_sectors_per_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) 	adapter->dev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) 	adapter->host = host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) 	adapter->host->irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) 	if (flag & BOARD_MEMMAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) 		adapter->host->base = tbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) 		adapter->host->io_port = tbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) 		adapter->host->n_io_port = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) 	adapter->host->unique_id = (pci_bus << 8) | pci_dev_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) 	 * Allocate buffer to issue internal commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) 	adapter->mega_buffer = dma_alloc_coherent(&adapter->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) 						  MEGA_BUFFER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) 						  &adapter->buf_dma_handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) 						  GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) 	if (!adapter->mega_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) 		dev_warn(&pdev->dev, "out of RAM\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) 		goto out_host_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) 	adapter->scb_list = kmalloc_array(MAX_COMMANDS, sizeof(scb_t),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) 					  GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) 	if (!adapter->scb_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) 		dev_warn(&pdev->dev, "out of RAM\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) 		goto out_free_cmd_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) 	if (request_irq(irq, (adapter->flag & BOARD_MEMMAP) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) 				megaraid_isr_memmapped : megaraid_isr_iomapped,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) 					IRQF_SHARED, "megaraid", adapter)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) 		dev_warn(&pdev->dev, "Couldn't register IRQ %d!\n", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) 		goto out_free_scb_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) 	if (mega_setup_mailbox(adapter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) 		goto out_free_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) 	if (mega_query_adapter(adapter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) 		goto out_free_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) 	 * Have checks for some buggy f/w
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) 	if ((subsysid == 0x1111) && (subsysvid == 0x1111)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314) 		 * Which firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) 		if (!strcmp(adapter->fw_version, "3.00") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) 				!strcmp(adapter->fw_version, "3.01")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) 			dev_warn(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) 				"Your card is a Dell PERC "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321) 				"2/SC RAID controller with "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) 				"firmware\nmegaraid: 3.00 or 3.01.  "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) 				"This driver is known to have "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) 				"corruption issues\nmegaraid: with "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) 				"those firmware versions on this "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) 				"specific card.  In order\nmegaraid: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) 				"to protect your data, please upgrade "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) 				"your firmware to version\nmegaraid: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) 				"3.10 or later, available from the "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330) 				"Dell Technical Support web\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) 				"megaraid: site at\nhttp://support."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) 				"dell.com/us/en/filelib/download/"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) 				"index.asp?fileid=2940\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) 			);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339) 	 * If we have a HP 1M(0x60E7)/2M(0x60E8) controller with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340) 	 * firmware H.01.07, H.01.08, and H.01.09 disable 64 bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) 	 * support, since this firmware cannot handle 64 bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342) 	 * addressing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) 	if ((subsysvid == PCI_VENDOR_ID_HP) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345) 	    ((subsysid == 0x60E7) || (subsysid == 0x60E8))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) 		 * which firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349) 		if (!strcmp(adapter->fw_version, "H01.07") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) 		    !strcmp(adapter->fw_version, "H01.08") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) 		    !strcmp(adapter->fw_version, "H01.09") ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) 			dev_warn(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353) 				"Firmware H.01.07, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) 				"H.01.08, and H.01.09 on 1M/2M "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) 				"controllers\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) 				"do not support 64 bit "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) 				"addressing.\nDISABLING "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) 				"64 bit support.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) 			adapter->flag &= ~BOARD_64BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363) 	if (mega_is_bios_enabled(adapter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) 		mega_hbas[hba_count].is_bios_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365) 	mega_hbas[hba_count].hostdata_addr = adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) 	 * Find out which channel is raid and which is scsi. This is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) 	 * for ROMB support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) 	mega_enum_raid_scsi(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) 	 * Find out if a logical drive is set as the boot drive. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375) 	 * there is one, will make that as the first logical drive.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) 	 * ROMB: Do we have to boot from a physical drive. Then all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) 	 * the physical drives would appear before the logical disks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) 	 * Else, all the physical drives would be exported to the mid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) 	 * layer after logical drives.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381) 	mega_get_boot_drv(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) 	if (adapter->boot_pdrv_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384) 		j = adapter->product_info.nchannels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) 		for( i = 0; i < j; i++ )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) 			adapter->logdrv_chan[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) 		for( i = j; i < NVIRT_CHAN + j; i++ )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) 			adapter->logdrv_chan[i] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390) 		for (i = 0; i < NVIRT_CHAN; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) 			adapter->logdrv_chan[i] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) 		for (i = NVIRT_CHAN; i < MAX_CHANNELS+NVIRT_CHAN; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393) 			adapter->logdrv_chan[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) 		adapter->mega_ch_class <<= NVIRT_CHAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) 	 * Do we support random deletion and addition of logical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) 	 * drives
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) 	adapter->read_ldidmap = 0;	/* set it after first logdrv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) 						   delete cmd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) 	adapter->support_random_del = mega_support_random_del(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) 	/* Initialize SCBs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) 	if (mega_init_scb(adapter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407) 		goto out_free_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) 	 * Reset the pending commands counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412) 	atomic_set(&adapter->pend_cmds, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415) 	 * Reset the adapter quiescent flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) 	atomic_set(&adapter->quiescent, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419) 	hba_soft_state[hba_count] = adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) 	 * Fill in the structure which needs to be passed back to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) 	 * application when it does an ioctl() for controller related
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) 	 * information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426) 	i = hba_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428) 	mcontroller[i].base = mega_baseport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) 	mcontroller[i].irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) 	mcontroller[i].numldrv = adapter->numldrv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431) 	mcontroller[i].pcibus = pci_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432) 	mcontroller[i].pcidev = id->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) 	mcontroller[i].pcifun = PCI_FUNC (pci_dev_func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) 	mcontroller[i].pciid = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) 	mcontroller[i].pcivendor = id->vendor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436) 	mcontroller[i].pcislot = PCI_SLOT(pci_dev_func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) 	mcontroller[i].uid = (pci_bus << 8) | pci_dev_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) 	/* Set the Mode of addressing to 64 bit if we can */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) 	if ((adapter->flag & BOARD_64BIT) && (sizeof(dma_addr_t) == 8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) 		dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443) 		adapter->has_64bit_addr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444) 	} else  {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) 		dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) 		adapter->has_64bit_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448) 		
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) 	mutex_init(&adapter->int_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) 	init_completion(&adapter->int_waitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) 	adapter->this_id = DEFAULT_INITIATOR_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453) 	adapter->host->this_id = DEFAULT_INITIATOR_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) #if MEGA_HAVE_CLUSTERING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) 	 * Is cluster support enabled on this controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) 	 * Note: In a cluster the HBAs ( the initiators ) will have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) 	 * different target IDs and we cannot assume it to be 7. Call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) 	 * to mega_support_cluster() will get the target ids also if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461) 	 * the cluster support is available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) 	adapter->has_cluster = mega_support_cluster(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) 	if (adapter->has_cluster) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) 		dev_notice(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) 			"Cluster driver, initiator id:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) 			adapter->this_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) 	pci_set_drvdata(pdev, host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473) 	mega_create_proc_entry(hba_count, mega_proc_dir_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) 	error = scsi_add_host(host, &pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) 		goto out_free_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) 	scsi_scan_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) 	hba_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483)  out_free_mbox:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484) 	dma_free_coherent(&adapter->dev->dev, sizeof(mbox64_t),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) 			  adapter->una_mbox64, adapter->una_mbox64_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486)  out_free_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487) 	free_irq(adapter->host->irq, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488)  out_free_scb_list:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) 	kfree(adapter->scb_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490)  out_free_cmd_buffer:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) 	dma_free_coherent(&adapter->dev->dev, MEGA_BUFFER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) 			  adapter->mega_buffer, adapter->buf_dma_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493)  out_host_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494) 	scsi_host_put(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495)  out_iounmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) 	if (flag & BOARD_MEMMAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) 		iounmap((void *)mega_baseport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498)  out_release_region:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) 	if (flag & BOARD_MEMMAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) 		release_mem_region(tbase, 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) 		release_region(mega_baseport, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503)  out_disable_device:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504) 	pci_disable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) __megaraid_shutdown(adapter_t *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) 	u_char	raw_mbox[sizeof(struct mbox_out)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513) 	mbox_t	*mbox = (mbox_t *)raw_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) 	int	i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) 	/* Flush adapter cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) 	memset(&mbox->m_out, 0, sizeof(raw_mbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) 	raw_mbox[0] = FLUSH_ADAPTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520) 	free_irq(adapter->host->irq, adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) 	/* Issue a blocking (interrupts disabled) command to the card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) 	issue_scb_block(adapter, raw_mbox);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) 	/* Flush disks cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) 	memset(&mbox->m_out, 0, sizeof(raw_mbox));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) 	raw_mbox[0] = FLUSH_SYSTEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) 	/* Issue a blocking (interrupts disabled) command to the card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) 	issue_scb_block(adapter, raw_mbox);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532) 	if (atomic_read(&adapter->pend_cmds) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533) 		dev_warn(&adapter->dev->dev, "pending commands!!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) 	 * Have a delibrate delay to make sure all the caches are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) 	 * actually flushed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) 	for (i = 0; i <= 10; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540) 		mdelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544) megaraid_remove_one(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) 	struct Scsi_Host *host = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547) 	adapter_t *adapter = (adapter_t *)host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548) 	char buf[12] = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) 	scsi_remove_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552) 	__megaraid_shutdown(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) 	/* Free our resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) 	if (adapter->flag & BOARD_MEMMAP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) 		iounmap((void *)adapter->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557) 		release_mem_region(adapter->host->base, 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) 		release_region(adapter->base, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561) 	mega_free_sgl(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563) 	sprintf(buf, "hba%d", adapter->host->host_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) 	remove_proc_subtree(buf, mega_proc_dir_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566) 	dma_free_coherent(&adapter->dev->dev, MEGA_BUFFER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567) 			  adapter->mega_buffer, adapter->buf_dma_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) 	kfree(adapter->scb_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) 	dma_free_coherent(&adapter->dev->dev, sizeof(mbox64_t),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570) 			  adapter->una_mbox64, adapter->una_mbox64_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572) 	scsi_host_put(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573) 	pci_disable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575) 	hba_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579) megaraid_shutdown(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581) 	struct Scsi_Host *host = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) 	adapter_t *adapter = (adapter_t *)host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584) 	__megaraid_shutdown(adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587) static struct pci_device_id megaraid_pci_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588) 	{PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) 		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590) 	{PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591) 		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592) 	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_AMI_MEGARAID3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593) 		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594) 	{0,}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596) MODULE_DEVICE_TABLE(pci, megaraid_pci_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598) static struct pci_driver megaraid_pci_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) 	.name		= "megaraid_legacy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600) 	.id_table	= megaraid_pci_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601) 	.probe		= megaraid_probe_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602) 	.remove		= megaraid_remove_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) 	.shutdown	= megaraid_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606) static int __init megaraid_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610) 	if ((max_cmd_per_lun <= 0) || (max_cmd_per_lun > MAX_CMD_PER_LUN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611) 		max_cmd_per_lun = MAX_CMD_PER_LUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612) 	if (max_mbox_busy_wait > MBOX_BUSY_WAIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613) 		max_mbox_busy_wait = MBOX_BUSY_WAIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615) #ifdef CONFIG_PROC_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616) 	mega_proc_dir_entry = proc_mkdir("megaraid", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617) 	if (!mega_proc_dir_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618) 		printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619) 				"megaraid: failed to create megaraid root\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622) 	error = pci_register_driver(&megaraid_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623) 	if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624) #ifdef CONFIG_PROC_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625) 		remove_proc_entry("megaraid", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) 	 * Register the driver as a character device, for applications
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632) 	 * to access it for ioctls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633) 	 * First argument (major) to register_chrdev implies a dynamic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634) 	 * major number allocation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636) 	major = register_chrdev(0, "megadev_legacy", &megadev_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637) 	if (!major) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638) 		printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639) 				"megaraid: failed to register char device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645) static void __exit megaraid_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648) 	 * Unregister the character device interface to the driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650) 	unregister_chrdev(major, "megadev_legacy");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652) 	pci_unregister_driver(&megaraid_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654) #ifdef CONFIG_PROC_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655) 	remove_proc_entry("megaraid", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659) module_init(megaraid_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660) module_exit(megaraid_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662) /* vi: set ts=8 sw=8 tw=78: */