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