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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2)  *  linux/drivers/message/fusion/mptspi.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  *      For use with LSI PCI chip/adapter(s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *      running LSI Fusion MPT (Message Passing Technology) firmware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *  Copyright (c) 1999-2008 LSI Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *  (mailto:DL-MPTFusionLinux@lsi.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)     This program is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)     it under the terms of the GNU General Public License as published by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)     the Free Software Foundation; version 2 of the License.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)     This program is distributed in the hope that it will be useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)     but WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18)     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19)     GNU General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21)     NO WARRANTY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22)     THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23)     CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24)     LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25)     MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26)     solely responsible for determining the appropriateness of using and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27)     distributing the Program and assumes all risks associated with its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28)     exercise of rights under this Agreement, including but not limited to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29)     the risks and costs of program errors, damage to or loss of data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30)     programs or equipment, and unavailability or interruption of operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32)     DISCLAIMER OF LIABILITY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33)     NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34)     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35)     DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36)     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37)     TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38)     USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39)     HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41)     You should have received a copy of the GNU General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42)     along with this program; if not, write to the Free Software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43)     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #include <linux/kdev_t.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #include <linux/delay.h>	/* for mdelay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #include <linux/interrupt.h>	/* needed for in_interrupt() proto */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #include <linux/reboot.h>	/* notifier code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #include <linux/raid_class.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #include <scsi/scsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) #include <scsi/scsi_cmnd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) #include <scsi/scsi_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) #include <scsi/scsi_tcq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) #include <scsi/scsi_transport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) #include <scsi/scsi_transport_spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) #include <scsi/scsi_dbg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) #include "mptbase.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) #include "mptscsih.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) #define my_NAME		"Fusion MPT SPI Host driver"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) #define my_VERSION	MPT_LINUX_VERSION_COMMON
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) #define MYNAM		"mptspi"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) MODULE_AUTHOR(MODULEAUTHOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) MODULE_DESCRIPTION(my_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) MODULE_VERSION(my_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) /* Command line args */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) static int mpt_saf_te = MPTSCSIH_SAF_TE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) module_param(mpt_saf_te, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) MODULE_PARM_DESC(mpt_saf_te, " Force enabling SEP Processor: enable=1  (default=MPTSCSIH_SAF_TE=0)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) static void mptspi_write_offset(struct scsi_target *, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) static void mptspi_write_width(struct scsi_target *, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) static int mptspi_write_spi_device_pg1(struct scsi_target *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 				       struct _CONFIG_PAGE_SCSI_DEVICE_1 *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) static struct scsi_transport_template *mptspi_transport_template = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) static u8	mptspiDoneCtx = MPT_MAX_PROTOCOL_DRIVERS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) static u8	mptspiTaskCtx = MPT_MAX_PROTOCOL_DRIVERS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) static u8	mptspiInternalCtx = MPT_MAX_PROTOCOL_DRIVERS; /* Used only for internal commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99)  * 	mptspi_setTargetNegoParms  - Update the target negotiation parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100)  *	@hd: Pointer to a SCSI Host Structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101)  *	@target: per target private data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102)  *	@sdev: SCSI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104)  * 	Update the target negotiation parameters based on the the Inquiry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105)  *	data, adapter capabilities, and NVRAM settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106)  **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) mptspi_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 			    struct scsi_device *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	MPT_ADAPTER *ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	SpiCfgData *pspi_data = &ioc->spi_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	int  id = (int) target->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	int  nvram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	u8 width = MPT_NARROW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	u8 factor = MPT_ASYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	u8 offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	u8 nfactor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	u8 noQas = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	target->negoFlags = pspi_data->noQas;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	if (sdev->scsi_level < SCSI_2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 		width = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 		factor = MPT_ULTRA2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 		offset = pspi_data->maxSyncOffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 		target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 		if (scsi_device_wide(sdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 			width = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 		if (scsi_device_sync(sdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 			factor = pspi_data->minSyncFactor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 			if (!scsi_device_dt(sdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 					factor = MPT_ULTRA2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 				if (!scsi_device_ius(sdev) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 				    !scsi_device_qas(sdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 					factor = MPT_ULTRA160;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 				else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 					factor = MPT_ULTRA320;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 					if (scsi_device_qas(sdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 						ddvprintk(ioc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 						printk(MYIOC_s_DEBUG_FMT "Enabling QAS due to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 						"byte56=%02x on id=%d!\n", ioc->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 						scsi_device_qas(sdev), id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 						noQas = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 					if (sdev->type == TYPE_TAPE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 					    scsi_device_ius(sdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 						target->negoFlags |= MPT_TAPE_NEGO_IDP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 			offset = pspi_data->maxSyncOffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 			/* If RAID, never disable QAS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 			 * else if non RAID, do not disable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 			 *   QAS if bit 1 is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 			 * bit 1 QAS support, non-raid only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 			 * bit 0 IU support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 			if (target->raidVolume == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 				noQas = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 			factor = MPT_ASYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 			offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	if (!sdev->tagged_supported)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 		target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	/* Update tflags based on NVRAM settings. (SCSI only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 		nvram = pspi_data->nvram[id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 		nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 		if (width)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 			width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 		if (offset > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 			/* Ensure factor is set to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 			 * maximum of: adapter, nvram, inquiry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 			if (nfactor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 				if (nfactor < pspi_data->minSyncFactor )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 					nfactor = pspi_data->minSyncFactor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 				factor = max(factor, nfactor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 				if (factor == MPT_ASYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 					offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 				offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 				factor = MPT_ASYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 			factor = MPT_ASYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	/* Make sure data is consistent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	if ((!width) && (factor < MPT_ULTRA2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 		factor = MPT_ULTRA2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	/* Save the data to the target structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	target->minSyncFactor = factor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	target->maxOffset = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	target->maxWidth = width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	spi_min_period(scsi_target(sdev)) = factor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	spi_max_offset(scsi_target(sdev)) = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	spi_max_width(scsi_target(sdev)) = width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	/* Disable unused features.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	if (!width)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 		target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	if (!offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 		target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	if ( factor > MPT_ULTRA320 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 		noQas = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	if (noQas && (pspi_data->noQas == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 		pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 		target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 		/* Disable QAS in a mixed configuration case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 		ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 			"Disabling QAS due to noQas=%02x on id=%d!\n", ioc->name, noQas, id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) }
^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)  * 	mptspi_writeIOCPage4  - write IOC Page 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244)  *	@hd: Pointer to a SCSI Host Structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245)  *	@channel: channel number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246)  *	@id: write IOC Page4 for this ID & Bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248)  *	Return: -EAGAIN if unable to obtain a Message Frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249)  *		or 0 if success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251)  *	Remark: We do not wait for a return, write pages sequentially.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252)  **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) mptspi_writeIOCPage4(MPT_SCSI_HOST *hd, u8 channel , u8 id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	MPT_ADAPTER		*ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	Config_t		*pReq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	IOCPage4_t		*IOCPage4Ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	MPT_FRAME_HDR		*mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	dma_addr_t		 dataDma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	u32			 flagsLength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	int			 ii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	/* Get a MF for this command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 		dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 				"writeIOCPage4 : no msg frames!\n",ioc->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 		return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	/* Set the request and the data pointers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	 * Place data at end of MF.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	pReq = (Config_t *)mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	/* Complete the request frame (same for all requests).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	pReq->Reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	pReq->ChainOffset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	pReq->Function = MPI_FUNCTION_CONFIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	pReq->ExtPageLength = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	pReq->ExtPageType = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	pReq->MsgFlags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	for (ii=0; ii < 8; ii++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 		pReq->Reserved2[ii] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	IOCPage4Ptr = ioc->spi_data.pIocPg4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	dataDma = ioc->spi_data.IocPg4_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	ii = IOCPage4Ptr->ActiveSEP++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	IOCPage4Ptr->SEP[ii].SEPTargetID = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	IOCPage4Ptr->SEP[ii].SEPBus = channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	pReq->Header = IOCPage4Ptr->Header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	pReq->PageAddress = cpu_to_le32(id | (channel << 8 ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	/* Add a SGE to the config request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 		(IOCPage4Ptr->Header.PageLength + ii) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	ioc->add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 		"writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 		ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, id, channel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315)  *	mptspi_initTarget - Target, LUN alloc/free functionality.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316)  *	@hd: Pointer to MPT_SCSI_HOST structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317)  *	@vtarget: per target private data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318)  *	@sdev: SCSI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320)  *	NOTE: It's only SAFE to call this routine if data points to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321)  *	sane & valid STANDARD INQUIRY data!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323)  *	Allocate and initialize memory for this target.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324)  *	Save inquiry data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326)  **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) mptspi_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 		    struct scsi_device *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	/* Is LUN supported? If so, upper 2 bits will be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	* in first byte of inquiry data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	if (sdev->inq_periph_qual != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	if (vtarget == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	vtarget->type = sdev->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	if ((sdev->type == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 		/* Treat all Processors as SAF-TE if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 		 * command line option is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 		vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 		mptspi_writeIOCPage4(hd, vtarget->channel, vtarget->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	}else if ((sdev->type == TYPE_PROCESSOR) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 		!(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 		if (sdev->inquiry_len > 49 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 			if (sdev->inquiry[44] == 'S' &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 			    sdev->inquiry[45] == 'A' &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 			    sdev->inquiry[46] == 'F' &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 			    sdev->inquiry[47] == '-' &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 			    sdev->inquiry[48] == 'T' &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 			    sdev->inquiry[49] == 'E' ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 				vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 				mptspi_writeIOCPage4(hd, vtarget->channel, vtarget->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	mptspi_setTargetNegoParms(hd, vtarget, sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) }
^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)  *	mptspi_is_raid - Determines whether target is belonging to volume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367)  *	@hd: Pointer to a SCSI HOST structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368)  *	@id: target device id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370)  *	Return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371)  *		non-zero = true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372)  *		zero = false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) mptspi_is_raid(struct _MPT_SCSI_HOST *hd, u32 id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	int i, rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	MPT_ADAPTER *ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	if (!ioc->raid_data.pIocPg2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	for (i=0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 		if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID == id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 			rc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) static int mptspi_target_alloc(struct scsi_target *starget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	struct Scsi_Host *shost = dev_to_shost(&starget->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	struct _MPT_SCSI_HOST *hd = shost_priv(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	VirtTarget		*vtarget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	MPT_ADAPTER *ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	if (hd == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	if (!vtarget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	vtarget->ioc_id = ioc->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	vtarget->id = (u8)starget->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	vtarget->channel = (u8)starget->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	vtarget->starget = starget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	starget->hostdata = vtarget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	if (starget->channel == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 		if (mptscsih_is_phys_disk(ioc, 0, starget->id) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 		vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 		/* The real channel for this device is zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 		vtarget->channel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 		/* The actual physdisknum (for RAID passthrough) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 		vtarget->id = mptscsih_raid_id_to_num(ioc, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 		    starget->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	if (starget->channel == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	    mptspi_is_raid(hd, starget->id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 		vtarget->raidVolume = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 		ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 		    "RAID Volume @ channel=%d id=%d\n", ioc->name, starget->channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 		    starget->id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	if (ioc->spi_data.nvram &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	    ioc->spi_data.nvram[starget->id] != MPT_HOST_NVRAM_INVALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 		u32 nvram = ioc->spi_data.nvram[starget->id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 		spi_min_period(starget) = (nvram & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 		spi_max_width(starget) = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 		spi_min_period(starget) = ioc->spi_data.minSyncFactor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 		spi_max_width(starget) = ioc->spi_data.maxBusWidth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	spi_max_offset(starget) = ioc->spi_data.maxSyncOffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	spi_offset(starget) = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	spi_period(starget) = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	mptspi_write_width(starget, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) mptspi_target_destroy(struct scsi_target *starget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	kfree(starget->hostdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	starget->hostdata = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464)  *	mptspi_print_write_nego - negotiation parameters debug info that is being sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465)  *	@hd: Pointer to a SCSI HOST structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466)  *	@starget: SCSI target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467)  *	@ii: negotiation parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) mptspi_print_write_nego(struct _MPT_SCSI_HOST *hd, struct scsi_target *starget, u32 ii)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	ddvprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT "id=%d Requested = 0x%08x"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	    " ( %s factor = 0x%02x @ offset = 0x%02x %s%s%s%s%s%s%s%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	    hd->ioc->name, starget->id, ii,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	    ii & MPI_SCSIDEVPAGE0_NP_WIDE ? "Wide ": "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	    ((ii >> 8) & 0xFF), ((ii >> 16) & 0xFF),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	    ii & MPI_SCSIDEVPAGE0_NP_IU ? "IU ": "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	    ii & MPI_SCSIDEVPAGE0_NP_DT ? "DT ": "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	    ii & MPI_SCSIDEVPAGE0_NP_QAS ? "QAS ": "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	    ii & MPI_SCSIDEVPAGE0_NP_HOLD_MCS ? "HOLDMCS ": "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	    ii & MPI_SCSIDEVPAGE0_NP_WR_FLOW ? "WRFLOW ": "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	    ii & MPI_SCSIDEVPAGE0_NP_RD_STRM ? "RDSTRM ": "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	    ii & MPI_SCSIDEVPAGE0_NP_RTI ? "RTI ": "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	    ii & MPI_SCSIDEVPAGE0_NP_PCOMP_EN ? "PCOMP ": ""));
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489)  *	mptspi_print_read_nego - negotiation parameters debug info that is being read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490)  *	@hd: Pointer to a SCSI HOST structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491)  *	@starget: SCSI target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492)  *	@ii: negotiation parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) mptspi_print_read_nego(struct _MPT_SCSI_HOST *hd, struct scsi_target *starget, u32 ii)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	ddvprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT "id=%d Read = 0x%08x"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	    " ( %s factor = 0x%02x @ offset = 0x%02x %s%s%s%s%s%s%s%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	    hd->ioc->name, starget->id, ii,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	    ii & MPI_SCSIDEVPAGE0_NP_WIDE ? "Wide ": "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	    ((ii >> 8) & 0xFF), ((ii >> 16) & 0xFF),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	    ii & MPI_SCSIDEVPAGE0_NP_IU ? "IU ": "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	    ii & MPI_SCSIDEVPAGE0_NP_DT ? "DT ": "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	    ii & MPI_SCSIDEVPAGE0_NP_QAS ? "QAS ": "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	    ii & MPI_SCSIDEVPAGE0_NP_HOLD_MCS ? "HOLDMCS ": "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	    ii & MPI_SCSIDEVPAGE0_NP_WR_FLOW ? "WRFLOW ": "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	    ii & MPI_SCSIDEVPAGE0_NP_RD_STRM ? "RDSTRM ": "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	    ii & MPI_SCSIDEVPAGE0_NP_RTI ? "RTI ": "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	    ii & MPI_SCSIDEVPAGE0_NP_PCOMP_EN ? "PCOMP ": ""));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) static int mptspi_read_spi_device_pg0(struct scsi_target *starget,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 			     struct _CONFIG_PAGE_SCSI_DEVICE_0 *pass_pg0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	struct Scsi_Host *shost = dev_to_shost(&starget->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	struct _MPT_SCSI_HOST *hd = shost_priv(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	struct _MPT_ADAPTER *ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	struct _CONFIG_PAGE_SCSI_DEVICE_0 *spi_dev_pg0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	dma_addr_t spi_dev_pg0_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	struct _x_config_parms cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	struct _CONFIG_PAGE_HEADER hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	int err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	/* No SPI parameters for RAID devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	if (starget->channel == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	    mptspi_is_raid(hd, starget->id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	size = ioc->spi_data.sdp0length * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	if (ioc->spi_data.sdp0length & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 		size += size + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	size += 2048;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	spi_dev_pg0 = dma_alloc_coherent(&ioc->pcidev->dev, size, &spi_dev_pg0_dma, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	if (spi_dev_pg0 == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 		starget_printk(KERN_ERR, starget, MYIOC_s_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 		    "dma_alloc_coherent for parameters failed\n", ioc->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	memset(&hdr, 0, sizeof(hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	hdr.PageVersion = ioc->spi_data.sdp0version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	hdr.PageLength = ioc->spi_data.sdp0length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	hdr.PageNumber = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	memset(&cfg, 0, sizeof(cfg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	cfg.cfghdr.hdr = &hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	cfg.physAddr = spi_dev_pg0_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	cfg.dir = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	cfg.pageAddr = starget->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	cfg.timeout = 60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	if (mpt_config(ioc, &cfg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 		starget_printk(KERN_ERR, starget, MYIOC_s_FMT "mpt_config failed\n", ioc->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	memcpy(pass_pg0, spi_dev_pg0, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	mptspi_print_read_nego(hd, starget, le32_to_cpu(spi_dev_pg0->NegotiatedParameters));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570)  out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	dma_free_coherent(&ioc->pcidev->dev, size, spi_dev_pg0, spi_dev_pg0_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) static u32 mptspi_getRP(struct scsi_target *starget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	u32 nego = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	nego |= spi_iu(starget) ? MPI_SCSIDEVPAGE1_RP_IU : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	nego |= spi_dt(starget) ? MPI_SCSIDEVPAGE1_RP_DT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	nego |= spi_qas(starget) ? MPI_SCSIDEVPAGE1_RP_QAS : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	nego |= spi_hold_mcs(starget) ? MPI_SCSIDEVPAGE1_RP_HOLD_MCS : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	nego |= spi_wr_flow(starget) ? MPI_SCSIDEVPAGE1_RP_WR_FLOW : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	nego |= spi_rd_strm(starget) ? MPI_SCSIDEVPAGE1_RP_RD_STRM : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	nego |= spi_rti(starget) ? MPI_SCSIDEVPAGE1_RP_RTI : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	nego |= spi_pcomp_en(starget) ? MPI_SCSIDEVPAGE1_RP_PCOMP_EN : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	nego |= (spi_period(starget) <<  MPI_SCSIDEVPAGE1_RP_SHIFT_MIN_SYNC_PERIOD) & MPI_SCSIDEVPAGE1_RP_MIN_SYNC_PERIOD_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	nego |= (spi_offset(starget) << MPI_SCSIDEVPAGE1_RP_SHIFT_MAX_SYNC_OFFSET) & MPI_SCSIDEVPAGE1_RP_MAX_SYNC_OFFSET_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	nego |= spi_width(starget) ?  MPI_SCSIDEVPAGE1_RP_WIDE : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	return nego;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) static void mptspi_read_parameters(struct scsi_target *starget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	int nego;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	struct _CONFIG_PAGE_SCSI_DEVICE_0 spi_dev_pg0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	mptspi_read_spi_device_pg0(starget, &spi_dev_pg0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	nego = le32_to_cpu(spi_dev_pg0.NegotiatedParameters);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	spi_iu(starget) = (nego & MPI_SCSIDEVPAGE0_NP_IU) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	spi_dt(starget) = (nego & MPI_SCSIDEVPAGE0_NP_DT) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	spi_qas(starget) = (nego & MPI_SCSIDEVPAGE0_NP_QAS) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	spi_wr_flow(starget) = (nego & MPI_SCSIDEVPAGE0_NP_WR_FLOW) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	spi_rd_strm(starget) = (nego & MPI_SCSIDEVPAGE0_NP_RD_STRM) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	spi_rti(starget) = (nego & MPI_SCSIDEVPAGE0_NP_RTI) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	spi_pcomp_en(starget) = (nego & MPI_SCSIDEVPAGE0_NP_PCOMP_EN) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	spi_hold_mcs(starget) = (nego & MPI_SCSIDEVPAGE0_NP_HOLD_MCS) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	spi_period(starget) = (nego & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> MPI_SCSIDEVPAGE0_NP_SHIFT_SYNC_PERIOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	spi_offset(starget) = (nego & MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> MPI_SCSIDEVPAGE0_NP_SHIFT_SYNC_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	spi_width(starget) = (nego & MPI_SCSIDEVPAGE0_NP_WIDE) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, u8 channel, u8 id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	MPT_ADAPTER	*ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	MpiRaidActionRequest_t	*pReq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	MPT_FRAME_HDR		*mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	int			ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	unsigned long 	 	timeleft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	mutex_lock(&ioc->internal_cmds.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	/* Get and Populate a free Frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 		dfailprintk(hd->ioc, printk(MYIOC_s_WARN_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 			"%s: no msg frames!\n", ioc->name, __func__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 		ret = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	pReq = (MpiRaidActionRequest_t *)mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	if (quiesce)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 		pReq->Action = MPI_RAID_ACTION_QUIESCE_PHYS_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 		pReq->Action = MPI_RAID_ACTION_ENABLE_PHYS_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	pReq->Reserved1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	pReq->ChainOffset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	pReq->Function = MPI_FUNCTION_RAID_ACTION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	pReq->VolumeID = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	pReq->VolumeBus = channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 	pReq->PhysDiskNum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	pReq->MsgFlags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	pReq->Reserved2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	pReq->ActionDataWord = 0; /* Reserved for this action */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	ioc->add_sge((char *)&pReq->ActionDataSGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 		MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RAID Volume action=%x channel=%d id=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 			ioc->name, pReq->Action, channel, id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	INITIALIZE_MGMT_STATUS(ioc->internal_cmds.status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	mpt_put_msg_frame(ioc->InternalCtx, ioc, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 	timeleft = wait_for_completion_timeout(&ioc->internal_cmds.done, 10*HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 	if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 		ret = -ETIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: TIMED OUT!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 		    ioc->name, __func__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 		if (ioc->internal_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 		if (!timeleft) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 			printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 			    ioc->name, __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 			mpt_HardResetHandler(ioc, CAN_SLEEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 			mpt_free_msg_frame(ioc, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	ret = ioc->internal_cmds.completion_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	mutex_unlock(&ioc->internal_cmds.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 			     struct scsi_device *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	VirtTarget *vtarget = scsi_target(sdev)->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	MPT_ADAPTER *ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	/* no DV on RAID devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	if (sdev->channel == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	    mptspi_is_raid(hd, sdev->id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	/* If this is a piece of a RAID, then quiesce first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	if (sdev->channel == 1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	    mptscsih_quiesce_raid(hd, 1, vtarget->channel, vtarget->id) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 		starget_printk(KERN_ERR, scsi_target(sdev), MYIOC_s_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 		    "Integrated RAID quiesce failed\n", ioc->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	hd->spi_pending |= (1 << sdev->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	spi_dv_device(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	hd->spi_pending &= ~(1 << sdev->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	if (sdev->channel == 1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	    mptscsih_quiesce_raid(hd, 0, vtarget->channel, vtarget->id) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 		starget_printk(KERN_ERR, scsi_target(sdev), MYIOC_s_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 		    "Integrated RAID resume failed\n", ioc->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	mptspi_read_parameters(sdev->sdev_target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	spi_display_xfer_agreement(sdev->sdev_target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	mptspi_read_parameters(sdev->sdev_target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) static int mptspi_slave_alloc(struct scsi_device *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	MPT_SCSI_HOST *hd = shost_priv(sdev->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	VirtTarget		*vtarget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	VirtDevice		*vdevice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	struct scsi_target 	*starget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	MPT_ADAPTER *ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	if (sdev->channel == 1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 		mptscsih_is_phys_disk(ioc, 0, sdev->id) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 			return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	if (!vdevice) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 		printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 				ioc->name, sizeof(VirtDevice));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	vdevice->lun = sdev->lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	sdev->hostdata = vdevice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	starget = scsi_target(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	vtarget = starget->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 	vdevice->vtarget = vtarget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	vtarget->num_luns++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	if (sdev->channel == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 		sdev->no_uld_attach = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) static int mptspi_slave_configure(struct scsi_device *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	struct _MPT_SCSI_HOST *hd = shost_priv(sdev->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	VirtTarget *vtarget = scsi_target(sdev)->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	mptspi_initTarget(hd, vtarget, sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	ret = mptscsih_slave_configure(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	ddvprintk(hd->ioc, printk(MYIOC_s_DEBUG_FMT "id=%d min_period=0x%02x"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 		" max_offset=0x%02x max_width=%d\n", hd->ioc->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 		sdev->id, spi_min_period(scsi_target(sdev)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 		spi_max_offset(scsi_target(sdev)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		spi_max_width(scsi_target(sdev))));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	if ((sdev->channel == 1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 	     !(mptspi_is_raid(hd, sdev->id))) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	    !spi_initial_dv(sdev->sdev_target))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 		mptspi_dv_device(hd, sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) mptspi_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	struct _MPT_SCSI_HOST *hd = shost_priv(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	VirtDevice	*vdevice = SCpnt->device->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	MPT_ADAPTER *ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	if (!vdevice || !vdevice->vtarget) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 		SCpnt->result = DID_NO_CONNECT << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 		SCpnt->scsi_done(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 		return 0;
^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) 	if (SCpnt->device->channel == 1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 		mptscsih_is_phys_disk(ioc, 0, SCpnt->device->id) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 		SCpnt->result = DID_NO_CONNECT << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		SCpnt->scsi_done(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 	if (spi_dv_pending(scsi_target(SCpnt->device)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 		ddvprintk(ioc, scsi_print_command(SCpnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 	return mptscsih_qcmd(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) static void mptspi_slave_destroy(struct scsi_device *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	struct scsi_target *starget = scsi_target(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	VirtTarget *vtarget = starget->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	VirtDevice *vdevice = sdev->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	/* Will this be the last lun on a non-raid device? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	if (vtarget->num_luns == 1 && vdevice->configured_lun) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 		struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 		/* Async Narrow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 		pg1.RequestedParameters = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 		pg1.Reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 		pg1.Configuration = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 		mptspi_write_spi_device_pg1(starget, &pg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 	mptscsih_slave_destroy(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) static struct scsi_host_template mptspi_driver_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	.module				= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	.proc_name			= "mptspi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	.show_info			= mptscsih_show_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	.name				= "MPT SPI Host",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	.info				= mptscsih_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	.queuecommand			= mptspi_qcmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	.target_alloc			= mptspi_target_alloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	.slave_alloc			= mptspi_slave_alloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 	.slave_configure		= mptspi_slave_configure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	.target_destroy			= mptspi_target_destroy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	.slave_destroy			= mptspi_slave_destroy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	.change_queue_depth 		= mptscsih_change_queue_depth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	.eh_abort_handler		= mptscsih_abort,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	.eh_device_reset_handler	= mptscsih_dev_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	.eh_bus_reset_handler		= mptscsih_bus_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	.eh_host_reset_handler		= mptscsih_host_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	.bios_param			= mptscsih_bios_param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	.can_queue			= MPT_SCSI_CAN_QUEUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	.this_id			= -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	.sg_tablesize			= MPT_SCSI_SG_DEPTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	.max_sectors			= 8192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	.cmd_per_lun			= 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	.shost_attrs			= mptscsih_host_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) static int mptspi_write_spi_device_pg1(struct scsi_target *starget,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 			       struct _CONFIG_PAGE_SCSI_DEVICE_1 *pass_pg1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	struct Scsi_Host *shost = dev_to_shost(&starget->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	struct _MPT_SCSI_HOST *hd = shost_priv(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	struct _MPT_ADAPTER *ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	struct _CONFIG_PAGE_SCSI_DEVICE_1 *pg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	dma_addr_t pg1_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	struct _x_config_parms cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	struct _CONFIG_PAGE_HEADER hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	int err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	u32 nego_parms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	u32 period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	struct scsi_device *sdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	/* don't allow updating nego parameters on RAID devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	if (starget->channel == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	    mptspi_is_raid(hd, starget->id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	size = ioc->spi_data.sdp1length * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	pg1 = dma_alloc_coherent(&ioc->pcidev->dev, size, &pg1_dma, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	if (pg1 == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 		starget_printk(KERN_ERR, starget, MYIOC_s_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 		    "dma_alloc_coherent for parameters failed\n", ioc->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	memset(&hdr, 0, sizeof(hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	hdr.PageVersion = ioc->spi_data.sdp1version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	hdr.PageLength = ioc->spi_data.sdp1length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	hdr.PageNumber = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	hdr.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	memset(&cfg, 0, sizeof(cfg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 	cfg.cfghdr.hdr = &hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	cfg.physAddr = pg1_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	cfg.dir = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	cfg.pageAddr = starget->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	memcpy(pg1, pass_pg1, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	pg1->Header.PageVersion = hdr.PageVersion;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	pg1->Header.PageLength = hdr.PageLength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	pg1->Header.PageNumber = hdr.PageNumber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	pg1->Header.PageType = hdr.PageType;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	nego_parms = le32_to_cpu(pg1->RequestedParameters);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	period = (nego_parms & MPI_SCSIDEVPAGE1_RP_MIN_SYNC_PERIOD_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 		MPI_SCSIDEVPAGE1_RP_SHIFT_MIN_SYNC_PERIOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	if (period == 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 		/* Turn on inline data padding for TAPE when running U320 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 		for (i = 0 ; i < 16; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 			sdev = scsi_device_lookup_by_target(starget, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 			if (sdev && sdev->type == TYPE_TAPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 				sdev_printk(KERN_DEBUG, sdev, MYIOC_s_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 					    "IDP:ON\n", ioc->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 				nego_parms |= MPI_SCSIDEVPAGE1_RP_IDP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 				pg1->RequestedParameters =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 				    cpu_to_le32(nego_parms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 		}
^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) 	mptspi_print_write_nego(hd, starget, le32_to_cpu(pg1->RequestedParameters));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	if (mpt_config(ioc, &cfg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 		starget_printk(KERN_ERR, starget, MYIOC_s_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 		    "mpt_config failed\n", ioc->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929)  out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	dma_free_coherent(&ioc->pcidev->dev, size, pg1, pg1_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) static void mptspi_write_offset(struct scsi_target *starget, int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	u32 nego;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	if (offset < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 		offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	if (offset > 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 		offset = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	if (spi_offset(starget) == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 		mptspi_read_parameters(starget);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	spi_offset(starget) = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	nego = mptspi_getRP(starget);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	pg1.RequestedParameters = cpu_to_le32(nego);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	pg1.Reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	pg1.Configuration = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	mptspi_write_spi_device_pg1(starget, &pg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) static void mptspi_write_period(struct scsi_target *starget, int period)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	u32 nego;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	if (period < 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		period = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	if (period > 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 		period = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	if (spi_period(starget) == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 		mptspi_read_parameters(starget);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	if (period == 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 		spi_iu(starget) = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 		spi_dt(starget) = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	} else if (period == 9) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 		spi_dt(starget) = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	spi_period(starget) = period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	nego = mptspi_getRP(starget);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	pg1.RequestedParameters = cpu_to_le32(nego);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	pg1.Reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	pg1.Configuration = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	mptspi_write_spi_device_pg1(starget, &pg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) static void mptspi_write_dt(struct scsi_target *starget, int dt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	u32 nego;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	if (spi_period(starget) == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 		mptspi_read_parameters(starget);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	if (!dt && spi_period(starget) < 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 		spi_period(starget) = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	spi_dt(starget) = dt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	nego = mptspi_getRP(starget);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	pg1.RequestedParameters = cpu_to_le32(nego);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	pg1.Reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	pg1.Configuration = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	mptspi_write_spi_device_pg1(starget, &pg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) static void mptspi_write_iu(struct scsi_target *starget, int iu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	u32 nego;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	if (spi_period(starget) == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 		mptspi_read_parameters(starget);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	if (!iu && spi_period(starget) < 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 		spi_period(starget) = 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	spi_iu(starget) = iu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	nego = mptspi_getRP(starget);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	pg1.RequestedParameters = cpu_to_le32(nego);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	pg1.Reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	pg1.Configuration = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	mptspi_write_spi_device_pg1(starget, &pg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) #define MPTSPI_SIMPLE_TRANSPORT_PARM(parm) 				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) static void mptspi_write_##parm(struct scsi_target *starget, int parm)\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) {									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 	struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	u32 nego;							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	spi_##parm(starget) = parm;					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	nego = mptspi_getRP(starget);					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 	pg1.RequestedParameters = cpu_to_le32(nego);			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	pg1.Reserved = 0;						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	pg1.Configuration = 0;						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 									\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	mptspi_write_spi_device_pg1(starget, &pg1);				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) MPTSPI_SIMPLE_TRANSPORT_PARM(rd_strm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) MPTSPI_SIMPLE_TRANSPORT_PARM(wr_flow)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) MPTSPI_SIMPLE_TRANSPORT_PARM(rti)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) MPTSPI_SIMPLE_TRANSPORT_PARM(hold_mcs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) MPTSPI_SIMPLE_TRANSPORT_PARM(pcomp_en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) static void mptspi_write_qas(struct scsi_target *starget, int qas)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	struct Scsi_Host *shost = dev_to_shost(&starget->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	struct _MPT_SCSI_HOST *hd = shost_priv(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	VirtTarget *vtarget = starget->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	u32 nego;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	if ((vtarget->negoFlags & MPT_TARGET_NO_NEGO_QAS) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	    hd->ioc->spi_data.noQas)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 		spi_qas(starget) = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 		spi_qas(starget) = qas;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	nego = mptspi_getRP(starget);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	pg1.RequestedParameters = cpu_to_le32(nego);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	pg1.Reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	pg1.Configuration = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 	mptspi_write_spi_device_pg1(starget, &pg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) static void mptspi_write_width(struct scsi_target *starget, int width)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	u32 nego;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	if (!width) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 		spi_dt(starget) = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 		if (spi_period(starget) < 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 			spi_period(starget) = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	spi_width(starget) = width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	nego = mptspi_getRP(starget);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	pg1.RequestedParameters = cpu_to_le32(nego);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	pg1.Reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	pg1.Configuration = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	mptspi_write_spi_device_pg1(starget, &pg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) struct work_queue_wrapper {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	struct work_struct	work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	struct _MPT_SCSI_HOST	*hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	int			disk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) static void mpt_work_wrapper(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	struct work_queue_wrapper *wqw =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 		container_of(work, struct work_queue_wrapper, work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	struct _MPT_SCSI_HOST *hd = wqw->hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	MPT_ADAPTER *ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	struct Scsi_Host *shost = ioc->sh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	struct scsi_device *sdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	int disk = wqw->disk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	struct _CONFIG_PAGE_IOC_3 *pg3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 	kfree(wqw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	mpt_findImVolumes(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	pg3 = ioc->raid_data.pIocPg3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	if (!pg3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	shost_for_each_device(sdev,shost) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 		struct scsi_target *starget = scsi_target(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 		VirtTarget *vtarget = starget->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 		/* only want to search RAID components */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 		if (sdev->channel != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 		/* The id is the raid PhysDiskNum, even if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 		 * starget->id is the actual target address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 		if(vtarget->id != disk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 		starget_printk(KERN_INFO, vtarget->starget, MYIOC_s_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 		    "Integrated RAID requests DV of new device\n", ioc->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 		mptspi_dv_device(hd, sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 	shost_printk(KERN_INFO, shost, MYIOC_s_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	    "Integrated RAID detects new device %d\n", ioc->name, disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	scsi_scan_target(&ioc->sh->shost_gendev, 1, disk, 0, SCSI_SCAN_RESCAN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) static void mpt_dv_raid(struct _MPT_SCSI_HOST *hd, int disk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	struct work_queue_wrapper *wqw = kmalloc(sizeof(*wqw), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	MPT_ADAPTER *ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	if (!wqw) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 		shost_printk(KERN_ERR, ioc->sh, MYIOC_s_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 		    "Failed to act on RAID event for physical disk %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 		    ioc->name, disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	INIT_WORK(&wqw->work, mpt_work_wrapper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	wqw->hd = hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	wqw->disk = disk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	schedule_work(&wqw->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) mptspi_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 	u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	struct _MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 	if (ioc->bus_type != SPI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 	if (hd && event ==  MPI_EVENT_INTEGRATED_RAID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 		int reason
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 			= (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 		if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 			int disk = (le32_to_cpu(pEvReply->Data[0]) & 0xFF000000) >> 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 			mpt_dv_raid(hd, disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	return mptscsih_event_process(ioc, pEvReply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) mptspi_deny_binding(struct scsi_target *starget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 	struct _MPT_SCSI_HOST *hd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 		(struct _MPT_SCSI_HOST *)dev_to_shost(starget->dev.parent)->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 	return ((mptspi_is_raid(hd, starget->id)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 		starget->channel == 0) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) static struct spi_function_template mptspi_transport_functions = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 	.get_offset	= mptspi_read_parameters,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	.set_offset	= mptspi_write_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	.show_offset	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	.get_period	= mptspi_read_parameters,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 	.set_period	= mptspi_write_period,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	.show_period	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	.get_width	= mptspi_read_parameters,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 	.set_width	= mptspi_write_width,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 	.show_width	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 	.get_iu		= mptspi_read_parameters,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 	.set_iu		= mptspi_write_iu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 	.show_iu	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 	.get_dt		= mptspi_read_parameters,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 	.set_dt		= mptspi_write_dt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	.show_dt	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 	.get_qas	= mptspi_read_parameters,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	.set_qas	= mptspi_write_qas,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 	.show_qas	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 	.get_wr_flow	= mptspi_read_parameters,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	.set_wr_flow	= mptspi_write_wr_flow,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 	.show_wr_flow	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	.get_rd_strm	= mptspi_read_parameters,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	.set_rd_strm	= mptspi_write_rd_strm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 	.show_rd_strm	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 	.get_rti	= mptspi_read_parameters,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 	.set_rti	= mptspi_write_rti,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 	.show_rti	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 	.get_pcomp_en	= mptspi_read_parameters,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	.set_pcomp_en	= mptspi_write_pcomp_en,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	.show_pcomp_en	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	.get_hold_mcs	= mptspi_read_parameters,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	.set_hold_mcs	= mptspi_write_hold_mcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	.show_hold_mcs	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	.deny_binding	= mptspi_deny_binding,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) /****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)  * Supported hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) static struct pci_device_id mptspi_pci_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_53C1030,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 		PCI_ANY_ID, PCI_ANY_ID },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	{ PCI_VENDOR_ID_ATTO, MPI_MANUFACTPAGE_DEVID_53C1030,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 		PCI_ANY_ID, PCI_ANY_ID },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVID_53C1035,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 		PCI_ANY_ID, PCI_ANY_ID },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 	{0}	/* Terminating entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) MODULE_DEVICE_TABLE(pci, mptspi_pci_table);
^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)  * renegotiate for a given target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) mptspi_dv_renegotiate_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 	struct work_queue_wrapper *wqw =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 		container_of(work, struct work_queue_wrapper, work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 	struct _MPT_SCSI_HOST *hd = wqw->hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 	struct scsi_device *sdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 	struct scsi_target *starget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 	struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 	u32 nego;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 	MPT_ADAPTER *ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 	kfree(wqw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	if (hd->spi_pending) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 		shost_for_each_device(sdev, ioc->sh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 			if  (hd->spi_pending & (1 << sdev->id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 			starget = scsi_target(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 			nego = mptspi_getRP(starget);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 			pg1.RequestedParameters = cpu_to_le32(nego);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 			pg1.Reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 			pg1.Configuration = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 			mptspi_write_spi_device_pg1(starget, &pg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 		shost_for_each_device(sdev, ioc->sh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 			mptspi_dv_device(hd, sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) mptspi_dv_renegotiate(struct _MPT_SCSI_HOST *hd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	struct work_queue_wrapper *wqw = kmalloc(sizeof(*wqw), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 	if (!wqw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 	INIT_WORK(&wqw->work, mptspi_dv_renegotiate_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	wqw->hd = hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 	schedule_work(&wqw->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)  * spi module reset handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) mptspi_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 	rc = mptscsih_ioc_reset(ioc, reset_phase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 	if ((ioc->bus_type != SPI) || (!rc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 	/* only try to do a renegotiation if we're properly set up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 	 * if we get an ioc fault on bringup, ioc->sh will be NULL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 	if (reset_phase == MPT_IOC_POST_RESET &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 	    ioc->sh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 		struct _MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 		mptspi_dv_renegotiate(hd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)  * spi module resume handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) mptspi_resume(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 	MPT_ADAPTER 	*ioc = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 	struct _MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 	rc = mptscsih_resume(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 	mptspi_dv_renegotiate(hd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)  *	mptspi_probe - Installs scsi devices per bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)  *	@pdev: Pointer to pci_dev structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)  *	Returns 0 for success, non-zero for failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	struct Scsi_Host	*sh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	MPT_SCSI_HOST		*hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	MPT_ADAPTER 		*ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 	unsigned long		 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	int			 ii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	int			 numSGE = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 	int			 scale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 	int			 ioc_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 	int			error=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 	int			r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 	if ((r = mpt_attach(pdev,id)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 		return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 	ioc = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 	ioc->DoneCtx = mptspiDoneCtx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 	ioc->TaskCtx = mptspiTaskCtx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	ioc->InternalCtx = mptspiInternalCtx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 	/*  Added sanity check on readiness of the MPT adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 	if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 		printk(MYIOC_s_WARN_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 		  "Skipping because it's not operational!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 		  ioc->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 		error = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 		goto out_mptspi_probe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 	if (!ioc->active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 		printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 		  ioc->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 		error = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 		goto out_mptspi_probe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 	/*  Sanity check - ensure at least 1 port is INITIATOR capable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 	ioc_cap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 	for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 		if (ioc->pfacts[ii].ProtocolFlags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 		    MPI_PORTFACTS_PROTOCOL_INITIATOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 			ioc_cap ++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 	if (!ioc_cap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 		printk(MYIOC_s_WARN_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 			"Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 			ioc->name, ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 	sh = scsi_host_alloc(&mptspi_driver_template, sizeof(MPT_SCSI_HOST));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 	if (!sh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 		printk(MYIOC_s_WARN_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 			"Unable to register controller with SCSI subsystem\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 			ioc->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 		error = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 		goto out_mptspi_probe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 	/* VMWare emulation doesn't properly implement WRITE_SAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	if (pdev->subsystem_vendor == 0x15AD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 		sh->no_write_same = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 	spin_lock_irqsave(&ioc->FreeQlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 	/* Attach the SCSI Host to the IOC structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 	ioc->sh = sh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 	sh->io_port = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 	sh->n_io_port = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 	sh->irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 	/* set 16 byte cdb's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 	sh->max_cmd_len = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 	/* Yikes!  This is important!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 	 * Otherwise, by default, linux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 	 * only scans target IDs 0-7!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 	 * pfactsN->MaxDevices unreliable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 	 * (not supported in early
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 	 *	versions of the FW).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 	 * max_id = 1 + actual max id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 	 * max_lun = 1 + actual last lun,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 	 *	see hosts.h :o(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 	sh->max_id = ioc->devices_per_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 	sh->max_lun = MPT_LAST_LUN + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 	 * If RAID Firmware Detected, setup virtual channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 	if (ioc->ir_firmware)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 		sh->max_channel = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 		sh->max_channel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 	sh->this_id = ioc->pfacts[0].PortSCSIID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 	/* Required entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 	sh->unique_id = ioc->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 	/* Verify that we won't exceed the maximum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 	 * number of chain buffers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 	 * We can optimize:  ZZ = req_sz/sizeof(SGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 	 * For 32bit SGE's:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 	 *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 	 *               + (req_sz - 64)/sizeof(SGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 	 * A slightly different algorithm is required for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 	 * 64bit SGEs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 	scale = ioc->req_sz/ioc->SGE_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 	if (ioc->sg_addr_size == sizeof(u64)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 		numSGE = (scale - 1) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 		  (ioc->facts.MaxChainDepth-1) + scale +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 		  (ioc->req_sz - 60) / ioc->SGE_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 		numSGE = 1 + (scale - 1) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 		  (ioc->facts.MaxChainDepth-1) + scale +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 		  (ioc->req_sz - 64) / ioc->SGE_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 	if (numSGE < sh->sg_tablesize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 		/* Reset this value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 		  "Resetting sg_tablesize to %d from %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 		  ioc->name, numSGE, sh->sg_tablesize));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 		sh->sg_tablesize = numSGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 	hd = shost_priv(sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 	hd->ioc = ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 	/* SCSI needs scsi_cmnd lookup table!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 	 * (with size equal to req_depth*PtrSz!)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 	ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 	if (!ioc->ScsiLookup) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 		error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 		goto out_mptspi_probe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 	spin_lock_init(&ioc->scsi_lookup_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 	dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 		 ioc->name, ioc->ScsiLookup));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 	ioc->spi_data.Saf_Te = mpt_saf_te;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 	ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 		"saf_te %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 		ioc->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 		mpt_saf_te));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 	ioc->spi_data.noQas = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 	hd->last_queue_full = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 	hd->spi_pending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 	/* Some versions of the firmware don't support page 0; without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 	 * that we can't get the parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 	if (ioc->spi_data.sdp0length != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 		sh->transportt = mptspi_transport_template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 	error = scsi_add_host (sh, &ioc->pcidev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 	if(error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 		dprintk(ioc, printk(MYIOC_s_ERR_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 		  "scsi_add_host failed\n", ioc->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 		goto out_mptspi_probe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 	 * issue internal bus reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 	if (ioc->spi_data.bus_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 		mptscsih_IssueTaskMgmt(hd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 		    MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 		    0, 0, 0, 0, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 	scsi_scan_host(sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) out_mptspi_probe:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 	mptscsih_remove(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 	return error;
^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) static void mptspi_remove(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 	scsi_remove_host(ioc->sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 	mptscsih_remove(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) static struct pci_driver mptspi_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 	.name		= "mptspi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 	.id_table	= mptspi_pci_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	.probe		= mptspi_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 	.remove		= mptspi_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 	.shutdown	= mptscsih_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 	.suspend	= mptscsih_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 	.resume		= mptspi_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) };
^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)  *	mptspi_init - Register MPT adapter(s) as SCSI host(s) with SCSI mid-layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569)  *	Returns 0 for success, non-zero for failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) mptspi_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 	show_mptmod_ver(my_NAME, my_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 	mptspi_transport_template = spi_attach_transport(&mptspi_transport_functions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 	if (!mptspi_transport_template)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 	mptspiDoneCtx = mpt_register(mptscsih_io_done, MPTSPI_DRIVER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 	    "mptscsih_io_done");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 	mptspiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSPI_DRIVER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 	    "mptscsih_taskmgmt_complete");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 	mptspiInternalCtx = mpt_register(mptscsih_scandv_complete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 	    MPTSPI_DRIVER, "mptscsih_scandv_complete");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 	mpt_event_register(mptspiDoneCtx, mptspi_event_process);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 	mpt_reset_register(mptspiDoneCtx, mptspi_ioc_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 	error = pci_register_driver(&mptspi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 		spi_release_transport(mptspi_transport_template);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)  *	mptspi_exit - Unregisters MPT adapter(s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) static void __exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) mptspi_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 	pci_unregister_driver(&mptspi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 	mpt_reset_deregister(mptspiDoneCtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 	mpt_event_deregister(mptspiDoneCtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 	mpt_deregister(mptspiInternalCtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 	mpt_deregister(mptspiTaskCtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 	mpt_deregister(mptspiDoneCtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 	spi_release_transport(mptspi_transport_template);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) module_init(mptspi_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) module_exit(mptspi_exit);