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/mptscsih.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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #include <scsi/scsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #include <scsi/scsi_cmnd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) #include <scsi/scsi_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) #include <scsi/scsi_tcq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) #include <scsi/scsi_dbg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) #include "mptbase.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) #include "mptscsih.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) #include "lsi/mpi_log_sas.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) #define my_NAME		"Fusion MPT SCSI Host driver"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) #define my_VERSION	MPT_LINUX_VERSION_COMMON
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) #define MYNAM		"mptscsih"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) MODULE_AUTHOR(MODULEAUTHOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) MODULE_DESCRIPTION(my_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) MODULE_VERSION(my_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82)  *  Other private/forward protos...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) struct scsi_cmnd	*mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) static struct scsi_cmnd * mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) static void	mptscsih_set_scsi_lookup(MPT_ADAPTER *ioc, int i, struct scsi_cmnd *scmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) static int	SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *scmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) int		mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) static void	mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) int		mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) static int	mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 				 SCSIIORequest_t *pReq, int req_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) static void	mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) static void	mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) int	mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 		u64 lun, int ctx2abort, ulong timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) int		mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) int		mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) static int	mptscsih_get_completion_code(MPT_ADAPTER *ioc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 		MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) int		mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) static int	mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) static void	mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) mptscsih_taskmgmt_reply(MPT_ADAPTER *ioc, u8 type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 				SCSITaskMgmtReply_t *pScsiTmReply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) void 		mptscsih_remove(struct pci_dev *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) void 		mptscsih_shutdown(struct pci_dev *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) int 		mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) int 		mptscsih_resume(struct pci_dev *pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124)  *	mptscsih_getFreeChainBuffer - Function to get a free chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125)  *	from the MPT_SCSI_HOST FreeChainQ.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126)  *	@ioc: Pointer to MPT_ADAPTER structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127)  *	@req_idx: Index of the SCSI IO request frame. (output)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129)  *	return SUCCESS or FAILED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	MPT_FRAME_HDR *chainBuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	int chain_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "getFreeChainBuffer called\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	    ioc->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	spin_lock_irqsave(&ioc->FreeQlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	if (!list_empty(&ioc->FreeChainQ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 		int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 		chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 				u.frame.linkage.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 		list_del(&chainBuf->u.frame.linkage.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 		offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 		chain_idx = offset / ioc->req_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 		rc = SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 		dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 		    "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 		    ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 		rc = FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 		chain_idx = MPT_HOST_NO_CHAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 		dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "getFreeChainBuffer failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 		    ioc->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	*retIndex = chain_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) } /* mptscsih_getFreeChainBuffer() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168)  *	mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169)  *	SCSIIORequest_t Message Frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170)  *	@ioc: Pointer to MPT_ADAPTER structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171)  *	@SCpnt: Pointer to scsi_cmnd structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172)  *	@pReq: Pointer to SCSIIORequest_t structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174)  *	Returns ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 		SCSIIORequest_t *pReq, int req_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	char 	*psge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	char	*chainSge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	int	 frm_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	int	 sges_left, sg_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	int	 chain_idx = MPT_HOST_NO_CHAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	int	 sgeOffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	int	 numSgeSlots, numSgeThisFrame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	u32	 sgflags, sgdir, thisxfer = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	int	 chain_dma_off = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	int	 newIndex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	int	 ii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	dma_addr_t v2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	u32	RequestNB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	if (sgdir == MPI_SCSIIO_CONTROL_WRITE)  {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 		sgdir = MPT_TRANSFER_HOST_TO_IOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 		sgdir = MPT_TRANSFER_IOC_TO_HOST;
^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) 	psge = (char *) &pReq->SGL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	frm_sz = ioc->req_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	/* Map the data portion, if any.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	 * sges_left  = 0 if no data transfer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	sges_left = scsi_dma_map(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	if (sges_left < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 		return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	/* Handle the SG case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	sg = scsi_sglist(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	sg_done  = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	chainSge = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	/* Prior to entering this loop - the following must be set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	 * current MF:  sgeOffset (bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	 *              chainSge (Null if original MF is not a chain buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	 *              sg_done (num SGE done for this MF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) nextSGEset:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	numSgeSlots = ((frm_sz - sgeOffset) / ioc->SGE_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | sgdir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	/* Get first (num - 1) SG elements
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	 * Skip any SG entries with a length of 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	 * NOTE: at finish, sg and psge pointed to NEXT data/location positions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	for (ii=0; ii < (numSgeThisFrame-1); ii++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 		thisxfer = sg_dma_len(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 		if (thisxfer == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 			/* Get next SG element from the OS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 			sg = sg_next(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 			sg_done++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 		v2 = sg_dma_address(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 		ioc->add_sge(psge, sgflags | thisxfer, v2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 		/* Get next SG element from the OS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 		sg = sg_next(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 		psge += ioc->SGE_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 		sgeOffset += ioc->SGE_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 		sg_done++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	if (numSgeThisFrame == sges_left) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 		/* Add last element, end of buffer and end of list flags.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 		sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 				MPT_SGE_FLAGS_END_OF_BUFFER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 				MPT_SGE_FLAGS_END_OF_LIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 		/* Add last SGE and set termination flags.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 		 * Note: Last SGE may have a length of 0 - which should be ok.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 		thisxfer = sg_dma_len(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 		v2 = sg_dma_address(sg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 		ioc->add_sge(psge, sgflags | thisxfer, v2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 		sgeOffset += ioc->SGE_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 		sg_done++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 		if (chainSge) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 			/* The current buffer is a chain buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 			 * but there is not another one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 			 * Update the chain element
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 			 * Offset and Length fields.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 			ioc->add_chain((char *)chainSge, 0, sgeOffset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 				ioc->ChainBufferDMA + chain_dma_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 			/* The current buffer is the original MF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 			 * and there is no Chain buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 			pReq->ChainOffset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 			RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor)  + 1) & 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 			dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 			    "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 			ioc->RequestNB[req_idx] = RequestNB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 		/* At least one chain buffer is needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 		 * Complete the first MF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 		 *  - last SGE element, set the LastElement bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 		 *  - set ChainOffset (words) for orig MF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 		 *             (OR finish previous MF chain buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 		 *  - update MFStructPtr ChainIndex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 		 *  - Populate chain element
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 		 * Also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 		 * Loop until done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 		dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SG: Chain Required! sg done %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 				ioc->name, sg_done));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 		/* Set LAST_ELEMENT flag for last non-chain element
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 		 * in the buffer. Since psge points at the NEXT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 		 * SGE element, go back one SGE element, update the flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 		 * and reset the pointer. (Note: sgflags & thisxfer are already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 		 * set properly).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 		if (sg_done) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 			u32 *ptmp = (u32 *) (psge - ioc->SGE_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 			sgflags = le32_to_cpu(*ptmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 			sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 			*ptmp = cpu_to_le32(sgflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 		if (chainSge) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 			/* The current buffer is a chain buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 			 * chainSge points to the previous Chain Element.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 			 * Update its chain element Offset and Length (must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 			 * include chain element size) fields.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 			 * Old chain element is now complete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 			u8 nextChain = (u8) (sgeOffset >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 			sgeOffset += ioc->SGE_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 			ioc->add_chain((char *)chainSge, nextChain, sgeOffset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 					 ioc->ChainBufferDMA + chain_dma_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 			/* The original MF buffer requires a chain buffer -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 			 * set the offset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 			 * Last element in this MF is a chain element.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 			pReq->ChainOffset = (u8) (sgeOffset >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 			RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor)  + 1) & 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 			dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 			ioc->RequestNB[req_idx] = RequestNB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 		sges_left -= sg_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 		/* NOTE: psge points to the beginning of the chain element
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 		 * in current buffer. Get a chain buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 		if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 			dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 			    "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348)  			    ioc->name, pReq->CDB[0], SCpnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 			return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 		/* Update the tracking arrays.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 		 * If chainSge == NULL, update ReqToChain, else ChainToChain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 		if (chainSge) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 			ioc->ChainToChain[chain_idx] = newIndex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 			ioc->ReqToChain[req_idx] = newIndex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 		chain_idx = newIndex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 		chain_dma_off = ioc->req_sz * chain_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 		/* Populate the chainSGE for the current buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 		 * - Set chain buffer pointer to psge and fill
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 		 *   out the Address and Flags fields.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 		chainSge = (char *) psge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 		dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "  Current buff @ %p (index 0x%x)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 		    ioc->name, psge, req_idx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 		/* Start the SGE for the next buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 		psge = (char *) (ioc->ChainBuffer + chain_dma_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 		sgeOffset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 		sg_done = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 		dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "  Chain buff @ %p (index 0x%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 		    ioc->name, psge, chain_idx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 		/* Start the SGE for the next buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 		goto nextSGEset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	return SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) } /* mptscsih_AddSGE() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391)     U32 SlotStatus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	MPT_FRAME_HDR *mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	SEPRequest_t 	 *SEPMsg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	if (ioc->bus_type != SAS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	/* Not supported for hidden raid components
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 		dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: no msg frames!!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 		    ioc->name,__func__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	SEPMsg = (SEPRequest_t *)mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	SEPMsg->Bus = vtarget->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	SEPMsg->TargetID = vtarget->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	SEPMsg->SlotStatus = SlotStatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	    "Sending SEP cmd=%x channel=%d id=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	    ioc->name, SlotStatus, SEPMsg->Bus, SEPMsg->TargetID));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) #ifdef CONFIG_FUSION_LOGGING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424)  *	mptscsih_info_scsiio - debug print info on reply frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425)  *	@ioc: Pointer to MPT_ADAPTER structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426)  *	@sc: original scsi cmnd pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427)  *	@pScsiReply: Pointer to MPT reply frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429)  *	MPT_DEBUG_REPLY needs to be enabled to obtain this info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431)  *	Refer to lsi/mpi.h.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432)  **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) mptscsih_info_scsiio(MPT_ADAPTER *ioc, struct scsi_cmnd *sc, SCSIIOReply_t * pScsiReply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	char	*desc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	char	*desc1 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	u16	ioc_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	u8	skey, asc, ascq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	ioc_status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	switch (ioc_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	case MPI_IOCSTATUS_SUCCESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 		desc = "success";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	case MPI_IOCSTATUS_SCSI_INVALID_BUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 		desc = "invalid bus";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	case MPI_IOCSTATUS_SCSI_INVALID_TARGETID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 		desc = "invalid target_id";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 		desc = "device not there";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 		desc = "data overrun";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 		desc = "data underrun";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 	case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 		desc = "I/O data error";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 		desc = "protocol error";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 		desc = "task terminated";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 		desc = "residual mismatch";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 		desc = "task management failed";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 		desc = "IOC terminated";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 		desc = "ext terminated";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 		desc = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 		break;
^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) 	switch (pScsiReply->SCSIStatus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	case MPI_SCSI_STATUS_SUCCESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 		desc1 = "success";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	case MPI_SCSI_STATUS_CHECK_CONDITION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 		desc1 = "check condition";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	case MPI_SCSI_STATUS_CONDITION_MET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 		desc1 = "condition met";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	case MPI_SCSI_STATUS_BUSY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 		desc1 = "busy";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	case MPI_SCSI_STATUS_INTERMEDIATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 		desc1 = "intermediate";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	case MPI_SCSI_STATUS_INTERMEDIATE_CONDMET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 		desc1 = "intermediate condmet";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	case MPI_SCSI_STATUS_RESERVATION_CONFLICT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 		desc1 = "reservation conflict";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	case MPI_SCSI_STATUS_COMMAND_TERMINATED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 		desc1 = "command terminated";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	case MPI_SCSI_STATUS_TASK_SET_FULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 		desc1 = "task set full";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	case MPI_SCSI_STATUS_ACA_ACTIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 		desc1 = "aca active";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	case MPI_SCSI_STATUS_FCPEXT_DEVICE_LOGGED_OUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 		desc1 = "fcpext device logged out";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	case MPI_SCSI_STATUS_FCPEXT_NO_LINK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 		desc1 = "fcpext no link";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	case MPI_SCSI_STATUS_FCPEXT_UNASSIGNED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 		desc1 = "fcpext unassigned";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 		desc1 = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	scsi_print_command(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	printk(MYIOC_s_DEBUG_FMT "\tfw_channel = %d, fw_id = %d, lun = %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	    ioc->name, pScsiReply->Bus, pScsiReply->TargetID, sc->device->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	printk(MYIOC_s_DEBUG_FMT "\trequest_len = %d, underflow = %d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	    "resid = %d\n", ioc->name, scsi_bufflen(sc), sc->underflow,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	    scsi_get_resid(sc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	printk(MYIOC_s_DEBUG_FMT "\ttag = %d, transfer_count = %d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	    "sc->result = %08X\n", ioc->name, le16_to_cpu(pScsiReply->TaskTag),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	    le32_to_cpu(pScsiReply->TransferCount), sc->result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	printk(MYIOC_s_DEBUG_FMT "\tiocstatus = %s (0x%04x), "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	    "scsi_status = %s (0x%02x), scsi_state = (0x%02x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	    ioc->name, desc, ioc_status, desc1, pScsiReply->SCSIStatus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	    pScsiReply->SCSIState);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	if (pScsiReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 		skey = sc->sense_buffer[2] & 0x0F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 		asc = sc->sense_buffer[12];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 		ascq = sc->sense_buffer[13];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 		printk(MYIOC_s_DEBUG_FMT "\t[sense_key,asc,ascq]: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 		    "[0x%02x,0x%02x,0x%02x]\n", ioc->name, skey, asc, ascq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	 *  Look for + dump FCP ResponseInfo[]!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	if (pScsiReply->SCSIState & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	    pScsiReply->ResponseInfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 		printk(MYIOC_s_DEBUG_FMT "response_info = %08xh\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 		    ioc->name, le32_to_cpu(pScsiReply->ResponseInfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572)  *	mptscsih_io_done - Main SCSI IO callback routine registered to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573)  *	Fusion MPT (base) driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574)  *	@ioc: Pointer to MPT_ADAPTER structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575)  *	@mf: Pointer to original MPT request frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576)  *	@r: Pointer to MPT reply frame (NULL if TurboReply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578)  *	This routine is called from mpt.c::mpt_interrupt() at the completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579)  *	of any SCSI IO request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580)  *	This routine is registered with the Fusion MPT (base) driver at driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581)  *	load/init time via the mpt_register() API call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583)  *	Returns 1 indicating alloc'd request frame ptr should be freed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	struct scsi_cmnd	*sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	MPT_SCSI_HOST	*hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	SCSIIORequest_t	*pScsiReq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	SCSIIOReply_t	*pScsiReply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	u16		 req_idx, req_idx_MR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	VirtDevice	 *vdevice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	VirtTarget	 *vtarget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	hd = shost_priv(ioc->sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	req_idx_MR = (mr != NULL) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	    le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx) : req_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	/* Special case, where already freed message frame is received from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	 * Firmware. It happens with Resetting IOC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	 * Return immediately. Do not care
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	if ((req_idx != req_idx_MR) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	    (le32_to_cpu(mf->u.frame.linkage.arg1) == 0xdeadbeaf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	sc = mptscsih_getclear_scsi_lookup(ioc, req_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	if (sc == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 		MPIHeader_t *hdr = (MPIHeader_t *)mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 		/* Remark: writeSDP1 will use the ScsiDoneCtx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 		 * If a SCSI I/O cmd, device disabled by OS and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 		 * completion done. Cannot touch sc struct. Just free mem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 		if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 			printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 			ioc->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 		mptscsih_freeChainBuffers(ioc, req_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	if ((unsigned char *)mf != sc->host_scribble) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 		mptscsih_freeChainBuffers(ioc, req_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	if (ioc->bus_type == SAS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 		VirtDevice *vdevice = sc->device->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 		if (!vdevice || !vdevice->vtarget ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 		    vdevice->vtarget->deleted) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 			sc->result = DID_NO_CONNECT << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	sc->host_scribble = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	sc->result = DID_OK << 16;		/* Set default reply as OK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	pScsiReq = (SCSIIORequest_t *) mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	pScsiReply = (SCSIIOReply_t *) mr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 		dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 			"ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 			ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	}else{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 		dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 			"ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 			ioc->name, mf, mr, sc, req_idx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 	if (pScsiReply == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 		/* special context reply handling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 		;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 		u32	 xfer_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 		u16	 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 		u8	 scsi_state, scsi_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 		u32	 log_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 		status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 		scsi_state = pScsiReply->SCSIState;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 		scsi_status = pScsiReply->SCSIStatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 		xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 		scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 		log_info = le32_to_cpu(pScsiReply->IOCLogInfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 		 *  if we get a data underrun indication, yet no data was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 		 *  transferred and the SCSI status indicates that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 		 *  command was never started, change the data underrun
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 		 *  to success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 		if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 		    (scsi_status == MPI_SCSI_STATUS_BUSY ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 		     scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 		     scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 			status = MPI_IOCSTATUS_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 		if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 			mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 		 *  Look for + dump FCP ResponseInfo[]!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 		if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 		    pScsiReply->ResponseInfo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 			printk(MYIOC_s_NOTE_FMT "[%d:%d:%d:%llu] "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 			"FCP_ResponseInfo=%08xh\n", ioc->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 			sc->device->host->host_no, sc->device->channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 			sc->device->id, sc->device->lun,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 			le32_to_cpu(pScsiReply->ResponseInfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 		switch(status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 		case MPI_IOCSTATUS_BUSY:			/* 0x0002 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 		case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:	/* 0x0006 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 			/* CHECKME!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 			 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 			 * But not: DID_BUS_BUSY lest one risk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 			 * killing interrupt handler:-(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 			sc->result = SAM_STAT_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 		case MPI_IOCSTATUS_SCSI_INVALID_BUS:		/* 0x0041 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 		case MPI_IOCSTATUS_SCSI_INVALID_TARGETID:	/* 0x0042 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 			sc->result = DID_BAD_TARGET << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 		case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:	/* 0x0043 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 			/* Spoof to SCSI Selection Timeout! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 			if (ioc->bus_type != FC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 				sc->result = DID_NO_CONNECT << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 			/* else fibre, just stall until rescan event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 				sc->result = DID_REQUEUE << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 			if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 				hd->sel_timeout[pScsiReq->TargetID]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 			vdevice = sc->device->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 			if (!vdevice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 			vtarget = vdevice->vtarget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 			if (vtarget->tflags & MPT_TARGET_FLAGS_LED_ON) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 				mptscsih_issue_sep_command(ioc, vtarget,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 				    MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 				vtarget->tflags &= ~MPT_TARGET_FLAGS_LED_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 		case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:		/* 0x004B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 			if ( ioc->bus_type == SAS ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 				u16 ioc_status =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 				    le16_to_cpu(pScsiReply->IOCStatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 				if ((ioc_status &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 					MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 					&&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 					((log_info & SAS_LOGINFO_MASK) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 					SAS_LOGINFO_NEXUS_LOSS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 						VirtDevice *vdevice =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 						sc->device->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 					    /* flag the device as being in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 					     * device removal delay so we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 					     * notify the midlayer to hold off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 					     * on timeout eh */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 						if (vdevice && vdevice->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 							vtarget &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 							vdevice->vtarget->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 							raidVolume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 							printk(KERN_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 							"Skipping Raid Volume"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 							"for inDMD\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 						else if (vdevice &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 							vdevice->vtarget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 							vdevice->vtarget->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 								inDMD = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 					    sc->result =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 						    (DID_TRANSPORT_DISRUPTED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 						    << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 					    break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 			} else if (ioc->bus_type == FC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 				 * The FC IOC may kill a request for variety of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 				 * reasons, some of which may be recovered by a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 				 * retry, some which are unlikely to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 				 * recovered. Return DID_ERROR instead of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 				 * DID_RESET to permit retry of the command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 				 * just not an infinite number of them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 				sc->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 			 * Allow non-SAS & non-NEXUS_LOSS to drop into below code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 		case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:	/* 0x0048 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 			/* Linux handles an unsolicited DID_RESET better
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 			 * than an unsolicited DID_ABORT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 			sc->result = DID_RESET << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 		case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:		/* 0x004C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 			if (ioc->bus_type == FC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 				sc->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 				sc->result = DID_RESET << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 		case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:	/* 0x0049 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 			scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 			if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 				sc->result=DID_SOFT_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 			else /* Sufficient data transfer occurred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 				sc->result = (DID_OK << 16) | scsi_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 			dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 			    "RESIDUAL_MISMATCH: result=%x on channel=%d id=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 			    ioc->name, sc->result, sc->device->channel, sc->device->id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 		case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:		/* 0x0045 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 			 *  Do upfront check for valid SenseData and give it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 			 *  precedence!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 			sc->result = (DID_OK << 16) | scsi_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 			if (!(scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
^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) 				 * For an Errata on LSI53C1030
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 				 * When the length of request data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 				 * and transfer data are different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 				 * with result of command (READ or VERIFY),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 				 * DID_SOFT_ERROR is set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 				if (ioc->bus_type == SPI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 					if ((pScsiReq->CDB[0] == READ_6  && ((pScsiReq->CDB[1] & 0x02) == 0)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 					    pScsiReq->CDB[0] == READ_10 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 					    pScsiReq->CDB[0] == READ_12 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 						(pScsiReq->CDB[0] == READ_16 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 						((pScsiReq->CDB[1] & 0x02) == 0)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 					    pScsiReq->CDB[0] == VERIFY  ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 					    pScsiReq->CDB[0] == VERIFY_16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 						if (scsi_bufflen(sc) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 							xfer_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 							sc->result =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 							DID_SOFT_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 						    printk(KERN_WARNING "Errata"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 						    "on LSI53C1030 occurred."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 						    "sc->req_bufflen=0x%02x,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 						    "xfer_cnt=0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 						    scsi_bufflen(sc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 						    xfer_cnt);
^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) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 				if (xfer_cnt < sc->underflow) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 					if (scsi_status == SAM_STAT_BUSY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 						sc->result = SAM_STAT_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 					else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 						sc->result = DID_SOFT_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 				if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 					/* What to do?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 				 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 					sc->result = DID_SOFT_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 				else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 					/*  Not real sure here either...  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 					sc->result = DID_RESET << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 			dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 			    "  sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 			    ioc->name, sc->underflow));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 			dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 			    "  ActBytesXferd=%02xh\n", ioc->name, xfer_cnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 			/* Report Queue Full
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 			if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 				mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 		case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:		/* 0x0044 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 			scsi_set_resid(sc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 		case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:	/* 0x0040 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 		case MPI_IOCSTATUS_SUCCESS:			/* 0x0000 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 			sc->result = (DID_OK << 16) | scsi_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 			if (scsi_state == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 				;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 			} else if (scsi_state &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 			    MPI_SCSI_STATE_AUTOSENSE_VALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 				 * For potential trouble on LSI53C1030.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 				 * (date:2007.xx.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 				 * It is checked whether the length of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 				 * request data is equal to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 				 * the length of transfer and residual.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 				 * MEDIUM_ERROR is set by incorrect data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 				if ((ioc->bus_type == SPI) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 					(sc->sense_buffer[2] & 0x20)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 					u32	 difftransfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 					difftransfer =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 					sc->sense_buffer[3] << 24 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 					sc->sense_buffer[4] << 16 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 					sc->sense_buffer[5] << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 					sc->sense_buffer[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 					if (((sc->sense_buffer[3] & 0x80) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 						0x80) && (scsi_bufflen(sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 						!= xfer_cnt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 						sc->sense_buffer[2] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 						    MEDIUM_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 						sc->sense_buffer[12] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 						sc->sense_buffer[13] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 						printk(KERN_WARNING"Errata"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 						"on LSI53C1030 occurred."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 						"sc->req_bufflen=0x%02x,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 						"xfer_cnt=0x%02x\n" ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 						scsi_bufflen(sc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 						xfer_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 					if (((sc->sense_buffer[3] & 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 						!= 0x80) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 						(scsi_bufflen(sc) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 						xfer_cnt + difftransfer)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 						sc->sense_buffer[2] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 							MEDIUM_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 						sc->sense_buffer[12] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 						sc->sense_buffer[13] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 						printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 						"Errata on LSI53C1030 occurred"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 						"sc->req_bufflen=0x%02x,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 						" xfer_cnt=0x%02x,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 						"difftransfer=0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 						scsi_bufflen(sc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 						xfer_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 						difftransfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 				 * If running against circa 200003dd 909 MPT f/w,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 				 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 				 * (QUEUE_FULL) returned from device! --> get 0x0000?128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 				 * and with SenseBytes set to 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 				if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 					mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 			else if (scsi_state &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 			         (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 			   ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 				 * What to do?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 				sc->result = DID_SOFT_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 			else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 				/*  Not real sure here either...  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 				sc->result = DID_RESET << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 			else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 				/* Device Inq. data indicates that it supports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 				 * QTags, but rejects QTag messages.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 				 * This command completed OK.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 				 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 				 * Not real sure here either so do nothing...  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 			if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 				mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 			/* Add handling of:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 			 * Reservation Conflict, Busy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 			 * Command Terminated, CHECK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 		case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:		/* 0x0047 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 			sc->result = DID_SOFT_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 		case MPI_IOCSTATUS_INVALID_FUNCTION:		/* 0x0001 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 		case MPI_IOCSTATUS_INVALID_SGL:			/* 0x0003 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 		case MPI_IOCSTATUS_INTERNAL_ERROR:		/* 0x0004 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		case MPI_IOCSTATUS_RESERVED:			/* 0x0005 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 		case MPI_IOCSTATUS_INVALID_FIELD:		/* 0x0007 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 		case MPI_IOCSTATUS_INVALID_STATE:		/* 0x0008 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 		case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:		/* 0x0046 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 		case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED:	/* 0x004A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 			 * What to do?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 			sc->result = DID_SOFT_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 		}	/* switch(status) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) #ifdef CONFIG_FUSION_LOGGING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 		if (sc->result && (ioc->debug_level & MPT_DEBUG_REPLY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 			mptscsih_info_scsiio(ioc, sc, pScsiReply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	} /* end of address reply case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	/* Unmap the DMA buffers, if any. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	scsi_dma_unmap(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	sc->scsi_done(sc);		/* Issue the command callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	/* Free Chain buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 	mptscsih_freeChainBuffers(ioc, req_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)  *	mptscsih_flush_running_cmds - For each command found, search
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)  *		Scsi_Host instance taskQ and reply to OS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)  *		Called only if recovering from a FW reload.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)  *	@hd: Pointer to a SCSI HOST structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)  *	Returns: None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)  *	Must be called while new I/Os are being queued.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	MPT_ADAPTER *ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	struct scsi_cmnd *sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	SCSIIORequest_t	*mf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	int		 ii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	int		 channel, id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	for (ii= 0; ii < ioc->req_depth; ii++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 		sc = mptscsih_getclear_scsi_lookup(ioc, ii);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 		if (!sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 		mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(ioc, ii);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 		if (!mf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 		channel = mf->Bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 		id = mf->TargetID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 		mptscsih_freeChainBuffers(ioc, ii);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 		mpt_free_msg_frame(ioc, (MPT_FRAME_HDR *)mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 		if ((unsigned char *)mf != sc->host_scribble)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 		scsi_dma_unmap(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 		sc->result = DID_RESET << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 		sc->host_scribble = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 		dtmprintk(ioc, sdev_printk(KERN_INFO, sc->device, MYIOC_s_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 		    "completing cmds: fw_channel %d, fw_id %d, sc=%p, mf = %p, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 		    "idx=%x\n", ioc->name, channel, id, sc, mf, ii));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 		sc->scsi_done(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) EXPORT_SYMBOL(mptscsih_flush_running_cmds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)  *	mptscsih_search_running_cmds - Delete any commands associated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)  *		with the specified target and lun. Function called only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)  *		when a lun is disable by mid-layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)  *		Do NOT access the referenced scsi_cmnd structure or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)  *		members. Will cause either a paging or NULL ptr error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)  *		(BUT, BUT, BUT, the code does reference it! - mdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)  *      @hd: Pointer to a SCSI HOST structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)  *	@vdevice: per device private data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)  *	Returns: None.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)  *	Called from slave_destroy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 	SCSIIORequest_t	*mf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	int		 ii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 	struct scsi_cmnd *sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	struct scsi_lun  lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	MPT_ADAPTER *ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	unsigned long	flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	for (ii = 0; ii < ioc->req_depth; ii++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 		if ((sc = ioc->ScsiLookup[ii]) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 			mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(ioc, ii);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 			if (mf == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 			/* If the device is a hidden raid component, then its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 			 * expected that the mf->function will be RAID_SCSI_IO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 			if (vdevice->vtarget->tflags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 			    MPT_TARGET_FLAGS_RAID_COMPONENT && mf->Function !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 			    MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 			int_to_scsilun(vdevice->lun, &lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 			if ((mf->Bus != vdevice->vtarget->channel) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 			    (mf->TargetID != vdevice->vtarget->id) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 			    memcmp(lun.scsi_lun, mf->LUN, 8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 			if ((unsigned char *)mf != sc->host_scribble)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 			ioc->ScsiLookup[ii] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 			spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 			mptscsih_freeChainBuffers(ioc, ii);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 			mpt_free_msg_frame(ioc, (MPT_FRAME_HDR *)mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 			scsi_dma_unmap(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 			sc->host_scribble = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 			sc->result = DID_NO_CONNECT << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 			dtmprintk(ioc, sdev_printk(KERN_INFO, sc->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 			   MYIOC_s_FMT "completing cmds: fw_channel %d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 			   "fw_id %d, sc=%p, mf = %p, idx=%x\n", ioc->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 			   vdevice->vtarget->channel, vdevice->vtarget->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 			   sc, mf, ii));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 			sc->scsi_done(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 			spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)  *	mptscsih_report_queue_full - Report QUEUE_FULL status returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)  *	from a SCSI target device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)  *	@sc: Pointer to scsi_cmnd structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)  *	@pScsiReply: Pointer to SCSIIOReply_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)  *	@pScsiReq: Pointer to original SCSI request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)  *	This routine periodically reports QUEUE_FULL status returned from a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)  *	SCSI target device.  It reports this to the console via kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)  *	printk() API call, not more than once every 10 seconds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	long time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	MPT_SCSI_HOST		*hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	MPT_ADAPTER	*ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	if (sc->device == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	if (sc->device->host == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	if ((hd = shost_priv(sc->device->host)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	if (time - hd->last_queue_full > 10 * HZ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 		dprintk(ioc, printk(MYIOC_s_WARN_FMT "Device (%d:%d:%llu) reported QUEUE_FULL!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 				ioc->name, 0, sc->device->id, sc->device->lun));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 		hd->last_queue_full = time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)  *	mptscsih_remove - Removed scsi devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)  *	@pdev: Pointer to pci_dev structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) mptscsih_remove(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 	struct Scsi_Host 	*host = ioc->sh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 	MPT_SCSI_HOST		*hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	int sz1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	if (host == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 		hd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 		hd = shost_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 	mptscsih_shutdown(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 	sz1=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	if (ioc->ScsiLookup != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 		sz1 = ioc->req_depth * sizeof(void *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 		kfree(ioc->ScsiLookup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 		ioc->ScsiLookup = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 	dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 	    "Free'd ScsiLookup (%d) memory\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	    ioc->name, sz1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	if (hd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 		kfree(hd->info_kbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	/* NULL the Scsi_Host pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	ioc->sh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	if (host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 		scsi_host_put(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 	mpt_detach(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)  *	mptscsih_shutdown - reboot notifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) mptscsih_shutdown(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)  *	mptscsih_suspend - Fusion MPT scsi driver suspend routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	scsi_block_requests(ioc->sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	flush_scheduled_work();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	mptscsih_shutdown(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	return mpt_suspend(pdev,state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) }
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)  *	mptscsih_resume - Fusion MPT scsi driver resume routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) mptscsih_resume(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 	rc = mpt_resume(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	scsi_unblock_requests(ioc->sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)  *	mptscsih_info - Return information about MPT adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)  *	@SChost: Pointer to Scsi_Host structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)  *	(linux scsi_host_template.info routine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)  *	Returns pointer to buffer where information was written.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) const char *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) mptscsih_info(struct Scsi_Host *SChost)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 	MPT_SCSI_HOST *h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 	int size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 	h = shost_priv(SChost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 	if (h->info_kbuf == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 		if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 			return h->info_kbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 	h->info_kbuf[0] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 	mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 	h->info_kbuf[size-1] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	return h->info_kbuf;
^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) int mptscsih_show_info(struct seq_file *m, struct Scsi_Host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 	MPT_SCSI_HOST	*hd = shost_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	MPT_ADAPTER	*ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 	seq_printf(m, "%s: %s, ", ioc->name, ioc->prod_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 	seq_printf(m, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 	seq_printf(m, "Ports=%d, ", ioc->facts.NumberOfPorts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 	seq_printf(m, "MaxQ=%d\n", ioc->req_depth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) }
^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) #define ADD_INDEX_LOG(req_ent)	do { } while(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)  *	mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)  *	@SCpnt: Pointer to scsi_cmnd structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)  *	(linux scsi_host_template.queuecommand routine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)  *	This is the primary SCSI IO start routine.  Create a MPI SCSIIORequest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)  *	from a linux scsi_cmnd request and send it to the IOC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)  *	Returns 0. (rtn value discarded by linux scsi mid-layer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) mptscsih_qcmd(struct scsi_cmnd *SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 	MPT_SCSI_HOST		*hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 	MPT_FRAME_HDR		*mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	SCSIIORequest_t		*pScsiReq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 	VirtDevice		*vdevice = SCpnt->device->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 	u32	 datalen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 	u32	 scsictl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	u32	 scsidir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 	u32	 cmd_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	int	 my_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	int	 ii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 	MPT_ADAPTER *ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 	hd = shost_priv(SCpnt->device->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 	ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 	dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "qcmd: SCpnt=%p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 		ioc->name, SCpnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 	if (ioc->taskmgmt_quiesce_io)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 		return SCSI_MLQUEUE_HOST_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	 *  Put together a MPT SCSI request...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 	if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 		dprintk(ioc, printk(MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 				ioc->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 		return SCSI_MLQUEUE_HOST_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	pScsiReq = (SCSIIORequest_t *) mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	ADD_INDEX_LOG(my_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 	/*    TUR's being issued with scsictl=0x02000000 (DATA_IN)!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	 *    Seems we may receive a buffer (datalen>0) even when there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	 *    will be no data transfer!  GRRRRR...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 		datalen = scsi_bufflen(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 		scsidir = MPI_SCSIIO_CONTROL_READ;	/* DATA IN  (host<--ioc<--dev) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	} else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 		datalen = scsi_bufflen(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 		scsidir = MPI_SCSIIO_CONTROL_WRITE;	/* DATA OUT (host-->ioc-->dev) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 		datalen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 		scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 	/* Default to untagged. Once a target structure has been allocated,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 	 * use the Inquiry data to determine if device supports tagged.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 	if ((vdevice->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	    SCpnt->device->tagged_supported)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 		scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 		scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 	/* Use the above information to set up the message frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 	pScsiReq->TargetID = (u8) vdevice->vtarget->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 	pScsiReq->Bus = vdevice->vtarget->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 	pScsiReq->ChainOffset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 	if (vdevice->vtarget->tflags &  MPT_TARGET_FLAGS_RAID_COMPONENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 		pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 		pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 	pScsiReq->CDBLength = SCpnt->cmd_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 	pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 	pScsiReq->Reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 	pScsiReq->MsgFlags = mpt_msg_flags(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 	int_to_scsilun(SCpnt->device->lun, (struct scsi_lun *)pScsiReq->LUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 	pScsiReq->Control = cpu_to_le32(scsictl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 	 *  Write SCSI CDB into the message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 	cmd_len = SCpnt->cmd_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 	for (ii=0; ii < cmd_len; ii++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 		pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 	for (ii=cmd_len; ii < 16; ii++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 		pScsiReq->CDB[ii] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 	/* DataLength */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 	pScsiReq->DataLength = cpu_to_le32(datalen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 	/* SenseBuffer low address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 	pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 					   + (my_idx * MPT_SENSE_BUFFER_ALLOC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 	/* Now add the SG list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 	 * Always have a SGE even if null length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 	if (datalen == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 		/* Add a NULL SGE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 		ioc->add_sge((char *)&pScsiReq->SGL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 			MPT_SGE_FLAGS_SSIMPLE_READ | 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 			(dma_addr_t) -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 		/* Add a 32 or 64 bit SGE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 		if (mptscsih_AddSGE(ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 			goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	SCpnt->host_scribble = (unsigned char *)mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 	mptscsih_set_scsi_lookup(ioc, my_idx, SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 	mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 	dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 			ioc->name, SCpnt, mf, my_idx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 	DBG_DUMP_REQUEST_FRAME(ioc, (u32 *)mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433)  fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 	mptscsih_freeChainBuffers(ioc, my_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 	mpt_free_msg_frame(ioc, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 	return SCSI_MLQUEUE_HOST_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441)  *	mptscsih_freeChainBuffers - Function to free chain buffers associated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)  *	with a SCSI IO request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443)  *	@hd: Pointer to the MPT_SCSI_HOST instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)  *	@req_idx: Index of the SCSI IO request frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446)  *	Called if SG chain buffer allocation fails and mptscsih callbacks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447)  *	No return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 	MPT_FRAME_HDR *chain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 	int chain_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 	int next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 	/* Get the first chain index and reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 	 * tracker state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 	chain_idx = ioc->ReqToChain[req_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 	ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 	while (chain_idx != MPT_HOST_NO_CHAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 		/* Save the next chain buffer index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 		next = ioc->ChainToChain[chain_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 		/* Free this chain buffer and reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 		 * tracker
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 		ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 		chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 					+ (chain_idx * ioc->req_sz));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 		spin_lock_irqsave(&ioc->FreeQlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 		list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 		spin_unlock_irqrestore(&ioc->FreeQlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 		dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FreeChainBuffers (index %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 				ioc->name, chain_idx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 		/* handle next */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 		chain_idx = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)  *	Reset Handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496)  *	mptscsih_IssueTaskMgmt - Generic send Task Management function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)  *	@hd: Pointer to MPT_SCSI_HOST structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)  *	@type: Task Management type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499)  *	@channel: channel number for task management
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500)  *	@id: Logical Target ID for reset (if appropriate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501)  *	@lun: Logical Unit for reset (if appropriate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)  *	@ctx2abort: Context for the task to be aborted (if appropriate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503)  *	@timeout: timeout for task management control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505)  *	Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)  *	or a non-interrupt thread.  In the former, must not call schedule().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508)  *	Not all fields are meaningfull for all task types.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)  *	Returns 0 for SUCCESS, or FAILED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)  **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, u64 lun,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 	int ctx2abort, ulong timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 	MPT_FRAME_HDR	*mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 	SCSITaskMgmt_t	*pScsiTm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 	int		 ii;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 	int		 retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 	MPT_ADAPTER 	*ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 	u8		 issue_hard_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 	u32		 ioc_raw_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 	unsigned long	 time_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 	issue_hard_reset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 	ioc_raw_state = mpt_GetIocState(ioc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 	if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 		printk(MYIOC_s_WARN_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 			"TaskMgmt type=%x: IOC Not operational (0x%x)!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 			ioc->name, type, ioc_raw_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 		printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 		    ioc->name, __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 		if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 			printk(MYIOC_s_WARN_FMT "TaskMgmt HardReset "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 			    "FAILED!!\n", ioc->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 	/* DOORBELL ACTIVE check is not required if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 	*  MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q is supported.
^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) 	if (!((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 		 && (ioc->facts.MsgVersion >= MPI_VERSION_01_05)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 		(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 		printk(MYIOC_s_WARN_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 			"TaskMgmt type=%x: ioc_state: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 			"DOORBELL_ACTIVE (0x%x)!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 			ioc->name, type, ioc_raw_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 		return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 	mutex_lock(&ioc->taskmgmt_cmds.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 		mf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 		retval = FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 	/* Return Fail to calling function if no message frames available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 	if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 		dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 			"TaskMgmt no msg frames!!\n", ioc->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 		retval = FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 		mpt_clear_taskmgmt_in_progress_flag(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 			ioc->name, mf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 	/* Format the Request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 	pScsiTm = (SCSITaskMgmt_t *) mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 	pScsiTm->TargetID = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 	pScsiTm->Bus = channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 	pScsiTm->ChainOffset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 	pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 	pScsiTm->Reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 	pScsiTm->TaskType = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 	pScsiTm->Reserved1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 	pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586)                     ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 	int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 	for (ii=0; ii < 7; ii++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 		pScsiTm->Reserved2[ii] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 	pScsiTm->TaskMsgContext = ctx2abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt: ctx2abort (0x%08x) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 		"task_type = 0x%02X, timeout = %ld\n", ioc->name, ctx2abort,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 		type, timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 	DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)pScsiTm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 	INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 	time_count = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 	if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 	    (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 		mpt_put_msg_frame_hi_pri(ioc->TaskCtx, ioc, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 		retval = mpt_send_handshake_request(ioc->TaskCtx, ioc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 			sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 		if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 			dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 				"TaskMgmt handshake FAILED!(mf=%p, rc=%d) \n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 				ioc->name, mf, retval));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 			mpt_free_msg_frame(ioc, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 			mpt_clear_taskmgmt_in_progress_flag(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 			goto out;
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 	wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 		timeout*HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 	if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 		retval = FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 		dtmprintk(ioc, printk(MYIOC_s_ERR_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 		    "TaskMgmt TIMED OUT!(mf=%p)\n", ioc->name, mf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 		mpt_clear_taskmgmt_in_progress_flag(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 		if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 		issue_hard_reset = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 	retval = mptscsih_taskmgmt_reply(ioc, type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 	    (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 	    "TaskMgmt completed (%d seconds)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 	    ioc->name, jiffies_to_msecs(jiffies - time_count)/1000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 	CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 	if (issue_hard_reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 		printk(MYIOC_s_WARN_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 		       "Issuing Reset from %s!! doorbell=0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 		       ioc->name, __func__, mpt_GetIocState(ioc, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 		retval = (ioc->bus_type == SAS) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 			mpt_HardResetHandler(ioc, CAN_SLEEP) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 			mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 		mpt_free_msg_frame(ioc, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 	retval = (retval == 0) ? 0 : FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 	mutex_unlock(&ioc->taskmgmt_cmds.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) EXPORT_SYMBOL(mptscsih_IssueTaskMgmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 	switch (ioc->bus_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 	case FC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 		return 40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 	case SAS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 		return 30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 	case SPI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 		return 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674)  *	mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675)  *	@SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677)  *	(linux scsi_host_template.eh_abort_handler routine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679)  *	Returns SUCCESS or FAILED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680)  **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) mptscsih_abort(struct scsi_cmnd * SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 	MPT_SCSI_HOST	*hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 	MPT_FRAME_HDR	*mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 	u32		 ctx2abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 	int		 scpnt_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 	int		 retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 	VirtDevice	 *vdevice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 	MPT_ADAPTER	*ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 	/* If we can't locate our host adapter structure, return FAILED status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 	if ((hd = shost_priv(SCpnt->device->host)) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 		SCpnt->result = DID_RESET << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 		SCpnt->scsi_done(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 		printk(KERN_ERR MYNAM ": task abort: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 		    "can't locate host! (sc=%p)\n", SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 		return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 	ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 	printk(MYIOC_s_INFO_FMT "attempting task abort! (sc=%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 	       ioc->name, SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 	scsi_print_command(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 	vdevice = SCpnt->device->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 	if (!vdevice || !vdevice->vtarget) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 		    "task abort: device has been deleted (sc=%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 		    ioc->name, SCpnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 		SCpnt->result = DID_NO_CONNECT << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 		SCpnt->scsi_done(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 		retval = SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 	/* Task aborts are not supported for hidden raid components.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 		    "task abort: hidden raid component (sc=%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 		    ioc->name, SCpnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 		SCpnt->result = DID_RESET << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 		retval = FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 	/* Task aborts are not supported for volumes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 	if (vdevice->vtarget->raidVolume) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 		    "task abort: raid volume (sc=%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 		    ioc->name, SCpnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 		SCpnt->result = DID_RESET << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 		retval = FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 	/* Find this command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 	if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(ioc, SCpnt)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 		/* Cmd not found in ScsiLookup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 		 * Do OS callback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 		SCpnt->result = DID_RESET << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "task abort: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 		   "Command not in the active list! (sc=%p)\n", ioc->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 		   SCpnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 		retval = SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 	if (ioc->timeouts < -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 		ioc->timeouts++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 	if (mpt_fwfault_debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 		mpt_halt_firmware(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 	/* Most important!  Set TaskMsgContext to SCpnt's MsgContext!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 	 * (the IO to be ABORT'd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 	 * NOTE: Since we do not byteswap MsgContext, we do not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 	 *	 swap it here either.  It is an opaque cookie to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 	 *	 the controller, so it does not matter. -DaveM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 	mf = MPT_INDEX_2_MFPTR(ioc, scpnt_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 	ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 	retval = mptscsih_IssueTaskMgmt(hd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 			 MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 			 vdevice->vtarget->channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 			 vdevice->vtarget->id, vdevice->lun,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 			 ctx2abort, mptscsih_get_tm_timeout(ioc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 	if (SCPNT_TO_LOOKUP_IDX(ioc, SCpnt) == scpnt_idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 		    "task abort: command still in active list! (sc=%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 		    ioc->name, SCpnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 		retval = FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 		    "task abort: command cleared from active list! (sc=%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 		    ioc->name, SCpnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 		retval = SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 	printk(MYIOC_s_INFO_FMT "task abort: %s (rv=%04x) (sc=%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 	    ioc->name, ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), retval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 	    SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797)  *	mptscsih_dev_reset - Perform a SCSI TARGET_RESET!  new_eh variant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798)  *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800)  *	(linux scsi_host_template.eh_dev_reset_handler routine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802)  *	Returns SUCCESS or FAILED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803)  **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 	MPT_SCSI_HOST	*hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 	int		 retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 	VirtDevice	 *vdevice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 	MPT_ADAPTER	*ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 	/* If we can't locate our host adapter structure, return FAILED status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 		printk(KERN_ERR MYNAM ": target reset: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 		   "Can't locate host! (sc=%p)\n", SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 		return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 	ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 	printk(MYIOC_s_INFO_FMT "attempting target reset! (sc=%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 	       ioc->name, SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 	scsi_print_command(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 	vdevice = SCpnt->device->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 	if (!vdevice || !vdevice->vtarget) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 		retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 	/* Target reset to hidden raid component is not supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 		retval = FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 	retval = mptscsih_IssueTaskMgmt(hd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 				MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 				vdevice->vtarget->channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 				vdevice->vtarget->id, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 				mptscsih_get_tm_timeout(ioc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 	printk (MYIOC_s_INFO_FMT "target reset: %s (sc=%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 	if (retval == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 		return SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) 		return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857)  *	mptscsih_bus_reset - Perform a SCSI BUS_RESET!	new_eh variant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858)  *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860)  *	(linux scsi_host_template.eh_bus_reset_handler routine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862)  *	Returns SUCCESS or FAILED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863)  **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 	MPT_SCSI_HOST	*hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 	int		 retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 	VirtDevice	 *vdevice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 	MPT_ADAPTER	*ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 	/* If we can't locate our host adapter structure, return FAILED status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 		printk(KERN_ERR MYNAM ": bus reset: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 		   "Can't locate host! (sc=%p)\n", SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 		return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 	ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) 	printk(MYIOC_s_INFO_FMT "attempting bus reset! (sc=%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) 	       ioc->name, SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) 	scsi_print_command(SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) 	if (ioc->timeouts < -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) 		ioc->timeouts++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 	vdevice = SCpnt->device->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 	if (!vdevice || !vdevice->vtarget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 		return SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 	retval = mptscsih_IssueTaskMgmt(hd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 					MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 					vdevice->vtarget->channel, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 					mptscsih_get_tm_timeout(ioc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 	printk(MYIOC_s_INFO_FMT "bus reset: %s (sc=%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 	if (retval == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 		return SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 		return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907)  *	mptscsih_host_reset - Perform a SCSI host adapter RESET (new_eh variant)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908)  *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910)  *	(linux scsi_host_template.eh_host_reset_handler routine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912)  *	Returns SUCCESS or FAILED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) mptscsih_host_reset(struct scsi_cmnd *SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 	MPT_SCSI_HOST *  hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 	int              status = SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 	MPT_ADAPTER	*ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 	int		retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 	/*  If we can't locate the host to reset, then we failed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 		printk(KERN_ERR MYNAM ": host reset: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 		    "Can't locate host! (sc=%p)\n", SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 		return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 	/* make sure we have no outstanding commands at this stage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 	mptscsih_flush_running_cmds(hd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 	ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 	printk(MYIOC_s_INFO_FMT "attempting host reset! (sc=%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 	    ioc->name, SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 	/*  If our attempts to reset the host failed, then return a failed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 	 *  status.  The host will be taken off line by the SCSI mid-layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 	retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 	if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 		status = FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 		status = SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 	printk(MYIOC_s_INFO_FMT "host reset: %s (sc=%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) mptscsih_taskmgmt_reply(MPT_ADAPTER *ioc, u8 type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 	SCSITaskMgmtReply_t *pScsiTmReply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 	u16			 iocstatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 	u32			 termination_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 	int			 retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 	if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 		retval = FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 	DBG_DUMP_TM_REPLY_FRAME(ioc, (u32 *)pScsiTmReply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 	iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 	termination_count = le32_to_cpu(pScsiTmReply->TerminationCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 	    "TaskMgmt fw_channel = %d, fw_id = %d, task_type = 0x%02X,\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 	    "\tiocstatus = 0x%04X, loginfo = 0x%08X, response_code = 0x%02X,\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 	    "\tterm_cmnds = %d\n", ioc->name, pScsiTmReply->Bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 	    pScsiTmReply->TargetID, type, le16_to_cpu(pScsiTmReply->IOCStatus),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 	    le32_to_cpu(pScsiTmReply->IOCLogInfo), pScsiTmReply->ResponseCode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) 	    termination_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 	if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 	    pScsiTmReply->ResponseCode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 		mptscsih_taskmgmt_response_code(ioc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 		    pScsiTmReply->ResponseCode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 	if (iocstatus == MPI_IOCSTATUS_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 		retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 	retval = FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 	if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 		if (termination_count == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 			retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 	if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 	   iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 		retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 	char *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 	switch (response_code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 	case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 		desc = "The task completed.";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) 	case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 		desc = "The IOC received an invalid frame status.";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 	case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 		desc = "The task type is not supported.";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 	case MPI_SCSITASKMGMT_RSP_TM_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 		desc = "The requested task failed.";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 	case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 		desc = "The task completed successfully.";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 	case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 		desc = "The LUN request is invalid.";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 	case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 		desc = "The task is in the IOC queue and has not been sent to target.";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 		desc = "unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 	printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 		ioc->name, response_code, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) EXPORT_SYMBOL(mptscsih_taskmgmt_response_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041)  *	mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042)  *	@ioc: Pointer to MPT_ADAPTER structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043)  *	@mf: Pointer to SCSI task mgmt request frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044)  *	@mr: Pointer to SCSI task mgmt reply frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046)  *	This routine is called from mptbase.c::mpt_interrupt() at the completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047)  *	of any SCSI task management request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048)  *	This routine is registered with the MPT (base) driver at driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049)  *	load/init time via the mpt_register() API call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051)  *	Returns 1 indicating alloc'd request frame ptr should be freed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052)  **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) 	MPT_FRAME_HDR *mr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) 		"TaskMgmt completed (mf=%p, mr=%p)\n", ioc->name, mf, mr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 	ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) 	if (!mr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) 	ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) 	memcpy(ioc->taskmgmt_cmds.reply, mr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 	    min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) 	if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) 		mpt_clear_taskmgmt_in_progress_flag(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 		ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) 		complete(&ioc->taskmgmt_cmds.done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 		if (ioc->bus_type == SAS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 			ioc->schedule_target_reset(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082)  *	This is anyones guess quite frankly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 		sector_t capacity, int geom[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 	int		heads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) 	int		sectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) 	sector_t	cylinders;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 	ulong 		dummy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 	heads = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 	sectors = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 	dummy = heads * sectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 	cylinders = capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 	sector_div(cylinders,dummy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 	 * Handle extended translation size for logical drives
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 	 * > 1Gb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 	if ((ulong)capacity >= 0x200000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 		heads = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 		sectors = 63;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 		dummy = heads * sectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) 		cylinders = capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 		sector_div(cylinders,dummy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) 	/* return result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) 	geom[0] = heads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 	geom[1] = sectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) 	geom[2] = cylinders;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) /* Search IOC page 3 to determine if this is hidden physical disk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 	struct inactive_raid_component_info *component_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) 	RaidPhysDiskPage1_t *phys_disk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) 	int num_paths;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 	if (!ioc->raid_data.pIocPg3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) 		if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 		    (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 			rc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 	if (ioc->bus_type != SAS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 	 * Check if dual path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 		num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) 		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 		if (num_paths < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 		phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 		   (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 		if (!phys_disk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 		if ((mpt_raid_phys_disk_pg1(ioc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) 		    phys_disk))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) 			kfree(phys_disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) 		for (j = 0; j < num_paths; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 			if ((phys_disk->Path[j].Flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) 			    MPI_RAID_PHYSDISK1_FLAG_INVALID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 			if ((phys_disk->Path[j].Flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 			    MPI_RAID_PHYSDISK1_FLAG_BROKEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) 			if ((id == phys_disk->Path[j].PhysDiskID) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) 			    (channel == phys_disk->Path[j].PhysDiskBus)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) 				rc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) 				kfree(phys_disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 		kfree(phys_disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) 	 * Check inactive list for matching phys disks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 	if (list_empty(&ioc->raid_data.inactive_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) 	mutex_lock(&ioc->raid_data.inactive_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) 	list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) 	    list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) 		if ((component_info->d.PhysDiskID == id) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 		    (component_info->d.PhysDiskBus == channel))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 			rc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 	mutex_unlock(&ioc->raid_data.inactive_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) EXPORT_SYMBOL(mptscsih_is_phys_disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) u8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 	struct inactive_raid_component_info *component_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 	RaidPhysDiskPage1_t *phys_disk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 	int rc = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) 	int num_paths;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 	if (!ioc->raid_data.pIocPg3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) 	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 		if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 		    (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) 			rc = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 	if (ioc->bus_type != SAS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) 	 * Check if dual path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) 	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) 		num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) 		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) 		if (num_paths < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 		phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) 		   (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 		if (!phys_disk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 		if ((mpt_raid_phys_disk_pg1(ioc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 		    ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 		    phys_disk))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 			kfree(phys_disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 		for (j = 0; j < num_paths; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 			if ((phys_disk->Path[j].Flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 			    MPI_RAID_PHYSDISK1_FLAG_INVALID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 			if ((phys_disk->Path[j].Flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 			    MPI_RAID_PHYSDISK1_FLAG_BROKEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 			if ((id == phys_disk->Path[j].PhysDiskID) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 			    (channel == phys_disk->Path[j].PhysDiskBus)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 				rc = phys_disk->PhysDiskNum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 				kfree(phys_disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 		kfree(phys_disk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 	 * Check inactive list for matching phys disks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 	if (list_empty(&ioc->raid_data.inactive_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 	mutex_lock(&ioc->raid_data.inactive_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 	list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 	    list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 		if ((component_info->d.PhysDiskID == id) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 		    (component_info->d.PhysDiskBus == channel))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) 			rc = component_info->d.PhysDiskNum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) 	mutex_unlock(&ioc->raid_data.inactive_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) EXPORT_SYMBOL(mptscsih_raid_id_to_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279)  *	OS entry point to allow for host driver to free allocated memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280)  *	Called if no device present or device being unloaded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) mptscsih_slave_destroy(struct scsi_device *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) 	struct Scsi_Host	*host = sdev->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 	MPT_SCSI_HOST		*hd = shost_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 	VirtTarget		*vtarget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) 	VirtDevice		*vdevice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 	struct scsi_target 	*starget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 	starget = scsi_target(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 	vtarget = starget->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) 	vdevice = sdev->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 	if (!vdevice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 	mptscsih_search_running_cmds(hd, vdevice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 	vtarget->num_luns--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 	mptscsih_synchronize_cache(hd, vdevice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) 	kfree(vdevice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 	sdev->hostdata = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306)  *	mptscsih_change_queue_depth - This function will set a devices queue depth
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307)  *	@sdev: per scsi_device pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308)  *	@qdepth: requested queue depth
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310)  *	Adding support for new 'change_queue_depth' api.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 	MPT_SCSI_HOST		*hd = shost_priv(sdev->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 	VirtTarget 		*vtarget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 	struct scsi_target 	*starget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 	int			max_depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 	MPT_ADAPTER		*ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 	starget = scsi_target(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 	vtarget = starget->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 	if (ioc->bus_type == SPI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 		if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) 			max_depth = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 		else if (sdev->type == TYPE_DISK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) 			 vtarget->minSyncFactor <= MPT_ULTRA160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 			max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) 			max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 		 max_depth = ioc->sh->can_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 	if (!sdev->tagged_supported)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) 		max_depth = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 	if (qdepth > max_depth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 		qdepth = max_depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 	return scsi_change_queue_depth(sdev, qdepth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345)  *	OS entry point to adjust the queue_depths on a per-device basis.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346)  *	Called once per device the bus scan. Use it to force the queue_depth
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347)  *	member to 1 if a device does not support Q tags.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348)  *	Return non-zero if fails.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) mptscsih_slave_configure(struct scsi_device *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 	struct Scsi_Host	*sh = sdev->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 	VirtTarget		*vtarget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) 	VirtDevice		*vdevice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 	struct scsi_target 	*starget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 	MPT_SCSI_HOST		*hd = shost_priv(sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 	MPT_ADAPTER		*ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 	starget = scsi_target(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 	vtarget = starget->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 	vdevice = sdev->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 		"device @ %p, channel=%d, id=%d, lun=%llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) 		ioc->name, sdev, sdev->channel, sdev->id, sdev->lun));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 	if (ioc->bus_type == SPI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 		dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 		    "sdtr %d wdtr %d ppr %d inq length=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 		    ioc->name, sdev->sdtr, sdev->wdtr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 		    sdev->ppr, sdev->inquiry_len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) 	vdevice->configured_lun = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 		"Queue depth=%d, tflags=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 		ioc->name, sdev->queue_depth, vtarget->tflags));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 	if (ioc->bus_type == SPI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 		dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 		    "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 		    ioc->name, vtarget->negoFlags, vtarget->maxOffset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 		    vtarget->minSyncFactor));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 	mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) 	dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 		"tagged %d, simple %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) 		ioc->name,sdev->tagged_supported, sdev->simple_tags));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) 	blk_queue_dma_alignment (sdev->request_queue, 512 - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397)  *  Private routines...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) /* Utility function to copy sense data from the scsi_cmnd buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402)  * to the FC and SCSI target structures.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 	VirtDevice	*vdevice;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 	SCSIIORequest_t	*pReq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 	u32		 sense_count = le32_to_cpu(pScsiReply->SenseCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 	MPT_ADAPTER 	*ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) 	/* Get target structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 	pReq = (SCSIIORequest_t *) mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 	vdevice = sc->device->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 	if (sense_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 		u8 *sense_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 		int req_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 		/* Copy the sense received into the scsi command block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 		req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 		sense_data = ((u8 *)ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 		memcpy(sc->sense_buffer, sense_data, MPT_SENSE_BUFFER_ALLOC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 		/* Log SMART data (asc = 0x5D, non-IM case only) if required.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) 		if ((ioc->events) && (ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 			if ((sense_data[12] == 0x5D) && (vdevice->vtarget->raidVolume == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) 				int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 				idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) 				ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 				ioc->events[idx].eventContext = ioc->eventContext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 				ioc->events[idx].data[0] = (pReq->LUN[1] << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 					(MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 					(sc->device->channel << 8) | sc->device->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 				ioc->events[idx].data[1] = (sense_data[13] << 8) | sense_data[12];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 				ioc->eventContext++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) 				if (ioc->pcidev->vendor ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) 				    PCI_VENDOR_ID_IBM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) 					mptscsih_issue_sep_command(ioc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) 					    vdevice->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) 					vdevice->vtarget->tflags |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) 					    MPT_TARGET_FLAGS_LED_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hmmm... SenseData len=0! (?)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 				ioc->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460)  * mptscsih_get_scsi_lookup - retrieves scmd entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461)  * @ioc: Pointer to MPT_ADAPTER structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462)  * @i: index into the array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464)  * Returns the scsi_cmd pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) struct scsi_cmnd *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) 	unsigned long	flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) 	struct scsi_cmnd *scmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) 	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) 	scmd = ioc->ScsiLookup[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 	return scmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) EXPORT_SYMBOL(mptscsih_get_scsi_lookup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481)  * mptscsih_getclear_scsi_lookup -  retrieves and clears scmd entry from ScsiLookup[] array list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482)  * @ioc: Pointer to MPT_ADAPTER structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483)  * @i: index into the array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485)  * Returns the scsi_cmd pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487)  **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) static struct scsi_cmnd *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) 	unsigned long	flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) 	struct scsi_cmnd *scmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) 	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 	scmd = ioc->ScsiLookup[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 	ioc->ScsiLookup[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) 	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) 	return scmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503)  * mptscsih_set_scsi_lookup - write a scmd entry into the ScsiLookup[] array list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505)  * @ioc: Pointer to MPT_ADAPTER structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506)  * @i: index into the array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507)  * @scmd: scsi_cmnd pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509)  **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) mptscsih_set_scsi_lookup(MPT_ADAPTER *ioc, int i, struct scsi_cmnd *scmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 	unsigned long	flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) 	ioc->ScsiLookup[i] = scmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521)  * SCPNT_TO_LOOKUP_IDX - searches for a given scmd in the ScsiLookup[] array list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522)  * @ioc: Pointer to MPT_ADAPTER structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523)  * @sc: scsi_cmnd pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 	unsigned long	flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 	int i, index=-1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 	spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 	for (i = 0; i < ioc->req_depth; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 		if (ioc->ScsiLookup[i] == sc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) 			index = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 	spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 	return index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 	MPT_SCSI_HOST	*hd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 	if (ioc->sh == NULL || shost_priv(ioc->sh) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 	hd = shost_priv(ioc->sh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) 	switch (reset_phase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) 	case MPT_IOC_SETUP_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 		    "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 	case MPT_IOC_PRE_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) 		    "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) 		mptscsih_flush_running_cmds(hd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 	case MPT_IOC_POST_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 		    "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 		if (ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) 			ioc->internal_cmds.status |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) 				MPT_MGMT_STATUS_DID_IOCRESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) 			complete(&ioc->internal_cmds.done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) 	return 1;		/* currently means nothing really */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) 	u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) 	devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) 		"MPT event (=%02Xh) routed to SCSI host driver!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) 		ioc->name, event));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) 	if ((event == MPI_EVENT_IOC_BUS_RESET ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) 	    event == MPI_EVENT_EXT_BUS_RESET) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) 	    (ioc->bus_type == SPI) && (ioc->soft_resets < -1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) 			ioc->soft_resets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) 	return 1;		/* currently means nothing really */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599)  *  Bus Scan and Domain Validation functionality ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604)  *	mptscsih_scandv_complete - Scan and DV callback routine registered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605)  *	to Fustion MPT (base) driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607)  *	@ioc: Pointer to MPT_ADAPTER structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608)  *	@mf: Pointer to original MPT request frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609)  *	@mr: Pointer to MPT reply frame (NULL if TurboReply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611)  *	This routine is called from mpt.c::mpt_interrupt() at the completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612)  *	of any SCSI IO request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613)  *	This routine is registered with the Fusion MPT (base) driver at driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614)  *	load/init time via the mpt_register() API call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616)  *	Returns 1 indicating alloc'd request frame ptr should be freed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618)  *	Remark: Sets a completion code and (possibly) saves sense data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619)  *	in the IOC member localReply structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620)  *	Used ONLY for DV and other internal commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) 				MPT_FRAME_HDR *reply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) 	SCSIIORequest_t *pReq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) 	SCSIIOReply_t	*pReply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) 	u8		 cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) 	u16		 req_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) 	u8	*sense_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) 	int		 sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) 	ioc->internal_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) 	ioc->internal_cmds.completion_code = MPT_SCANDV_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 	if (!reply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) 	pReply = (SCSIIOReply_t *) reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) 	pReq = (SCSIIORequest_t *) req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) 	ioc->internal_cmds.completion_code =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) 	    mptscsih_get_completion_code(ioc, req, reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) 	ioc->internal_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) 	memcpy(ioc->internal_cmds.reply, reply,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) 	    min(MPT_DEFAULT_FRAME_SIZE, 4 * reply->u.reply.MsgLength));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) 	cmd = reply->u.hdr.Function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) 	if (((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) 	    (cmd == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) 	    (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) 		req_idx = le16_to_cpu(req->u.frame.hwhdr.msgctxu.fld.req_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) 		sense_data = ((u8 *)ioc->sense_buf_pool +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) 		    (req_idx * MPT_SENSE_BUFFER_ALLOC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) 		sz = min_t(int, pReq->SenseBufferLength,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) 		    MPT_SENSE_BUFFER_ALLOC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) 		memcpy(ioc->internal_cmds.sense, sense_data, sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) 	if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) 	ioc->internal_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) 	complete(&ioc->internal_cmds.done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666)  *	mptscsih_get_completion_code - get completion code from MPT request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667)  *	@ioc: Pointer to MPT_ADAPTER structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668)  *	@req: Pointer to original MPT request frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669)  *	@reply: Pointer to MPT reply frame (NULL if TurboReply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671)  **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) mptscsih_get_completion_code(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 				MPT_FRAME_HDR *reply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 	SCSIIOReply_t	*pReply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 	MpiRaidActionReply_t *pr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 	u8		 scsi_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 	u16		 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) 	int		 completion_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) 	pReply = (SCSIIOReply_t *)reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) 	status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) 	scsi_status = pReply->SCSIStatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) 	    "IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) 	    "IOCLogInfo=%08xh\n", ioc->name, status, pReply->SCSIState,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) 	    scsi_status, le32_to_cpu(pReply->IOCLogInfo)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) 	switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) 	case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:	/* 0x0043 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) 		completion_code = MPT_SCANDV_SELECTION_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) 	case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:		/* 0x0046 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) 	case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:	/* 0x0048 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) 	case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:		/* 0x004B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) 	case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:		/* 0x004C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) 		completion_code = MPT_SCANDV_DID_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) 	case MPI_IOCSTATUS_BUSY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) 	case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) 		completion_code = MPT_SCANDV_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) 	case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:		/* 0x0045 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) 	case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:	/* 0x0040 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) 	case MPI_IOCSTATUS_SUCCESS:			/* 0x0000 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) 		if (pReply->Function == MPI_FUNCTION_CONFIG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) 			completion_code = MPT_SCANDV_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) 		} else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) 			pr = (MpiRaidActionReply_t *)reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) 			if (le16_to_cpu(pr->ActionStatus) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) 				MPI_RAID_ACTION_ASTATUS_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) 				completion_code = MPT_SCANDV_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) 				completion_code = MPT_SCANDV_SOME_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) 		} else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) 			completion_code = MPT_SCANDV_SENSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) 		else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) 			if (req->u.scsireq.CDB[0] == INQUIRY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) 				completion_code = MPT_SCANDV_ISSUE_SENSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) 				completion_code = MPT_SCANDV_DID_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) 		} else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) 			completion_code = MPT_SCANDV_DID_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) 		else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) 			completion_code = MPT_SCANDV_DID_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) 		else if (scsi_status == MPI_SCSI_STATUS_BUSY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) 			completion_code = MPT_SCANDV_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) 			completion_code = MPT_SCANDV_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) 	case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:		/* 0x0047 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) 		if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) 			completion_code = MPT_SCANDV_DID_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) 			completion_code = MPT_SCANDV_SOME_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) 		completion_code = MPT_SCANDV_SOME_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) 	}	/* switch(status) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) 	    "  completionCode set to %08xh\n", ioc->name, completion_code));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) 	return completion_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757)  *	mptscsih_do_cmd - Do internal command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758)  *	@hd: MPT_SCSI_HOST pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759)  *	@io: INTERNAL_CMD pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761)  *	Issue the specified internally generated command and do command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762)  *	specific cleanup. For bus scan / DV only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763)  *	NOTES: If command is Inquiry and status is good,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764)  *	initialize a target structure, save the data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766)  *	Remark: Single threaded access only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768)  *	Return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769)  *		< 0 if an illegal command or no resources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771)  *		   0 if good
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773)  *		 > 0 if command complete but some type of completion error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) 	MPT_FRAME_HDR	*mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) 	SCSIIORequest_t	*pScsiReq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) 	int		 my_idx, ii, dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) 	int		 timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 	char		 cmdLen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 	char		 CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 	u8		 cmd = io->cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) 	MPT_ADAPTER *ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) 	int		 ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 	unsigned long	 timeleft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) 	unsigned long	 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) 	/* don't send internal command during diag reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) 	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) 	if (ioc->ioc_reset_in_progress) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) 		spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) 		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) 			"%s: busy with host reset\n", ioc->name, __func__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) 		return MPT_SCANDV_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) 	spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) 	mutex_lock(&ioc->internal_cmds.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) 	/* Set command specific information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) 	case INQUIRY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) 		cmdLen = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) 		dir = MPI_SCSIIO_CONTROL_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) 		CDB[0] = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) 		CDB[4] = io->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) 		timeout = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) 	case TEST_UNIT_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) 		cmdLen = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) 		dir = MPI_SCSIIO_CONTROL_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) 		timeout = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) 	case START_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) 		cmdLen = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) 		dir = MPI_SCSIIO_CONTROL_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) 		CDB[0] = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) 		CDB[4] = 1;	/*Spin up the disk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 		timeout = 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) 	case REQUEST_SENSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) 		cmdLen = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) 		CDB[0] = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) 		CDB[4] = io->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) 		dir = MPI_SCSIIO_CONTROL_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) 		timeout = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) 	case READ_BUFFER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) 		cmdLen = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) 		dir = MPI_SCSIIO_CONTROL_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) 		CDB[0] = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) 		if (io->flags & MPT_ICFLAG_ECHO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) 			CDB[1] = 0x0A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) 			CDB[1] = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) 		if (io->flags & MPT_ICFLAG_BUF_CAP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) 			CDB[1] |= 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 		CDB[6] = (io->size >> 16) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) 		CDB[7] = (io->size >>  8) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) 		CDB[8] = io->size & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) 		timeout = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) 	case WRITE_BUFFER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) 		cmdLen = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) 		dir = MPI_SCSIIO_CONTROL_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) 		CDB[0] = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) 		if (io->flags & MPT_ICFLAG_ECHO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) 			CDB[1] = 0x0A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) 			CDB[1] = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) 		CDB[6] = (io->size >> 16) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) 		CDB[7] = (io->size >>  8) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) 		CDB[8] = io->size & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) 		timeout = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) 	case RESERVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) 		cmdLen = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) 		dir = MPI_SCSIIO_CONTROL_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) 		CDB[0] = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) 		timeout = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) 	case RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) 		cmdLen = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) 		dir = MPI_SCSIIO_CONTROL_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) 		CDB[0] = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) 		timeout = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) 	case SYNCHRONIZE_CACHE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 		cmdLen = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) 		dir = MPI_SCSIIO_CONTROL_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) 		CDB[0] = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) //		CDB[1] = 0x02;	/* set immediate bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 		timeout = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) 		/* Error Case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) 		ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) 	/* Get and Populate a free Frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 	 * MsgContext set in mpt_get_msg_frame call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 	if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 		dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: No msg frames!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) 		    ioc->name, __func__));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 		ret = MPT_SCANDV_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 	pScsiReq = (SCSIIORequest_t *) mf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) 	/* Get the request index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) 	my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) 	ADD_INDEX_LOG(my_idx); /* for debug */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) 	if (io->flags & MPT_ICFLAG_PHYS_DISK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) 		pScsiReq->TargetID = io->physDiskNum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) 		pScsiReq->Bus = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) 		pScsiReq->ChainOffset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) 		pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) 		pScsiReq->TargetID = io->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) 		pScsiReq->Bus = io->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) 		pScsiReq->ChainOffset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) 		pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) 	pScsiReq->CDBLength = cmdLen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) 	pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) 	pScsiReq->Reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) 	pScsiReq->MsgFlags = mpt_msg_flags(ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) 	/* MsgContext set in mpt_get_msg_fram call  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) 	int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) 	if (io->flags & MPT_ICFLAG_TAGGED_CMD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) 		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) 		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) 	if (cmd == REQUEST_SENSE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) 		pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) 		devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) 		    "%s: Untagged! 0x%02x\n", ioc->name, __func__, cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) 	for (ii = 0; ii < 16; ii++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) 		pScsiReq->CDB[ii] = CDB[ii];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) 	pScsiReq->DataLength = cpu_to_le32(io->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) 	pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) 					   + (my_idx * MPT_SENSE_BUFFER_ALLOC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) 	    "%s: Sending Command 0x%02x for fw_channel=%d fw_id=%d lun=%llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) 	    ioc->name, __func__, cmd, io->channel, io->id, io->lun));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) 	if (dir == MPI_SCSIIO_CONTROL_READ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) 		ioc->add_sge((char *) &pScsiReq->SGL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) 		    MPT_SGE_FLAGS_SSIMPLE_READ | io->size, io->data_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) 		ioc->add_sge((char *) &pScsiReq->SGL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) 		    MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size, io->data_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) 	INITIALIZE_MGMT_STATUS(ioc->internal_cmds.status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) 	mpt_put_msg_frame(ioc->InternalCtx, ioc, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) 	timeleft = wait_for_completion_timeout(&ioc->internal_cmds.done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) 	    timeout*HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) 	if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) 		ret = MPT_SCANDV_DID_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) 		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) 		    "%s: TIMED OUT for cmd=0x%02x\n", ioc->name, __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) 		    cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) 		if (ioc->internal_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) 			mpt_free_msg_frame(ioc, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) 		if (!timeleft) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) 			printk(MYIOC_s_WARN_FMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) 			       "Issuing Reset from %s!! doorbell=0x%08xh"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) 			       " cmd=0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) 			       ioc->name, __func__, mpt_GetIocState(ioc, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) 			       cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) 			mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) 			mpt_free_msg_frame(ioc, mf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) 	ret = ioc->internal_cmds.completion_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) 	devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: success, rc=0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) 			ioc->name, __func__, ret));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) 	CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) 	mutex_unlock(&ioc->internal_cmds.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001)  *	mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002)  *	@hd: Pointer to a SCSI HOST structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003)  *	@vdevice: virtual target device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005)  *	Uses the ISR, but with special processing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006)  *	MUST be single-threaded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) 	INTERNAL_CMD		 iocmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) 	/* Ignore hidden raid components, this is handled when the command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) 	 * is sent to the volume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) 	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) 	if (vdevice->vtarget->type != TYPE_DISK || vdevice->vtarget->deleted ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) 	    !vdevice->configured_lun)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) 	/* Following parameters will not change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) 	 * in this routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) 	iocmd.cmd = SYNCHRONIZE_CACHE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) 	iocmd.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) 	iocmd.physDiskNum = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) 	iocmd.data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) 	iocmd.data_dma = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) 	iocmd.size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) 	iocmd.rsvd = iocmd.rsvd2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) 	iocmd.channel = vdevice->vtarget->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) 	iocmd.id = vdevice->vtarget->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) 	iocmd.lun = vdevice->lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) 	mptscsih_do_cmd(hd, &iocmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) mptscsih_version_fw_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) 			 char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) 	struct Scsi_Host *host = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) 	MPT_SCSI_HOST	*hd = shost_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) 	MPT_ADAPTER *ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) 	return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) 	    (ioc->facts.FWVersion.Word & 0xFF000000) >> 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) 	    (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) 	    (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) 	    ioc->facts.FWVersion.Word & 0x000000FF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) static DEVICE_ATTR(version_fw, S_IRUGO, mptscsih_version_fw_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) mptscsih_version_bios_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) 			   char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) 	struct Scsi_Host *host = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) 	MPT_SCSI_HOST	*hd = shost_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) 	MPT_ADAPTER *ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) 	return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) 	    (ioc->biosVersion & 0xFF000000) >> 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) 	    (ioc->biosVersion & 0x00FF0000) >> 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) 	    (ioc->biosVersion & 0x0000FF00) >> 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) 	    ioc->biosVersion & 0x000000FF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) static DEVICE_ATTR(version_bios, S_IRUGO, mptscsih_version_bios_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) mptscsih_version_mpi_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) 			  char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) 	struct Scsi_Host *host = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) 	MPT_SCSI_HOST	*hd = shost_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) 	MPT_ADAPTER *ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) 	return snprintf(buf, PAGE_SIZE, "%03x\n", ioc->facts.MsgVersion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) static DEVICE_ATTR(version_mpi, S_IRUGO, mptscsih_version_mpi_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) mptscsih_version_product_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) 			      struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) 	struct Scsi_Host *host = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) 	MPT_SCSI_HOST	*hd = shost_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) 	MPT_ADAPTER *ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) 	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->prod_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) static DEVICE_ATTR(version_product, S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097)     mptscsih_version_product_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) mptscsih_version_nvdata_persistent_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) 					struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) 					char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) 	struct Scsi_Host *host = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) 	MPT_SCSI_HOST	*hd = shost_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) 	MPT_ADAPTER *ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) 	return snprintf(buf, PAGE_SIZE, "%02xh\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) 	    ioc->nvdata_version_persistent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) static DEVICE_ATTR(version_nvdata_persistent, S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112)     mptscsih_version_nvdata_persistent_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) mptscsih_version_nvdata_default_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) 				     struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) 	struct Scsi_Host *host = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) 	MPT_SCSI_HOST	*hd = shost_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) 	MPT_ADAPTER *ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) 	return snprintf(buf, PAGE_SIZE, "%02xh\n",ioc->nvdata_version_default);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) static DEVICE_ATTR(version_nvdata_default, S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125)     mptscsih_version_nvdata_default_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) mptscsih_board_name_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) 			 char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) 	struct Scsi_Host *host = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) 	MPT_SCSI_HOST	*hd = shost_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) 	MPT_ADAPTER *ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) 	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) static DEVICE_ATTR(board_name, S_IRUGO, mptscsih_board_name_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) mptscsih_board_assembly_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) 			     struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) 	struct Scsi_Host *host = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) 	MPT_SCSI_HOST	*hd = shost_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) 	MPT_ADAPTER *ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) 	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_assembly);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) static DEVICE_ATTR(board_assembly, S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150)     mptscsih_board_assembly_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) mptscsih_board_tracer_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) 			   char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) 	struct Scsi_Host *host = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) 	MPT_SCSI_HOST	*hd = shost_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) 	MPT_ADAPTER *ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) 	return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_tracer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) static DEVICE_ATTR(board_tracer, S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163)     mptscsih_board_tracer_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) mptscsih_io_delay_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) 		       char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) 	struct Scsi_Host *host = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) 	MPT_SCSI_HOST	*hd = shost_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) 	MPT_ADAPTER *ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) 	return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->io_missing_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) static DEVICE_ATTR(io_delay, S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176)     mptscsih_io_delay_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) mptscsih_device_delay_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) 			   char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) 	struct Scsi_Host *host = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) 	MPT_SCSI_HOST	*hd = shost_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) 	MPT_ADAPTER *ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) 	return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->device_missing_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) static DEVICE_ATTR(device_delay, S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189)     mptscsih_device_delay_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) mptscsih_debug_level_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) 			  char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) 	struct Scsi_Host *host = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) 	MPT_SCSI_HOST	*hd = shost_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) 	MPT_ADAPTER *ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) 	return snprintf(buf, PAGE_SIZE, "%08xh\n", ioc->debug_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) mptscsih_debug_level_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) 			   const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) 	struct Scsi_Host *host = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) 	MPT_SCSI_HOST	*hd = shost_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) 	MPT_ADAPTER *ioc = hd->ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) 	int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) 	if (sscanf(buf, "%x", &val) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) 	ioc->debug_level = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) 	printk(MYIOC_s_INFO_FMT "debug_level=%08xh\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) 				ioc->name, ioc->debug_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) 	return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) static DEVICE_ATTR(debug_level, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) 	mptscsih_debug_level_show, mptscsih_debug_level_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) struct device_attribute *mptscsih_host_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) 	&dev_attr_version_fw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) 	&dev_attr_version_bios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) 	&dev_attr_version_mpi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) 	&dev_attr_version_product,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) 	&dev_attr_version_nvdata_persistent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) 	&dev_attr_version_nvdata_default,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) 	&dev_attr_board_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) 	&dev_attr_board_assembly,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) 	&dev_attr_board_tracer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) 	&dev_attr_io_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) 	&dev_attr_device_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) 	&dev_attr_debug_level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) 	NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) EXPORT_SYMBOL(mptscsih_host_attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) EXPORT_SYMBOL(mptscsih_remove);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) EXPORT_SYMBOL(mptscsih_shutdown);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) EXPORT_SYMBOL(mptscsih_suspend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) EXPORT_SYMBOL(mptscsih_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) EXPORT_SYMBOL(mptscsih_show_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) EXPORT_SYMBOL(mptscsih_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) EXPORT_SYMBOL(mptscsih_qcmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) EXPORT_SYMBOL(mptscsih_slave_destroy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) EXPORT_SYMBOL(mptscsih_slave_configure);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) EXPORT_SYMBOL(mptscsih_abort);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) EXPORT_SYMBOL(mptscsih_dev_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) EXPORT_SYMBOL(mptscsih_bus_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) EXPORT_SYMBOL(mptscsih_host_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) EXPORT_SYMBOL(mptscsih_bios_param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) EXPORT_SYMBOL(mptscsih_io_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) EXPORT_SYMBOL(mptscsih_scandv_complete);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) EXPORT_SYMBOL(mptscsih_event_process);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) EXPORT_SYMBOL(mptscsih_ioc_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) EXPORT_SYMBOL(mptscsih_change_queue_depth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/