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#define SNS_LEN(scp)    SCSI_SENSE_BUFFERSIZE
 122
 123
 124/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 125/*
 126 *      mptscsih_getFreeChainBuffer - Function to get a free chain
 127 *      from the MPT_SCSI_HOST FreeChainQ.
 128 *      @ioc: Pointer to MPT_ADAPTER structure
 129 *      @req_idx: Index of the SCSI IO request frame. (output)
 130 *
 131 *      return SUCCESS or FAILED
 132 */
 133static inline int
 134mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
 135{
 136        MPT_FRAME_HDR *chainBuf;
 137        unsigned long flags;
 138        int rc;
 139        int chain_idx;
 140
 141        dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "getFreeChainBuffer called\n",
 142            ioc->name));
 143        spin_lock_irqsave(&ioc->FreeQlock, flags);
 144        if (!list_empty(&ioc->FreeChainQ)) {
 145                int offset;
 146
 147                chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR,
 148                                u.frame.linkage.list);
 149                list_del(&chainBuf->u.frame.linkage.list);
 150                offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
 151                chain_idx = offset / ioc->req_sz;
 152                rc = SUCCESS;
 153                dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 154                    "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
 155                    ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx));
 156        } else {
 157                rc = FAILED;
 158                chain_idx = MPT_HOST_NO_CHAIN;
 159                dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "getFreeChainBuffer failed\n",
 160                    ioc->name));
 161        }
 162        spin_unlock_irqrestore(&ioc->FreeQlock, flags);
 163
 164        *retIndex = chain_idx;
 165        return rc;
 166} /* mptscsih_getFreeChainBuffer() */
 167
 168/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 169/*
 170 *      mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
 171 *      SCSIIORequest_t Message Frame.
 172 *      @ioc: Pointer to MPT_ADAPTER structure
 173 *      @SCpnt: Pointer to scsi_cmnd structure
 174 *      @pReq: Pointer to SCSIIORequest_t structure
 175 *
 176 *      Returns ...
 177 */
 178static int
 179mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
 180                SCSIIORequest_t *pReq, int req_idx)
 181{
 182        char    *psge;
 183        char    *chainSge;
 184        struct scatterlist *sg;
 185        int      frm_sz;
 186        int      sges_left, sg_done;
 187        int      chain_idx = MPT_HOST_NO_CHAIN;
 188        int      sgeOffset;
 189        int      numSgeSlots, numSgeThisFrame;
 190        u32      sgflags, sgdir, thisxfer = 0;
 191        int      chain_dma_off = 0;
 192        int      newIndex;
 193        int      ii;
 194        dma_addr_t v2;
 195        u32     RequestNB;
 196
 197        sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
 198        if (sgdir == MPI_SCSIIO_CONTROL_WRITE)  {
 199                sgdir = MPT_TRANSFER_HOST_TO_IOC;
 200        } else {
 201                sgdir = MPT_TRANSFER_IOC_TO_HOST;
 202        }
 203
 204        psge = (char *) &pReq->SGL;
 205        frm_sz = ioc->req_sz;
 206
 207        /* Map the data portion, if any.
 208         * sges_left  = 0 if no data transfer.
 209         */
 210        sges_left = scsi_dma_map(SCpnt);
 211        if (sges_left < 0)
 212                return FAILED;
 213
 214        /* Handle the SG case.
 215         */
 216        sg = scsi_sglist(SCpnt);
 217        sg_done  = 0;
 218        sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
 219        chainSge = NULL;
 220
 221        /* Prior to entering this loop - the following must be set
 222         * current MF:  sgeOffset (bytes)
 223         *              chainSge (Null if original MF is not a chain buffer)
 224         *              sg_done (num SGE done for this MF)
 225         */
 226
 227nextSGEset:
 228        numSgeSlots = ((frm_sz - sgeOffset) / ioc->SGE_size);
 229        numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
 230
 231        sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | sgdir;
 232
 233        /* Get first (num - 1) SG elements
 234         * Skip any SG entries with a length of 0
 235         * NOTE: at finish, sg and psge pointed to NEXT data/location positions
 236         */
 237        for (ii=0; ii < (numSgeThisFrame-1); ii++) {
 238                thisxfer = sg_dma_len(sg);
 239                if (thisxfer == 0) {
 240                        /* Get next SG element from the OS */
 241                        sg = sg_next(sg);
 242                        sg_done++;
 243                        continue;
 244                }
 245
 246                v2 = sg_dma_address(sg);
 247                ioc->add_sge(psge, sgflags | thisxfer, v2);
 248
 249                /* Get next SG element from the OS */
 250                sg = sg_next(sg);
 251                psge += ioc->SGE_size;
 252                sgeOffset += ioc->SGE_size;
 253                sg_done++;
 254        }
 255
 256        if (numSgeThisFrame == sges_left) {
 257                /* Add last element, end of buffer and end of list flags.
 258                 */
 259                sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
 260                                MPT_SGE_FLAGS_END_OF_BUFFER |
 261                                MPT_SGE_FLAGS_END_OF_LIST;
 262
 263                /* Add last SGE and set termination flags.
 264                 * Note: Last SGE may have a length of 0 - which should be ok.
 265                 */
 266                thisxfer = sg_dma_len(sg);
 267
 268                v2 = sg_dma_address(sg);
 269                ioc->add_sge(psge, sgflags | thisxfer, v2);
 270                sgeOffset += ioc->SGE_size;
 271                sg_done++;
 272
 273                if (chainSge) {
 274                        /* The current buffer is a chain buffer,
 275                         * but there is not another one.
 276                         * Update the chain element
 277                         * Offset and Length fields.
 278                         */
 279                        ioc->add_chain((char *)chainSge, 0, sgeOffset,
 280                                ioc->ChainBufferDMA + chain_dma_off);
 281                } else {
 282                        /* The current buffer is the original MF
 283                         * and there is no Chain buffer.
 284                         */
 285                        pReq->ChainOffset = 0;
 286                        RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor)  + 1) & 0x03;
 287                        dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 288                            "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
 289                        ioc->RequestNB[req_idx] = RequestNB;
 290                }
 291        } else {
 292                /* At least one chain buffer is needed.
 293                 * Complete the first MF
 294                 *  - last SGE element, set the LastElement bit
 295                 *  - set ChainOffset (words) for orig MF
 296                 *             (OR finish previous MF chain buffer)
 297                 *  - update MFStructPtr ChainIndex
 298                 *  - Populate chain element
 299                 * Also
 300                 * Loop until done.
 301                 */
 302
 303                dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SG: Chain Required! sg done %d\n",
 304                                ioc->name, sg_done));
 305
 306                /* Set LAST_ELEMENT flag for last non-chain element
 307                 * in the buffer. Since psge points at the NEXT
 308                 * SGE element, go back one SGE element, update the flags
 309                 * and reset the pointer. (Note: sgflags & thisxfer are already
 310                 * set properly).
 311                 */
 312                if (sg_done) {
 313                        u32 *ptmp = (u32 *) (psge - ioc->SGE_size);
 314                        sgflags = le32_to_cpu(*ptmp);
 315                        sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
 316                        *ptmp = cpu_to_le32(sgflags);
 317                }
 318
 319                if (chainSge) {
 320                        /* The current buffer is a chain buffer.
 321                         * chainSge points to the previous Chain Element.
 322                         * Update its chain element Offset and Length (must
 323                         * include chain element size) fields.
 324                         * Old chain element is now complete.
 325                         */
 326                        u8 nextChain = (u8) (sgeOffset >> 2);
 327                        sgeOffset += ioc->SGE_size;
 328                        ioc->add_chain((char *)chainSge, nextChain, sgeOffset,
 329                                         ioc->ChainBufferDMA + chain_dma_off);
 330                } else {
 331                        /* The original MF buffer requires a chain buffer -
 332                         * set the offset.
 333                         * Last element in this MF is a chain element.
 334                         */
 335                        pReq->ChainOffset = (u8) (sgeOffset >> 2);
 336                        RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor)  + 1) & 0x03;
 337                        dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
 338                        ioc->RequestNB[req_idx] = RequestNB;
 339                }
 340
 341                sges_left -= sg_done;
 342
 343
 344                /* NOTE: psge points to the beginning of the chain element
 345                 * in current buffer. Get a chain buffer.
 346                 */
 347                if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) {
 348                        dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 349                            "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
 350                            ioc->name, pReq->CDB[0], SCpnt));
 351                        return FAILED;
 352                }
 353
 354                /* Update the tracking arrays.
 355                 * If chainSge == NULL, update ReqToChain, else ChainToChain
 356                 */
 357                if (chainSge) {
 358                        ioc->ChainToChain[chain_idx] = newIndex;
 359                } else {
 360                        ioc->ReqToChain[req_idx] = newIndex;
 361                }
 362                chain_idx = newIndex;
 363                chain_dma_off = ioc->req_sz * chain_idx;
 364
 365                /* Populate the chainSGE for the current buffer.
 366                 * - Set chain buffer pointer to psge and fill
 367                 *   out the Address and Flags fields.
 368                 */
 369                chainSge = (char *) psge;
 370                dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "  Current buff @ %p (index 0x%x)",
 371                    ioc->name, psge, req_idx));
 372
 373                /* Start the SGE for the next buffer
 374                 */
 375                psge = (char *) (ioc->ChainBuffer + chain_dma_off);
 376                sgeOffset = 0;
 377                sg_done = 0;
 378
 379                dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "  Chain buff @ %p (index 0x%x)\n",
 380                    ioc->name, psge, chain_idx));
 381
 382                /* Start the SGE for the next buffer
 383                 */
 384
 385                goto nextSGEset;
 386        }
 387
 388        return SUCCESS;
 389} /* mptscsih_AddSGE() */
 390
 391static void
 392mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget,
 393    U32 SlotStatus)
 394{
 395        MPT_FRAME_HDR *mf;
 396        SEPRequest_t     *SEPMsg;
 397
 398        if (ioc->bus_type != SAS)
 399                return;
 400
 401        /* Not supported for hidden raid components
 402         */
 403        if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
 404                return;
 405
 406        if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
 407                dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: no msg frames!!\n",
 408                    ioc->name,__func__));
 409                return;
 410        }
 411
 412        SEPMsg = (SEPRequest_t *)mf;
 413        SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
 414        SEPMsg->Bus = vtarget->channel;
 415        SEPMsg->TargetID = vtarget->id;
 416        SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS;
 417        SEPMsg->SlotStatus = SlotStatus;
 418        devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 419            "Sending SEP cmd=%x channel=%d id=%d\n",
 420            ioc->name, SlotStatus, SEPMsg->Bus, SEPMsg->TargetID));
 421        mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
 422}
 423
 424#ifdef CONFIG_FUSION_LOGGING
 425/**
 426 *      mptscsih_info_scsiio - debug print info on reply frame
 427 *      @ioc: Pointer to MPT_ADAPTER structure
 428 *      @sc: original scsi cmnd pointer
 429 *      @pScsiReply: Pointer to MPT reply frame
 430 *
 431 *      MPT_DEBUG_REPLY needs to be enabled to obtain this info
 432 *
 433 *      Refer to lsi/mpi.h.
 434 **/
 435static void
 436mptscsih_info_scsiio(MPT_ADAPTER *ioc, struct scsi_cmnd *sc, SCSIIOReply_t * pScsiReply)
 437{
 438        char    *desc = NULL;
 439        char    *desc1 = NULL;
 440        u16     ioc_status;
 441        u8      skey, asc, ascq;
 442
 443        ioc_status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
 444
 445        switch (ioc_status) {
 446
 447        case MPI_IOCSTATUS_SUCCESS:
 448                desc = "success";
 449                break;
 450        case MPI_IOCSTATUS_SCSI_INVALID_BUS:
 451                desc = "invalid bus";
 452                break;
 453        case MPI_IOCSTATUS_SCSI_INVALID_TARGETID:
 454                desc = "invalid target_id";
 455                break;
 456        case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
 457                desc = "device not there";
 458                break;
 459        case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:
 460                desc = "data overrun";
 461                break;
 462        case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:
 463                desc = "data underrun";
 464                break;
 465        case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:
 466                desc = "I/O data error";
 467                break;
 468        case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:
 469                desc = "protocol error";
 470                break;
 471        case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:
 472                desc = "task terminated";
 473                break;
 474        case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
 475                desc = "residual mismatch";
 476                break;
 477        case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED:
 478                desc = "task management failed";
 479                break;
 480        case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:
 481                desc = "IOC terminated";
 482                break;
 483        case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:
 484                desc = "ext terminated";
 485                break;
 486        default:
 487                desc = "";
 488                break;
 489        }
 490
 491        switch (pScsiReply->SCSIStatus)
 492        {
 493
 494        case MPI_SCSI_STATUS_SUCCESS:
 495                desc1 = "success";
 496                break;
 497        case MPI_SCSI_STATUS_CHECK_CONDITION:
 498                desc1 = "check condition";
 499                break;
 500        case MPI_SCSI_STATUS_CONDITION_MET:
 501                desc1 = "condition met";
 502                break;
 503        case MPI_SCSI_STATUS_BUSY:
 504                desc1 = "busy";
 505                break;
 506        case MPI_SCSI_STATUS_INTERMEDIATE:
 507                desc1 = "intermediate";
 508                break;
 509        case MPI_SCSI_STATUS_INTERMEDIATE_CONDMET:
 510                desc1 = "intermediate condmet";
 511                break;
 512        case MPI_SCSI_STATUS_RESERVATION_CONFLICT:
 513                desc1 = "reservation conflict";
 514                break;
 515        case MPI_SCSI_STATUS_COMMAND_TERMINATED:
 516                desc1 = "command terminated";
 517                break;
 518        case MPI_SCSI_STATUS_TASK_SET_FULL:
 519                desc1 = "task set full";
 520                break;
 521        case MPI_SCSI_STATUS_ACA_ACTIVE:
 522                desc1 = "aca active";
 523                break;
 524        case MPI_SCSI_STATUS_FCPEXT_DEVICE_LOGGED_OUT:
 525                desc1 = "fcpext device logged out";
 526                break;
 527        case MPI_SCSI_STATUS_FCPEXT_NO_LINK:
 528                desc1 = "fcpext no link";
 529                break;
 530        case MPI_SCSI_STATUS_FCPEXT_UNASSIGNED:
 531                desc1 = "fcpext unassigned";
 532                break;
 533        default:
 534                desc1 = "";
 535                break;
 536        }
 537
 538        scsi_print_command(sc);
 539        printk(MYIOC_s_DEBUG_FMT "\tfw_channel = %d, fw_id = %d, lun = %llu\n",
 540            ioc->name, pScsiReply->Bus, pScsiReply->TargetID, sc->device->lun);
 541        printk(MYIOC_s_DEBUG_FMT "\trequest_len = %d, underflow = %d, "
 542            "resid = %d\n", ioc->name, scsi_bufflen(sc), sc->underflow,
 543            scsi_get_resid(sc));
 544        printk(MYIOC_s_DEBUG_FMT "\ttag = %d, transfer_count = %d, "
 545            "sc->result = %08X\n", ioc->name, le16_to_cpu(pScsiReply->TaskTag),
 546            le32_to_cpu(pScsiReply->TransferCount), sc->result);
 547
 548        printk(MYIOC_s_DEBUG_FMT "\tiocstatus = %s (0x%04x), "
 549            "scsi_status = %s (0x%02x), scsi_state = (0x%02x)\n",
 550            ioc->name, desc, ioc_status, desc1, pScsiReply->SCSIStatus,
 551            pScsiReply->SCSIState);
 552
 553        if (pScsiReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
 554                skey = sc->sense_buffer[2] & 0x0F;
 555                asc = sc->sense_buffer[12];
 556                ascq = sc->sense_buffer[13];
 557
 558                printk(MYIOC_s_DEBUG_FMT "\t[sense_key,asc,ascq]: "
 559                    "[0x%02x,0x%02x,0x%02x]\n", ioc->name, skey, asc, ascq);
 560        }
 561
 562        /*
 563         *  Look for + dump FCP ResponseInfo[]!
 564         */
 565        if (pScsiReply->SCSIState & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
 566            pScsiReply->ResponseInfo)
 567                printk(MYIOC_s_DEBUG_FMT "response_info = %08xh\n",
 568                    ioc->name, le32_to_cpu(pScsiReply->ResponseInfo));
 569}
 570#endif
 571
 572/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 573/*
 574 *      mptscsih_io_done - Main SCSI IO callback routine registered to
 575 *      Fusion MPT (base) driver
 576 *      @ioc: Pointer to MPT_ADAPTER structure
 577 *      @mf: Pointer to original MPT request frame
 578 *      @r: Pointer to MPT reply frame (NULL if TurboReply)
 579 *
 580 *      This routine is called from mpt.c::mpt_interrupt() at the completion
 581 *      of any SCSI IO request.
 582 *      This routine is registered with the Fusion MPT (base) driver at driver
 583 *      load/init time via the mpt_register() API call.
 584 *
 585 *      Returns 1 indicating alloc'd request frame ptr should be freed.
 586 */
 587int
 588mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
 589{
 590        struct scsi_cmnd        *sc;
 591        MPT_SCSI_HOST   *hd;
 592        SCSIIORequest_t *pScsiReq;
 593        SCSIIOReply_t   *pScsiReply;
 594        u16              req_idx, req_idx_MR;
 595        VirtDevice       *vdevice;
 596        VirtTarget       *vtarget;
 597
 598        hd = shost_priv(ioc->sh);
 599        req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
 600        req_idx_MR = (mr != NULL) ?
 601            le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx) : req_idx;
 602
 603        /* Special case, where already freed message frame is received from
 604         * Firmware. It happens with Resetting IOC.
 605         * Return immediately. Do not care
 606         */
 607        if ((req_idx != req_idx_MR) ||
 608            (le32_to_cpu(mf->u.frame.linkage.arg1) == 0xdeadbeaf))
 609                return 0;
 610
 611        sc = mptscsih_getclear_scsi_lookup(ioc, req_idx);
 612        if (sc == NULL) {
 613                MPIHeader_t *hdr = (MPIHeader_t *)mf;
 614
 615                /* Remark: writeSDP1 will use the ScsiDoneCtx
 616                 * If a SCSI I/O cmd, device disabled by OS and
 617                 * completion done. Cannot touch sc struct. Just free mem.
 618                 */
 619                if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
 620                        printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
 621                        ioc->name);
 622
 623                mptscsih_freeChainBuffers(ioc, req_idx);
 624                return 1;
 625        }
 626
 627        if ((unsigned char *)mf != sc->host_scribble) {
 628                mptscsih_freeChainBuffers(ioc, req_idx);
 629                return 1;
 630        }
 631
 632        if (ioc->bus_type == SAS) {
 633                VirtDevice *vdevice = sc->device->hostdata;
 634
 635                if (!vdevice || !vdevice->vtarget ||
 636                    vdevice->vtarget->deleted) {
 637                        sc->result = DID_NO_CONNECT << 16;
 638                        goto out;
 639                }
 640        }
 641
 642        sc->host_scribble = NULL;
 643        sc->result = DID_OK << 16;              /* Set default reply as OK */
 644        pScsiReq = (SCSIIORequest_t *) mf;
 645        pScsiReply = (SCSIIOReply_t *) mr;
 646
 647        if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
 648                dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 649                        "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
 650                        ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
 651        }else{
 652                dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 653                        "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
 654                        ioc->name, mf, mr, sc, req_idx));
 655        }
 656
 657        if (pScsiReply == NULL) {
 658                /* special context reply handling */
 659                ;
 660        } else {
 661                u32      xfer_cnt;
 662                u16      status;
 663                u8       scsi_state, scsi_status;
 664                u32      log_info;
 665
 666                status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
 667
 668                scsi_state = pScsiReply->SCSIState;
 669                scsi_status = pScsiReply->SCSIStatus;
 670                xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
 671                scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
 672                log_info = le32_to_cpu(pScsiReply->IOCLogInfo);
 673
 674                /*
 675                 *  if we get a data underrun indication, yet no data was
 676                 *  transferred and the SCSI status indicates that the
 677                 *  command was never started, change the data underrun
 678                 *  to success
 679                 */
 680                if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
 681                    (scsi_status == MPI_SCSI_STATUS_BUSY ||
 682                     scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
 683                     scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
 684                        status = MPI_IOCSTATUS_SUCCESS;
 685                }
 686
 687                if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
 688                        mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
 689
 690                /*
 691                 *  Look for + dump FCP ResponseInfo[]!
 692                 */
 693                if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
 694                    pScsiReply->ResponseInfo) {
 695                        printk(MYIOC_s_NOTE_FMT "[%d:%d:%d:%llu] "
 696                        "FCP_ResponseInfo=%08xh\n", ioc->name,
 697                        sc->device->host->host_no, sc->device->channel,
 698                        sc->device->id, sc->device->lun,
 699                        le32_to_cpu(pScsiReply->ResponseInfo));
 700                }
 701
 702                switch(status) {
 703                case MPI_IOCSTATUS_BUSY:                        /* 0x0002 */
 704                case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:      /* 0x0006 */
 705                        /* CHECKME!
 706                         * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
 707                         * But not: DID_BUS_BUSY lest one risk
 708                         * killing interrupt handler:-(
 709                         */
 710                        sc->result = SAM_STAT_BUSY;
 711                        break;
 712
 713                case MPI_IOCSTATUS_SCSI_INVALID_BUS:            /* 0x0041 */
 714                case MPI_IOCSTATUS_SCSI_INVALID_TARGETID:       /* 0x0042 */
 715                        sc->result = DID_BAD_TARGET << 16;
 716                        break;
 717
 718                case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:       /* 0x0043 */
 719                        /* Spoof to SCSI Selection Timeout! */
 720                        if (ioc->bus_type != FC)
 721                                sc->result = DID_NO_CONNECT << 16;
 722                        /* else fibre, just stall until rescan event */
 723                        else
 724                                sc->result = DID_REQUEUE << 16;
 725
 726                        if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
 727                                hd->sel_timeout[pScsiReq->TargetID]++;
 728
 729                        vdevice = sc->device->hostdata;
 730                        if (!vdevice)
 731                                break;
 732                        vtarget = vdevice->vtarget;
 733                        if (vtarget->tflags & MPT_TARGET_FLAGS_LED_ON) {
 734                                mptscsih_issue_sep_command(ioc, vtarget,
 735                                    MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED);
 736                                vtarget->tflags &= ~MPT_TARGET_FLAGS_LED_ON;
 737                        }
 738                        break;
 739
 740                case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:         /* 0x004B */
 741                        if ( ioc->bus_type == SAS ) {
 742                                u16 ioc_status =
 743                                    le16_to_cpu(pScsiReply->IOCStatus);
 744                                if ((ioc_status &
 745                                        MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)
 746                                        &&
 747                                        ((log_info & SAS_LOGINFO_MASK) ==
 748                                        SAS_LOGINFO_NEXUS_LOSS)) {
 749                                                VirtDevice *vdevice =
 750                                                sc->device->hostdata;
 751
 752                                            /* flag the device as being in
 753                                             * device removal delay so we can
 754                                             * notify the midlayer to hold off
 755                                             * on timeout eh */
 756                                                if (vdevice && vdevice->
 757                                                        vtarget &&
 758                                                        vdevice->vtarget->
 759                                                        raidVolume)
 760                                                        printk(KERN_INFO
 761                                                        "Skipping Raid Volume"
 762                                                        "for inDMD\n");
 763                                                else if (vdevice &&
 764                                                        vdevice->vtarget)
 765                                                        vdevice->vtarget->
 766                                                                inDMD = 1;
 767
 768                                            sc->result =
 769                                                    (DID_TRANSPORT_DISRUPTED
 770                                                    << 16);
 771                                            break;
 772                                }
 773                        } else if (ioc->bus_type == FC) {
 774                                /*
 775                                 * The FC IOC may kill a request for variety of
 776                                 * reasons, some of which may be recovered by a
 777                                 * retry, some which are unlikely to be
 778                                 * recovered. Return DID_ERROR instead of
 779                                 * DID_RESET to permit retry of the command,
 780                                 * just not an infinite number of them
 781                                 */
 782                                sc->result = DID_ERROR << 16;
 783                                break;
 784                        }
 785
 786                        /*
 787                         * Allow non-SAS & non-NEXUS_LOSS to drop into below code
 788                         */
 789
 790                case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:        /* 0x0048 */
 791                        /* Linux handles an unsolicited DID_RESET better
 792                         * than an unsolicited DID_ABORT.
 793                         */
 794                        sc->result = DID_RESET << 16;
 795                        break;
 796
 797                case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:         /* 0x004C */
 798                        if (ioc->bus_type == FC)
 799                                sc->result = DID_ERROR << 16;
 800                        else
 801                                sc->result = DID_RESET << 16;
 802                        break;
 803
 804                case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:      /* 0x0049 */
 805                        scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
 806                        if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
 807                                sc->result=DID_SOFT_ERROR << 16;
 808                        else /* Sufficient data transfer occurred */
 809                                sc->result = (DID_OK << 16) | scsi_status;
 810                        dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 811                            "RESIDUAL_MISMATCH: result=%x on channel=%d id=%d\n",
 812                            ioc->name, sc->result, sc->device->channel, sc->device->id));
 813                        break;
 814
 815                case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:          /* 0x0045 */
 816                        /*
 817                         *  Do upfront check for valid SenseData and give it
 818                         *  precedence!
 819                         */
 820                        sc->result = (DID_OK << 16) | scsi_status;
 821                        if (!(scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
 822
 823                                /*
 824                                 * For an Errata on LSI53C1030
 825                                 * When the length of request data
 826                                 * and transfer data are different
 827                                 * with result of command (READ or VERIFY),
 828                                 * DID_SOFT_ERROR is set.
 829                                 */
 830                                if (ioc->bus_type == SPI) {
 831                                        if ((pScsiReq->CDB[0] == READ_6  && ((pScsiReq->CDB[1] & 0x02) == 0)) ||
 832                                            pScsiReq->CDB[0] == READ_10 ||
 833                                            pScsiReq->CDB[0] == READ_12 ||
 834                                                (pScsiReq->CDB[0] == READ_16 &&
 835                                                ((pScsiReq->CDB[1] & 0x02) == 0)) ||
 836                                            pScsiReq->CDB[0] == VERIFY  ||
 837                                            pScsiReq->CDB[0] == VERIFY_16) {
 838                                                if (scsi_bufflen(sc) !=
 839                                                        xfer_cnt) {
 840                                                        sc->result =
 841                                                        DID_SOFT_ERROR << 16;
 842                                                    printk(KERN_WARNING "Errata"
 843                                                    "on LSI53C1030 occurred."
 844                                                    "sc->req_bufflen=0x%02x,"
 845                                                    "xfer_cnt=0x%02x\n",
 846                                                    scsi_bufflen(sc),
 847                                                    xfer_cnt);
 848                                                }
 849                                        }
 850                                }
 851
 852                                if (xfer_cnt < sc->underflow) {
 853                                        if (scsi_status == SAM_STAT_BUSY)
 854                                                sc->result = SAM_STAT_BUSY;
 855                                        else
 856                                                sc->result = DID_SOFT_ERROR << 16;
 857                                }
 858                                if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
 859                                        /* What to do?
 860                                        */
 861                                        sc->result = DID_SOFT_ERROR << 16;
 862                                }
 863                                else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
 864                                        /*  Not real sure here either...  */
 865                                        sc->result = DID_RESET << 16;
 866                                }
 867                        }
 868
 869
 870                        dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 871                            "  sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
 872                            ioc->name, sc->underflow));
 873                        dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 874                            "  ActBytesXferd=%02xh\n", ioc->name, xfer_cnt));
 875
 876                        /* Report Queue Full
 877                         */
 878                        if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
 879                                mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
 880
 881                        break;
 882
 883                case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:           /* 0x0044 */
 884                        scsi_set_resid(sc, 0);
 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        scsi_remove_host(host);
1180
1181        if((hd = shost_priv(host)) == NULL)
1182                return;
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        kfree(hd->info_kbuf);
1199
1200        /* NULL the Scsi_Host pointer
1201         */
1202        ioc->sh = NULL;
1203
1204        scsi_host_put(host);
1205
1206        mpt_detach(pdev);
1207
1208}
1209
1210/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1211/*
1212 *      mptscsih_shutdown - reboot notifier
1213 *
1214 */
1215void
1216mptscsih_shutdown(struct pci_dev *pdev)
1217{
1218}
1219
1220#ifdef CONFIG_PM
1221/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1222/*
1223 *      mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1224 *
1225 *
1226 */
1227int
1228mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1229{
1230        MPT_ADAPTER             *ioc = pci_get_drvdata(pdev);
1231
1232        scsi_block_requests(ioc->sh);
1233        flush_scheduled_work();
1234        mptscsih_shutdown(pdev);
1235        return mpt_suspend(pdev,state);
1236}
1237
1238/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1239/*
1240 *      mptscsih_resume - Fusion MPT scsi driver resume routine.
1241 *
1242 *
1243 */
1244int
1245mptscsih_resume(struct pci_dev *pdev)
1246{
1247        MPT_ADAPTER             *ioc = pci_get_drvdata(pdev);
1248        int rc;
1249
1250        rc = mpt_resume(pdev);
1251        scsi_unblock_requests(ioc->sh);
1252        return rc;
1253}
1254
1255#endif
1256
1257/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1258/**
1259 *      mptscsih_info - Return information about MPT adapter
1260 *      @SChost: Pointer to Scsi_Host structure
1261 *
1262 *      (linux scsi_host_template.info routine)
1263 *
1264 *      Returns pointer to buffer where information was written.
1265 */
1266const char *
1267mptscsih_info(struct Scsi_Host *SChost)
1268{
1269        MPT_SCSI_HOST *h;
1270        int size = 0;
1271
1272        h = shost_priv(SChost);
1273
1274        if (h->info_kbuf == NULL)
1275                if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1276                        return h->info_kbuf;
1277        h->info_kbuf[0] = '\0';
1278
1279        mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1280        h->info_kbuf[size-1] = '\0';
1281
1282        return h->info_kbuf;
1283}
1284
1285int mptscsih_show_info(struct seq_file *m, struct Scsi_Host *host)
1286{
1287        MPT_SCSI_HOST   *hd = shost_priv(host);
1288        MPT_ADAPTER     *ioc = hd->ioc;
1289
1290        seq_printf(m, "%s: %s, ", ioc->name, ioc->prod_name);
1291        seq_printf(m, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1292        seq_printf(m, "Ports=%d, ", ioc->facts.NumberOfPorts);
1293        seq_printf(m, "MaxQ=%d\n", ioc->req_depth);
1294
1295        return 0;
1296}
1297
1298/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1299#define ADD_INDEX_LOG(req_ent)  do { } while(0)
1300
1301/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1302/**
1303 *      mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1304 *      @SCpnt: Pointer to scsi_cmnd structure
1305 *
1306 *      (linux scsi_host_template.queuecommand routine)
1307 *      This is the primary SCSI IO start routine.  Create a MPI SCSIIORequest
1308 *      from a linux scsi_cmnd request and send it to the IOC.
1309 *
1310 *      Returns 0. (rtn value discarded by linux scsi mid-layer)
1311 */
1312int
1313mptscsih_qcmd(struct scsi_cmnd *SCpnt)
1314{
1315        MPT_SCSI_HOST           *hd;
1316        MPT_FRAME_HDR           *mf;
1317        SCSIIORequest_t         *pScsiReq;
1318        VirtDevice              *vdevice = SCpnt->device->hostdata;
1319        u32      datalen;
1320        u32      scsictl;
1321        u32      scsidir;
1322        u32      cmd_len;
1323        int      my_idx;
1324        int      ii;
1325        MPT_ADAPTER *ioc;
1326
1327        hd = shost_priv(SCpnt->device->host);
1328        ioc = hd->ioc;
1329
1330        dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "qcmd: SCpnt=%p\n",
1331                ioc->name, SCpnt));
1332
1333        if (ioc->taskmgmt_quiesce_io)
1334                return SCSI_MLQUEUE_HOST_BUSY;
1335
1336        /*
1337         *  Put together a MPT SCSI request...
1338         */
1339        if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
1340                dprintk(ioc, printk(MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1341                                ioc->name));
1342                return SCSI_MLQUEUE_HOST_BUSY;
1343        }
1344
1345        pScsiReq = (SCSIIORequest_t *) mf;
1346
1347        my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1348
1349        ADD_INDEX_LOG(my_idx);
1350
1351        /*    TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1352         *    Seems we may receive a buffer (datalen>0) even when there
1353         *    will be no data transfer!  GRRRRR...
1354         */
1355        if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1356                datalen = scsi_bufflen(SCpnt);
1357                scsidir = MPI_SCSIIO_CONTROL_READ;      /* DATA IN  (host<--ioc<--dev) */
1358        } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1359                datalen = scsi_bufflen(SCpnt);
1360                scsidir = MPI_SCSIIO_CONTROL_WRITE;     /* DATA OUT (host-->ioc-->dev) */
1361        } else {
1362                datalen = 0;
1363                scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1364        }
1365
1366        /* Default to untagged. Once a target structure has been allocated,
1367         * use the Inquiry data to determine if device supports tagged.
1368         */
1369        if ((vdevice->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES) &&
1370            SCpnt->device->tagged_supported)
1371                scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1372        else
1373                scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1374
1375
1376        /* Use the above information to set up the message frame
1377         */
1378        pScsiReq->TargetID = (u8) vdevice->vtarget->id;
1379        pScsiReq->Bus = vdevice->vtarget->channel;
1380        pScsiReq->ChainOffset = 0;
1381        if (vdevice->vtarget->tflags &  MPT_TARGET_FLAGS_RAID_COMPONENT)
1382                pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
1383        else
1384                pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1385        pScsiReq->CDBLength = SCpnt->cmd_len;
1386        pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1387        pScsiReq->Reserved = 0;
1388        pScsiReq->MsgFlags = mpt_msg_flags(ioc);
1389        int_to_scsilun(SCpnt->device->lun, (struct scsi_lun *)pScsiReq->LUN);
1390        pScsiReq->Control = cpu_to_le32(scsictl);
1391
1392        /*
1393         *  Write SCSI CDB into the message
1394         */
1395        cmd_len = SCpnt->cmd_len;
1396        for (ii=0; ii < cmd_len; ii++)
1397                pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1398
1399        for (ii=cmd_len; ii < 16; ii++)
1400                pScsiReq->CDB[ii] = 0;
1401
1402        /* DataLength */
1403        pScsiReq->DataLength = cpu_to_le32(datalen);
1404
1405        /* SenseBuffer low address */
1406        pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
1407                                           + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1408
1409        /* Now add the SG list
1410         * Always have a SGE even if null length.
1411         */
1412        if (datalen == 0) {
1413                /* Add a NULL SGE */
1414                ioc->add_sge((char *)&pScsiReq->SGL,
1415                        MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1416                        (dma_addr_t) -1);
1417        } else {
1418                /* Add a 32 or 64 bit SGE */
1419                if (mptscsih_AddSGE(ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1420                        goto fail;
1421        }
1422
1423        SCpnt->host_scribble = (unsigned char *)mf;
1424        mptscsih_set_scsi_lookup(ioc, my_idx, SCpnt);
1425
1426        mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
1427        dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1428                        ioc->name, SCpnt, mf, my_idx));
1429        DBG_DUMP_REQUEST_FRAME(ioc, (u32 *)mf);
1430        return 0;
1431
1432 fail:
1433        mptscsih_freeChainBuffers(ioc, my_idx);
1434        mpt_free_msg_frame(ioc, mf);
1435        return SCSI_MLQUEUE_HOST_BUSY;
1436}
1437
1438/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1439/*
1440 *      mptscsih_freeChainBuffers - Function to free chain buffers associated
1441 *      with a SCSI IO request
1442 *      @hd: Pointer to the MPT_SCSI_HOST instance
1443 *      @req_idx: Index of the SCSI IO request frame.
1444 *
1445 *      Called if SG chain buffer allocation fails and mptscsih callbacks.
1446 *      No return.
1447 */
1448static void
1449mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1450{
1451        MPT_FRAME_HDR *chain;
1452        unsigned long flags;
1453        int chain_idx;
1454        int next;
1455
1456        /* Get the first chain index and reset
1457         * tracker state.
1458         */
1459        chain_idx = ioc->ReqToChain[req_idx];
1460        ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1461
1462        while (chain_idx != MPT_HOST_NO_CHAIN) {
1463
1464                /* Save the next chain buffer index */
1465                next = ioc->ChainToChain[chain_idx];
1466
1467                /* Free this chain buffer and reset
1468                 * tracker
1469                 */
1470                ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1471
1472                chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1473                                        + (chain_idx * ioc->req_sz));
1474
1475                spin_lock_irqsave(&ioc->FreeQlock, flags);
1476                list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1477                spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1478
1479                dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FreeChainBuffers (index %d)\n",
1480                                ioc->name, chain_idx));
1481
1482                /* handle next */
1483                chain_idx = next;
1484        }
1485        return;
1486}
1487
1488/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1489/*
1490 *      Reset Handling
1491 */
1492
1493/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1494/**
1495 *      mptscsih_IssueTaskMgmt - Generic send Task Management function.
1496 *      @hd: Pointer to MPT_SCSI_HOST structure
1497 *      @type: Task Management type
1498 *      @channel: channel number for task management
1499 *      @id: Logical Target ID for reset (if appropriate)
1500 *      @lun: Logical Unit for reset (if appropriate)
1501 *      @ctx2abort: Context for the task to be aborted (if appropriate)
1502 *      @timeout: timeout for task management control
1503 *
1504 *      Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1505 *      or a non-interrupt thread.  In the former, must not call schedule().
1506 *
1507 *      Not all fields are meaningfull for all task types.
1508 *
1509 *      Returns 0 for SUCCESS, or FAILED.
1510 *
1511 **/
1512int
1513mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, u64 lun,
1514        int ctx2abort, ulong timeout)
1515{
1516        MPT_FRAME_HDR   *mf;
1517        SCSITaskMgmt_t  *pScsiTm;
1518        int              ii;
1519        int              retval;
1520        MPT_ADAPTER     *ioc = hd->ioc;
1521        unsigned long    timeleft;
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        timeleft = 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, SNS_LEN(sc));
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