^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) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/